找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4537|回复: 2
打印 上一主题 下一主题
收起左侧

从别处下载的,希望对学习430有用

[复制链接]
跳转到指定楼层
楼主
ID:62022 发表于 2014-11-15 18:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本章选择了一些简单的C语言程序例题,这些程序的结构简单,编程技巧不多,项目虽然
简单,但是非常适合入门单片机的学习者学习MSP430单片机的C 语言编程。
如下列出了C语言例题运行的MSP430F149实验板硬件资源环境,熟悉这些硬件资源,对
于理解程序非常重要。
(1)数码管:
左侧数码管与P5口相连,a~g,h对应P5.0~P5.7
右侧数码管与P4口相连,a~g,h对应P4.0~P4.7
(2)发光二极管
8 个发光二极管与P3 口连接
(3)按钮:
左侧8个按钮与P2口相连,引脚号标在按钮上方
右侧8个按钮与P1口相连,引脚号标在按钮上方
(4)P2.3引脚还是模拟比较器输入
(5)P6.0,P6.1引脚连接模拟量电位器,用于模拟量实验

9.1  通过 C 语言编程例入门 MSP430C 语言编程

  如下例子都在MSP430F149实验板上通过验证。
  例1:使与P3口的P3.0引脚连接的发光二极管闪烁。
#include <msp430x14x.h>  //声明库
void main(void)  //主函数
{
unsigned int i;  //变量声明
WDTCTL=WDTPW+WDTHOLD; //关掉看门狗
P3DIR |=BIT0; //设置P3.0为输出,这里BIT0=0x0001
while(1) //无限次while循环
{
for(i=0;i<20000;i++) //for语句,i为循环变量,i每次循环加1,当i<20000时,
  //循环延时
P3OUT=0x00; //使P3.0输出低电平,发光二极管亮,(低电平使发光二极管亮)
for(i=0;i<20000;i++) //再次循环延时
P3OUT=0x01;//使P3.0输出高电平,发光二极管灭,(高电平使发光二极管灭)
}
}
  例2:8个发光二极管 1、3、5、7与 2、4、6、8交替发光的例子
#include <msp430x14x.h>  
void main(void)
{
unsigned int i;
WDTCTL=WDTPW+WDTHOLD;
P3DIR=0XFF; //设置P3口为输出
while(1)
{
for(i=0;i<20000;i++)
P3OUT=0X55; //使发光二极管1、3、5、7 灭,2、4、6、8亮
for(i=0;i<20000;i++)
P3OUT=0XAA;//使发光二极管1、3、5、7亮,2、4、6、8灭
}
}
  例 3:定时器控制的发光二极管闪烁。这里使用了 MSP430F149芯片的 32768Hz低频晶体振荡器作为时钟
源。用定时器 A定时 1s,发光二极管灭 0.5s,亮.0.5s。
#include <msp430x14x.h>
void main (void)
{
WDTCTL= WDTPW + WDTHOLD; //设置看门狗控制寄存器,关看门狗
TACTL = TASSEL0 + TACLR; // 设置定时器A控制寄存器,
  //TASSEL0=0x0100,选择辅助时钟ACLK,
  //TACLR=0x0004,清除定时器A计数器
CCTL0 = CCIE;  //设置捕获/比较控制寄存器,CCIE=0x0010,使能捕获比较中断
CCR0 =16384;  //设置捕获/比较寄存器,初始值为16384,对于32768Hz的频率,相当于0.5s
P3DIR |=BIT7; //P3.7为输出
TACTL |= MC0; //设置定时器A控制寄存器,MC0=0x0010,使计数模式为增计数
_EINT(); //使能中断,这是一个C编译器支持的内部过程。
while(1); //无限次while循环
}

interrupt[TIMERA0_VECTOR] void Timer_A(void) //定时器A的CC0中断处理程序
//TIMERA0_VECTOR=6*2,等于基地址0xFFE0+12=0xFFEC
{
P3OUT ^= BIT7; //将P3.7引脚取反,就是使发光二极管闪烁
}

例 4:选择不同的时钟源,使 P3.7 连接的发光二极管闪烁。
(1)使用 XT2时钟源,8MHz频率,用定时器 A分频,产生 1s脉冲,使 P3.7引脚的发光二极管闪烁。
#include <msp430x14x.h>
#define XTOFF 0x40;  
void main (void)
{
WDTCTL= WDTPW + WDTHOLD; //关闭看门狗
BCSCTL1 &= ~XT2OFF;  //基础时钟控制寄存器BCSCTL1的第7位置0,使XT2启动
BCSCTL2 = SELS + DIVS1 + DIVS0; //基础时钟控制寄存器BCSCTL2设置,第3位置1,选择
//XT2CLK作为SMCLK时钟;将第2和第1位置1,使分频比为8
TACTL =0x02D4;
  //定时器A控制寄存器设置,第2位置1:清除;第4、5位置1、0:加计数模式
  //加计数至CCR0,然后重新开始;第6、7位1、1,所以是8分频;第8、9位是
//0、1,所以TA使用SMCLK时钟。
CCTL0 = CCIE;  //CCIE=0x0010,使能定时器A中断
CCR0 =62500;  //设置计数器CCR0的初值,((8MHz/8)/8)/2=62500,相当于0.5s的时间
P3DIR |=BIT7; //将P3.7设置为输出
_EINT(); //调用C430编译器内部函数,使能中断
while(1); //无限次循环
}
interrupt[TIMERA0_VECTOR] void Timer_A(void)  //定时器A中断函数
{
P3OUT ^= BIT7; //P3.7位取反
}
(2)使用32768Hz晶体产生1s信号的程序如下:
#include <msp430x14x.h>
void main (void)
{
WDTCTL= WDTPW + WDTHOLD;
TACTL =TASSEL0+TACLR+MC0;  
CCTL0 = CCIE;
CCR0 =16384;
P3DIR |=BIT7;
_EINT();
while(1);
}
interrupt[TIMERA0_VECTOR] void Timer_A(void)
{
P3OUT ^= BIT7;
}
(3)看门狗使输出 P3.7 引脚连接的发光二极管每秒闪烁一次的例子:
#include <msp430x14x.h>
void main (void)
{
WDTCTL= WDTPW + WDTTMSEL+WDTSSEL;
IE1|=WDTIE;
P3DIR |=BIT7;
_EINT();
while(1);
}
interrupt[WDT_VECTOR] void WDT_interrupt(void)
{
P3OUT ^= BIT7;
}
  例 5:  P4和 P5输出口连接的数码管显示 1和 2。
#include <msp430x14x.h>
void main(void)
{
unsigned char seg[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
//定义七段译码的共阳数码管显示数组
// hgfg dcba
//0=1100 0000
//1=1111 1001
//2=1010 0100
//……
//9=1001 0000
WDTCTL=WDTPW+WDTHOLD; //关闭看门狗,以便于调试
P4DIR=0XFF; //设置P4口为输出
P5DIR=0XFF;//设置P5口为输出
P4OUT=seg[1];//向P4口输出数组的第1个元素,数字1的段码
P5OUT=seg[2];//向P5口输出数组的第2个元素,数字2的段码
}
    例6:与 P5 口连接的数码管加 1计数,与 P4口相连的数码管显示数字8。
#include <msp430x14x.h>
void main(void)
{
  inti,x; //声明数据类型
unsigned char seg[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
WDTCTL=WDTPW+WDTHOLD;//关看门狗
P4DIR=0XFF; //P4口为输出,连接有共阳极数码管
P5DIR=0XFF; //P5口为输出,连接有共阳极数码管
P4OUT=seg[8]; //P4输出数字8
P5OUT=seg[0]; //P5输出数字0
while(1)  //无限次While循环
  {
for(i=0;i<=9;i++) //循环变量I从0到9循环
for(x=0;x<20000;x++) //没有循环体的for循环,用于延迟时间
P5OUT=seg; //按照循环变量i的数值,取出相应的数组元素
  }
}
例7:使用定时器输出精确的秒信号。从0开始计时,数码管显示0~60秒,每隔10秒使数码管
更换显示,并顺序点亮发光二极管。
#include <msp430x14x.h>
#define XTOFF 0x40;
unsigned int i=0,j=0; //声明数据类型
unsigned charseg_7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
  //数码管字型码数组
unsigned intbit[8]={0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080};
   //发光二极管点亮顺序数组
void main (void)  
{
WDTCTL= WDTPW + WDTHOLD; //关看门狗
TACTL = TASSEL0 + TACLR; // 设置定时器A控制寄存器,
  //TASSEL0=0x0100,选择辅助时钟ACLK(32kHz)
  //TACLR=0x0004,清除定时器A计数器
CCTL0 = CCIE; //使能定时器A捕捉与中断功能,CCIE=0x0010
CCR0 =32768;  // 设置计数器CCR0初值
TACTL |= MC0; //设置定时器工作模式为加计数到CCR0初值
P3DIR = 0XFF; //P3口为输出
P4DIR = 0XFF; //P4口为输出
P5DIR = 0XFF; //P5口为输出
P3OUT = 0X7E; //P3口输出为0111 1110
_EINT(); 调用C430编译器内部函数使能中断
while(1); //没有循环体的无限次while循环
}
interrupt[TIMERA0_VECTOR] void Timer_A(void) //定时器A的中断函数
{
i+=1; i每次循环加1
if (i==10) //如果i=1
  {
i=0;  //使i=0
j+=1; j每次加1
P3OUT ^= bit[j]; //数组的第j个元素取反后从P3口输出,使发光二极管顺序点亮
  if(j==6)  //如果j=6
{  
j=0; 使j=0
  }
  }
P4OUT =seg_7;//数码管字型数组中取第i个元素,送到P4口输出
P5OUT = seg_7[j]; //数码管字型数组中取第j个元素,送到P5口输出
}
例8:连接在P1.0 口的按键控制数码管显示数值,数码管显示按动次数。
#include <msp430x14x.h> //声明库文件
char Key_Pressed(void); //声明被调用函数
void main(void)  
{  
unsigned char seg[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
  //共阳数码管字型码数组
unsigned int i=0; //声明数据类型
WDTCTL = WDTPW + WDTHOLD; //关看门狗  
P1DIR &= ~BIT0; //P1.0引脚设置成输入,该引脚连接的按键按下时,按键输出低电平
P4DIR =0xff;    //P4口设置为输出,连接共阳数码管
P4OUT=seg[8];  //P4口输出数字8
while (1) //无限次while循环
  {
if(Key_Pressed()) //调用按键函数,如果按键函数返回1,

Page 6 of 21
基于模拟前端信号处理与控制技术的专业论坛、网站
P4OUT=seg[i++]; // 则数码管字型数组下标加1,选择相应的七段字型从
  //P4口输出
  if(i>9) //如果i大于9,则使i=0
  i=0;
  }
}
char Key_Pressed(void) //按键函数
  {
unsigned int i;  //声明变量i
while(!(P1IN&BIT0));//当P1输入寄存器P1IN的第0位为0时,开始while循环
for(i=0;i<8000;i++);//延时一段时间,消除按键抖动
  if(!(P1IN&BIT0)) //如果P1输入寄存器P1IN的第0位还是0,则返回1,表示按键按下
return 1;
else  //否则认为按键未按下,返回0
return 0;
  }
   例9:将P6口输入的模拟电压AD转换后,从P4、P5口连接的数码管输出。
  使用AD单通道多次转换,采集P6.0输入的模拟电压值(变化范围:0~3.3V),转换为数字量。
建立二维数组和通过顺序查表的方法得出采集回来的电压值。然后通过数码管显示当前电压值,显
示跟随输入的模拟电压的变化。由于只有两位数码管,故显示电压值精确到小数点后一位,如当前
输入电压2.37V,则显示2.4V。可用万用表检测显示是否准确。
#include "msp430x14x.h"      声明库
void Init(void);//声明初始化函数
interrupt [ADC_VECTOR]void ADC12(void); //声明AD转换中断函数
unsigned int Result;  声明变量
unsigned int Table[4][10] = { {0x040,0x0BC,0x138,0x1B4,0x230, 0x2AC , 0x328 , 0x3A4 , 0x420 ,0x49C},
  {0x518 , 0x594 , 0x610 , 0x68C ,0x708 , 0x784 , 0x800, 0x87C ,0x8F8,0x974    },
  {0x9F0 , 0xA6C , 0xAE8 , 0xB64 , 0xBE0 , 0xC5C , 0xC08 , 0xD54 , 0xDD0,0xE4C },
     { 0xEC8 , 0xF44 , 0xFC0 , 0xFFF } };
//该数组元素用于与AD转换的电压数值相比较,如果某个数组元素稍大于等于AD转换后的电压数
//值,则将此元素输出
void main(void)  //主函数
{ P4DIR = 0XFF; //P4口设置为输出
P5DIR = 0XFF; //P5口设置为输出  
Init();  //调用初始化函数
_EINT();  //使能中断
ADC12CTL0 |= ENC+ADC12SC;  //设置转换控制寄存器ADC12CTL0,ENC=0x002使转换允许位为1,
  //意味着可以启动转换,同时ADC12TL0中的低电平位可以被修改。
//ADC12SC=0x001使采样/转换控制位为1,如果采样信号SAMPCON由
//采样定时器产生(SHP=1),则ASC12SC=1将产生一次转换
while (1);  //无限次的while循环
}
void Init(void)  //初始化函数
{
WDTCTL = WDTPW+WDTHOLD;    //关看门狗
P6SEL |= 0x01;             // 设置P6口的P6.0引脚为外围模块AD转换器的模拟信号输入引脚  
ADC12CTL0 &= ~ENC;         //复位转换允许位  
ADC12CTL0 = ADC12ON + SHT0_2 + REFON + REF2_5V;    // Turn on and set up ADC12
  //设置转换控制寄存器ADC12CTL0,ADC12ON=0x010,使ADC12内核工作
//SHT0_2=2*0x100,确定采样周期为4×tADC12CLK×4
//REFON=0x020,内部参考电压打开
//REF2_5V=0x040,选择内部参考电压发生器的电压为2.5V
ADC12CTL1 = SHP + CONSEQ_2 ;  // 设置AD转换控制寄存器ADC12CTL1
  //SHP=0x0200 设置SAMPON来自采样定时器,采样信号上升沿触发采样
//CONSEQ_2=2*2 设置工作模式为单通道、多次转换模式
ADC12MCTL0 = SREF_0;  //设置通道0的转换存储控制寄存器ADC12MCTL0,
//SREF_0=0*0x10 选择参考电压为VR+=AVCC,VR-=AVSS ,因此输入模拟信号
  //范围是3.3V~0V。
ADC12IE |= BIT0;      //设置中断允许寄存器ADC12IE,将第0位置1,使通道A0转换后产生中断
}   
interrupt[ADC_VECTOR] void ADC12 (void)//AD转换中断函数
{
unsigned charseg_7[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
  //声明无小数点显示的数码管七段字型码数组
unsigned char seg_8[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
  //声明有小数点显示的数码管七段字型码数组  
unsigned i,j;       //声明变量数据类型  
ADC12CTL0 &= ~ENC;  //设置AD转换控制寄存器ADC12CTL0,ENC=0x002,~ENC=0xFFD,停止AD转换
  for( i=0 ; i<4 ;i++) //扫描Table 数组行下标
   {  
  for(j=0; j<10; j++)               //扫描Table 数组列下标
  {if (ADC12MEM0<=Table[j])  
goto xxx;   //如果Table数组元素大于转换数值,则转到标号 xxx
}  
}  
xxx:    {P4OUT = seg_7[j];   //P4 口输出
   P5OUT = seg_8; }     //P5 口输出
ADC12CTL0 |= ENC+ADC12SC;  //  使能再次转换
}   

例10: 模拟比较器实验
接电位器于端口P2.3, 用来输入模拟电压值 (0~3.3V)。 参考电压选取0.5VCC, 待测电压由P2.3
端输入,如果待测电压大于参考电压,P1.0端口的LED点亮,反之熄灭。
注意:顺时针调节电位器,输入的模拟电压值增大。
#include <msp430x14x.h>
void main (void)
{
   WDTCTL=WDTPW+WDTHOLD;
   P3DIR |= BIT0;   //P3口的第0引脚为输入
   CACTL1 =CARSEL + CAREF1 + CAON;//设置控制寄存器CACTL1,
//CARSEL=0x40,设置内部参考电压,当CAEX=0时参考电平加在(-)端
//CAREF1=0x20,选择0.5×VCC作为参考电压
//CAON=0x08,  打开比较器
   CACTL2 = P2CA0; //设置控制寄存器CACTL2,
//P2CA0=0x04,设置外部引脚信号连接在比较器输入端
   while (1) //无限次循环
    {
if ((CACTL2 & CAOUT )== CAOUT)//CAOUT=0x01,如果比较器输出为1
  //若CACTL2寄存器的第0位为1,则表示输入电压
  //大于参考电压
   P3OUT &= ~BIT0;  //则P3的第0引脚输出低电平,相连的发光二极管亮
    else  
    P3OUT |= BIT0;  //否则,P3的第0引脚输出高电平,相连的发光二极管灭
    }
}      
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:57810 发表于 2015-2-20 10:20 | 只看该作者
很好!
回复

使用道具 举报

板凳
ID:74307 发表于 2015-3-7 22:05 | 只看该作者
太好了可以好好学学了!!!!!!!!!!!!!!!!!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表