培训人员网站建设,wordpress速度慢设置,焦作网站建设哪家专业,购物网站排名女装本章选择了一些简单的C语言程序例题#xff0c;这些程序的结构简单#xff0c;编程技巧不多#xff0c;题目虽然
简单#xff0c;但是非常适合入门单片机的学习者学习MSP430单片机的C 语言编程。
如下列出了C语言例题运行的MSP430F149实验板硬件资源环境#xff0c;熟悉…本章选择了一些简单的C语言程序例题这些程序的结构简单编程技巧不多题目虽然
简单但是非常适合入门单片机的学习者学习MSP430单片机的C 语言编程。
如下列出了C语言例题运行的MSP430F149实验板硬件资源环境熟悉这些硬件资源对
于理解程序非常重要。
1数码管
左侧数码管与P5口相连a~gh对应P5.0~P5.7
右侧数码管与P4口相连a~gh对应P4.0~P4.7
2发光二极管
8 个发光二极管与P3 口连接
3按钮
左侧8个按钮与P2口相连引脚号标在按钮上方
右侧8个按钮与P1口相连引脚号标在按钮上方
4P2.3引脚还是模拟比较器输入
5P6.0P6.1引脚连接模拟量电位器用于模拟量实验 9.1 通过 C 语言编程例入门 MSP430C 语言编程 如下例子都在MSP430F149实验板上通过验证。 例1使与P3口的P3.0引脚连接的发光二极管闪烁。
#include msp430x14x.h //声明库
void main(void) //主函数
{
unsigned int i; //变量声明
WDTCTLWDTPWWDTHOLD; //关掉看门狗
P3DIR |BIT0; //设置P3.0为输出这里BIT00x0001 while(1) //无限次while循环 { for (i0;i20000;i) //for语句i为循环变量i每次循环加1当i20000时 //循环延时 P3OUT0x00; 使P3.0输出低电平发光二极管亮低电平使发光二极管亮 for (i0;i20000;i) //再次循环延时 P3OUT0x01; 使P3.0输出高电平发光二极管灭高电平使发光二极管灭 }
} 例28个发光二极管 1、3、5、7与 2、4、6、8交替发光的例子
#include msp430x14x.h
void main(void)
{
unsigned int i;
WDTCTLWDTPWWDTHOLD;
P3DIR0XFF; //设置P3口为输出 while(1) { for (i0;i20000;i) P3OUT0X55; //使发光二极管1、3、5、7 灭2、4、6、8亮 for (i0;i20000;i) P3OUT0XAA;//使发光二极管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控制寄存器 // TASSEL00x0100选择辅助时钟ACLK // TACLR0x0004清除定时器A计数器
CCTL0 CCIE; //设置捕获/比较控制寄存器CCIE0x0010使能捕获比较中断
CCR0 16384; //设置捕获/比较寄存器初始值为16384对于32768Hz的频率相当于0.5s
P3DIR |BIT7; //P3.7为输出
TACTL | MC0; //设置定时器A控制寄存器MC00x0010使计数模式为增计数
_EINT(); //使能中断这是一个C编译器支持的内部过程。
while(1); //无限次while循环
} interrupt[TIMERA0_VECTOR] void Timer_A (void) //定时器A的CC0中断处理程序 //TIMERA0_VECTOR6*2,等于基地址0xFFE0120xFFEC
{ 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; //CCIE0x0010使能定时器A中断
CCR0 62500; //设置计数器CCR0的初值8MHz/8/8/262500相当于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 TASSEL0TACLRMC0;
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 WDTTMSELWDTSSEL;
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
//01100 0000
//11111 1001
//21010 0100
//……
//91001 0000 WDTCTLWDTPWWDTHOLD; //关闭看门狗以便于调试 P4DIR0XFF; //设置P4口为输出 P5DIR0XFF;//设置P5口为输出 P4OUTseg[1];//向P4口输出数组的第1个元素数字1的段码 P5OUTseg[2];//向P5口输出数组的第2个元素数字2的段码
} 例6与 P5 口连接的数码管加 1计数与 P4口相连的数码管显示数字8。
#include msp430x14x.h
void main(void)
{ int i,x; //声明数据类型 unsigned char seg[]{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; WDTCTLWDTPWWDTHOLD;//关看门狗 P4DIR0XFF; //P4口为输出连接有共阳极数码管 P5DIR0XFF; //P5口为输出连接有共阳极数码管 P4OUTseg[8]; //P4输出数字8 P5OUTseg[0]; //P5输出数字0 while(1) //无限次While循环 { for(i0;i9;i) //循环变量I从0到9循环 for(x0;x20000;x) //没有循环体的for循环用于延迟时间 P5OUTseg[i]; //按照循环变量i的数值取出相应的数组元素 }
}
例7使用定时器输出精确的秒信号。从0开始计时数码管显示060秒每隔10秒使数码管
更换显示并顺序点亮发光二极管。
#include msp430x14x.h
#define XTOFF 0x40;
unsigned int i0,j0; //声明数据类型
unsigned char seg_7[10]{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //数码管字型码数组
unsigned int bit[8]{0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080}; //发光二极管点亮顺序数组
void main (void)
{
WDTCTL WDTPW WDTHOLD; //关看门狗
TACTL TASSEL0 TACLR; // 设置定时器A控制寄存器 // TASSEL00x0100选择辅助时钟ACLK32kHz // TACLR0x0004清除定时器A计数器
CCTL0 CCIE; //使能定时器A捕捉与中断功能CCIE0x0010
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的中断函数
{
i1; i每次循环加1
if (i10) //如果i1 { i0; //使i0 j1; j每次加1 P3OUT ^ bit[j]; //数组的第j个元素取反后从P3口输出使发光二极管顺序点亮 if (j6) //如果j6 { j0; 使j0 } } P4OUT seg_7[i];//数码管字型数组中取第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 i0; //声明数据类型 WDTCTL WDTPW WDTHOLD; //关看门狗 P1DIR ~BIT0; //P1.0引脚设置成输入该引脚连接的按键按下时按键输出低电平 P4DIR 0xff; //P4口设置为输出连接共阳数码管 P4OUTseg[8]; //P4口输出数字8 while (1) //无限次while循环 { if(Key_Pressed()) //调用按键函数如果按键函数返回1
Simpo PDF Password Remover Unregistered Version - http://www.simpopdf.comwww.Microcontrol.cn 微控设计网 中国MSP430单片机专业网站
基于模拟前端信号处理与控制技术的专业论坛、网站
www.Microcontrol.cn 微控设计网
Page 6 of 21
基于模拟前端信号处理与控制技术的专业论坛、网站 P4OUTseg[i]; // 则数码管字型数组下标加1选择相应的七段字型从 // P4口输出 if (i9) //如果i大于9则使i0 i0; }
}
char Key_Pressed(void) //按键函数 { unsigned int i; //声明变量i while(!(P1INBIT0)); //当P1输入寄存器P1IN的第0位为0时开始while循环 for(i0;i8000;i);//延时一段时间消除按键抖动 if (!(P1INBIT0)) //如果P1输入寄存器P1IN的第0位还是0则返回1表示按键按下 return 1; else //否则认为按键未按下返回0
return 0; } 例9将P6口输入的模拟电压AD转换后从P4、P5口连接的数码管输出。 使用AD单通道多次转换采集P6.0输入的模拟电压值变化范围03.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 | ENCADC12SC; //设置转换控制寄存器ADC12CTL0ENC0x002使转换允许位为1 //意味着可以启动转换同时ADC12TL0中的低电平位可以被修改。
//ADC12SC0x001使采样/转换控制位为1如果采样信号SAMPCON由
//采样定时器产生SHP1则ASC12SC1将产生一次转换 while (1); //无限次的while循环
}
void Init(void) //初始化函数
{ WDTCTL WDTPWWDTHOLD; //关看门狗 P6SEL | 0x01; // 设置P6口的P6.0引脚为外围模块AD转换器的模拟信号输入引脚 ADC12CTL0 ~ENC; //复位转换允许位 ADC12CTL0 ADC12ON SHT0_2 REFON REF2_5V; // Turn on and set up ADC12 //设置转换控制寄存器ADC12CTL0ADC12ON0x010使ADC12内核工作 //SHT0_22*0x100确定采样周期为4×tADC12CLK×4 //REFON0x020内部参考电压打开 //REF2_5V0x040选择内部参考电压发生器的电压为2.5V ADC12CTL1 SHP CONSEQ_2 ; // 设置AD转换控制寄存器ADC12CTL1 // SHP0x0200 设置SAMPON来自采样定时器采样信号上升沿触发采样 //CONSEQ_22*2 设置工作模式为单通道、多次转换模式 ADC12MCTL0 SREF_0; //设置通道0的转换存储控制寄存器ADC12MCTL0 //SREF_00*0x10 选择参考电压为VRAVCC,VR-AVSS 因此输入模拟信号 //范围是3.3V~0V。 ADC12IE | BIT0; //设置中断允许寄存器ADC12IE将第0位置1使通道A0转换后产生中断
}
interrupt[ADC_VECTOR] void ADC12 (void) //AD转换中断函数
{ unsigned char seg_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转换控制寄存器ADC12CTL0ENC0x002~ENC0xFFD停止AD转换 for ( i0 ; i4 ;i) //扫描Table 数组行下标 { for (j0; j10; j) //扫描Table 数组列下标 { if (ADC12MEM0Table[i][j]) goto xxx; //如果Table数组元素大于转换数值则转到标号 xxx } } xxx: {P4OUT seg_7[j]; //P4 口输出 P5OUT seg_8[i]; } //P5 口输出 ADC12CTL0 | ENCADC12SC; // 使能再次转换 } 例10 模拟比较器实验
接电位器于端口P2.3 用来输入模拟电压值 03.3V。 参考电压选取0.5VCC 待测电压由P2.3
端输入如果待测电压大于参考电压P1.0端口的LED点亮反之熄灭。
注意:顺时针调节电位器输入的模拟电压值增大。
#include msp430x14x.h
void main (void)
{ WDTCTLWDTPWWDTHOLD; P3DIR | BIT0; //P3口的第0引脚为输入 CACTL1 CARSEL CAREF1 CAON;//设置控制寄存器CACTL1 //CARSEL0x40设置内部参考电压当CAEX0时参考电平加在端 //CAREF10x20选择0.5×VCC作为参考电压 //CAON0x08 打开比较器 CACTL2 P2CA0; //设置控制寄存器CACTL2 //P2CA00x04设置外部引脚信号连接在比较器输入端 while (1) //无限次循环 {
if ((CACTL2 CAOUT ) CAOUT) //CAOUT0x01如果比较器输出为1 //若CACTL2寄存器的第0位为1则表示输入电压 //大于参考电压 P3OUT ~BIT0; //则P3的第0引脚输出低电平相连的发光二极管亮 else P3OUT | BIT0; //否则P3的第0引脚输出高电平相连的发光二极管灭 }
}
例11 MSPF149的UART向PC机的RS232串口发送字符串。 单片机UART以9600波特率8个数据位无校验位1个停止位。单片机上电后连续向PC发送字符
串利用串口调试助手可以显示发送的内容。需要发送其他英文会话可以改变Data[]数组内容。
#include msp430x14x.h
void Init(void);//声明初始化函数
char Data[20]xia lao shi ni hao!; //发送的字符串
void main(void)
{ unsigned int i; WDTCTL WDTPW WDTHOLD; Init(); //调用初始化函数 while(1) //无限次循环 { for(i0;i20;i) { TXBUF0Data[i]; //向缓冲器送入待发送数据 while((UTCTL00x01)0); //发送缓冲器有待发数据时UTCTL0的第0位复位进入等待 } }
}
void Init(void)
{ UCTL0 ~SWRST; //USART控制寄存器UCTL0SWRST0x01~SWRST0xFE将 //UCTL0寄存器的第0位复位后USART才能重新被允许 UCTL0 0X10; //UCTL0的第4位置1设置数据长度为8位第5位为0设置1位停止位 UBR00 0x03; //使用32768Hz晶体波特率为9600 UBR10 0x00; UMCTL0 0x4A; UTCTL0 0X10; //发送控制寄存器第4位置1选择辅助时钟ACLK1 ME1 | UTXE0 ; //设置模块允许寄存器ME1UTXE00x80设置ME1的第7位为1 //使USART模式发送允许 P3SEL|BIT4; //P3口选择寄存器的第4位置1选择外围模块 P3DIR|BIT4; //P3口方向寄存器的第4位置1选择输出
} 例12 MSP430F149的 USART 接受 PC 键盘输入的数值并显示。 在串口调试助手中的发送区选中“十六进制发送”和“自动发送”以十六进制形式,以字节为单
位输入某个数字如03这样单片机会接受到送到数码管显示该数字。若连续输入“030205”单
片机其实是接受到了来自PC的以9600波特率8个数据位一个停止位的无校验位的字符串显示器
瞬间显示了3、2、5看到的是最后的数字5。
#include msp430x14x.h
void Init(void);
void main (void)
{ P4DIR0XFF; //P4口为输出 WDTCTLWDTPWWDTHOLD; Init(); _EINT(); while(1); //无限次循环等待接收中断
}
void Init(void) //初始化函数 { UCTL0 ~SWRST; UCTL0 |CHAR; //8位数据1位停止位 UBR00 0X03;//9600波特率32kHz时钟 UBR01 0X00; UMCTL0 0X4A; UTCTL0 | SSEL0; //SSEL00x10选择辅助时钟ACLK
ME1 | UTXE0URXE0;//模块允许寄存器ME1 //UTXE00x80 发送允许 //URXE00x40 接收允许 P3SEL | BIT4BIT5; //P3口第4、5引脚供外围模块使用 P3DIR |BIT4BIT5; //P3口的第4、5位为输出 IE1 |URXIE0; //中断允许寄存器IE1第6位为1使能接收中断URXIE00x40 }
interrupt [UART0RX_VECTOR] void UART0RX (void) //接收中断函数 { unsigned char seg[]{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; unsigned int x0; { xRXBUF0; //将接收缓冲器的内容送x P4OUTseg[x]; //再送P4口显示 } }
例13 RS232 串口通信接收发送数字
发送从单片机 P1、P2口输入按键信号 PC机 RS232C 口接收。
接收PC 机由 RS232C 口发送数字时P4口连接的数码管显示。需要发送十六进制数例如
十进制数 3应该发送 03。
#include msp430x14x.h
void Init(void);//声明初始化函数
void Delay(void);声明延迟函数
void main(void) //主函数
{ P1DIR0X00; //设置P1口方向寄存器P1口作为输入 P1IES0X00; //设置P1口中断边沿选择寄存器置1为下跳沿置0为上跳沿 P1IE0XFF; //设置P1中断使能寄存器置1为允许中断置0为禁止中断 P2DIR0X00;//设置P2口方向寄存器置0为输入置1为输出 P2IES0X00;//设置P2口中断边沿选择寄存器置1为下跳沿置0为上跳沿 P2IE0XFF; //设置P2中断使能寄存器置1为允许中断置0为禁止中断 P4DIR0XFF; //设置P4口方向寄存器使P4口为输出
WDTCTL WDTPW WDTHOLD; //关看门狗 Init(); //调用初始化函数 _EINT(); //调用C编译器内部函数使能中断 _BIS_SR(LPM1_bits); //调用C编译器内部对状态寄存器某位置位的函数
//LPM_bitsSCG0CPUOFF
// SCG00x0040进入LPM1低功耗工作模式
// CPUOFF0x0010 关闭CPU唤醒所有允许的中断 _NOP(); //调用C编译器内部空操作函数
}
void Init(void) //初始化函数
{ UCTL0 ~SWRST; //USART控制寄存器UCTL0SWRST0x01~SWRST0xFE将 //UCTL0寄存器的第0位复位后USART才能重新被允许 UCTL0 0X10; //8位数据1位停止位 UBR00 0x03; //9600波特率32kHz时钟 UBR10 0x00; UMCTL0 0x4A; UTCTL0 0X10; //发送控制寄存器第4位置1选择辅助时钟ACLK1 ME1 | UTXE0URXE0; //模块允许寄存器ME1 //UTXE00x80 发送允许 //URXE00x40 接收允许 P3SEL | BIT4BIT5; //P3口第4、5引脚供外围模块使用 P3DIR |BIT4BIT5; //P3口的第4、5位为输出 IE1 |URXIE0; //中断允许寄存器IE1第6位为1使能接收中断URXIE00x40
}
interrupt[PORT1_VECTOR]void PORT1(void) //P1口中断函数
{ if(P1IFGBIT0) //如果中断标志寄存器的第0位为1则延迟一段时间 {Delay(); //调用延迟函数 if(P1IFGBIT0)//若如果中断标志寄存器的第0位还为1 {TXBUF00X30; //向USART的发送缓冲器送数字“0” P1IFG~BIT0;} //清除中断标志 } //如下部分只是向USART发送缓冲器所送数字不同 else if(P1IFGBIT1) {Delay(); if(P1IFGBIT1) {TXBUF00X31; P1IFG~BIT1;}} else if(P1IFGBIT2) {Delay(); if(P1IFGBIT2) {TXBUF00X32; P1IFG~BIT2;}} else if(P1IFGBIT3) {Delay(); if(P1IFGBIT3) {TXBUF00X33; P1IFG~BIT3;} } else if(P1IFGBIT4) {Delay(); if(P1IFGBIT4) {TXBUF00X34; P1IFG~BIT4;}} else if(P1IFGBIT5) {Delay(); if(P1IFGBIT5) {TXBUF00X35; P1IFG~BIT5;}} else if(P1IFGBIT6) {Delay(); if(P1IFGBIT6) {TXBUF00X36; P1IFG~BIT6;}} else if(P1IFGBIT7) {Delay(); if(P1IFGBIT7) {TXBUF00X30; P1IFG~BIT7;}} }
interrupt[PORT2_VECTOR]void PORT2(void) //P2口中断函数
{ if(P2IFGBIT0) {Delay(); if(P2IFGBIT0) {TXBUF00X37; P2IFG~BIT0;} } else if(P2IFGBIT1) {Delay(); if(P2IFGBIT1) {TXBUF00X38; P2IFG~BIT1;}} else if(P2IFGBIT2) {Delay(); if(P2IFGBIT2) {TXBUF00X39; P2IFG~BIT2;}} else if(P2IFGBIT3) {Delay(); if(P2IFGBIT3) {TXBUF00X30; P2IFG~BIT3;}} else if(P2IFGBIT4) {Delay(); if(P2IFGBIT4) {TXBUF00X30; P2IFG~BIT4;}} else if(P2IFGBIT5) {Delay(); if(P2IFGBIT5) {TXBUF00X30; P2IFG~BIT5; }} else if(P2IFGBIT6) {Delay(); if(P2IFGBIT6) {TXBUF00X30; P2IFG~BIT6;} } else if(P2IFGBIT7) {Delay(); if(P2IFGBIT7) {TXBUF00X30P2IFG~BIT7;} } }
void Delay(void) //延迟函数
{ unsigned long i; for(i500;i0;i--);
}
interrupt [UART0RX_VECTOR] void UART0RX (void) //接收中断
{ unsigned char seg[]{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; unsigned int x0; xRXBUF0; //将接收缓冲器的内容赋予x P4OUTseg[x]; //送P4口显示需要PC机发送十六进制数 } //例如数字3必须输入03
//若要十进制需要改成P4OUTseg[x-0x30] 9.2 简单控制类单片机程序 例 1 定时控制程序
说明彩灯类程序例
#include msp430x14x.h
interrupt[TIMERA0_VECTOR] void Timer_A (void);
unsigned data1;
void main (void)
{
unsigned x1,y1;
unsigned char seg[10]{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
WDTCTL WDTPW WDTHOLD; //设置看门狗控制寄存器关看门狗
TACTL TASSEL0 TACLR; // 设置定时器A 控制寄存器 // TASSEL00x0100选择辅助时钟 ACLK // TACLR0x0004清除定时器A 计数器
CCTL0 CCIE; //设置捕获/比较控制寄存器CCIE0x0010使能捕获比较中断
CCR0 16384; //设置捕获/比较寄存器初始值为 16384对于32768Hz 的频率相当于 0.5s
P3DIR 0XFF; //P3 为输出
TACTL | MC0; //设置定时器 A控制寄存器MC00x0010使计数模式为增计数
_EINT(); //使能中断这是一个 C编译器支持的内部过程。
//p4初始化
P4DIR0XFF;
P5DIR0XFF;
while(1) //无限次 while 循环 { x1data1%10; //个位 y1data1/10; //十位 P4OUTseg[x1]; //显示个位 P5OUTseg[y1]; //显示十位
//如下是彩灯变化部分可以按照 data1 的值设定多种显示模式 if( data10) P3OUT0XFF; if(data11) P3OUT0X00; if( data12) P3OUT0X55; }
}
//定时中断
interrupt[TIMERA0_VECTOR] void Timer_A (void) //定时器 A的 CC0中断处理程序 //TIMERA0_VECTOR6*2,等于基地址 0xFFE0120xFFEC
{ //P3OUT ^ BIT7; //将P3.7引脚取反就是使发光二极管闪烁 data1; if (data13) data10;
} 例 2. 按键中断显示程序
说明P1、2 口按键中断后P4、5口输出按键值 keyvaluep1、keyvaluep2 显示数字的例子。
#include msp430x14x.h
void delay(int v);
unsigned keyvaluep1;
unsigned keyvaluep2;
//unsigned v;
void main (void)
{
unsigned char
seg[16]{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
WDTCTL WDTPW WDTHOLD; //设置看门狗控制寄存器关看门狗
//p3 初始化
P3DIR 0XFF; //P3 为输出
//p4 初始化
P4DIR0XFF; //P4 为输出
P5DIR0XFF; //P5 为输出 P1DIR0x00; // P1 口为输入 P2DIR0x00; // P2 口为输入 P1IFG0x00; //清除 P1口的中断标志 P2IFG0x00; //清除 P2口的中断标志 P1IES0xff; //设置 P1口中断是下降沿触发 P2IES0xff; //设置 P2口中断是下降沿触发 P1IE0xff; //允许 P1口中断 P2IE0xff; //允许 P2口中断
_EINT(); //使能中断这是一个 C 编译器支持的内部过程。
while(1) //无限次 while循环 { P4OUTseg[keyvaluep1]; //显示个位 P5OUTseg[keyvaluep2]; //显示十位 }
} void delay(int v) //延时子程序 { while(v!0) v--; } //以下是 port1的中断服务程序
interrupt[PORT1_VECTOR] void PORT1 (void) { unsigned temp1; //局部变量? //temp 暂时存放端口的中断标志寄存器
中的值 //temp 暂时存放端口的中断标志寄存器中的值 delay(2666); // 消除抖动延时 if ((P1IN0xff)!0xff) //如果有键按下 { temp1P1IFG; //temp1 记录中断标志 switch(temp1) { case 1: keyvaluep10;break; case 2: keyvaluep11;break; case 4: keyvaluep12;break; case 8: keyvaluep13;break; case 16: keyvaluep14;break; case 32: keyvaluep15;break; case 64: keyvaluep16;break; case 128: keyvaluep17;break; //default: keyvaluep10;break; } } P1IFG0X00; //清除中断标志返回主程序 }
//以下是 port2的中断服务程序
interrupt[PORT2_VECTOR] void PORT2 (void)
{ unsigned char temp1; delay(2666); if ((P2IN0xff)!0xff) { temp1P2IFG; switch(temp1) { case 1: keyvaluep28;break; case 2: keyvaluep29;break; case 4: keyvaluep210;break; case 8: keyvaluep211;break; case 16: keyvaluep212;break; case 32: keyvaluep213;break; case 64: keyvaluep214;break; case 128: keyvaluep215;break; //default: keyvaluep20;break; } } P2IFG0X00;
} 例 3. 90 延时开关程序
说明当按键 P1.0 第一次按下时P3.0 和 P3.1 连接的发光二极管亮当第二次按下时一个发光管灭
90 秒后全灭。P4、5 口输出时间值。
#include msp430x14x.h
interrupt[TIMERA0_VECTOR] void Timer_A (void);
interrupt[PORT1_VECTOR] void PORT1 (void) ;
void delay(int v); //延时子程序
unsigned data1;
unsigned keyvaluep1;
void main (void)
{
unsigned state;
unsigned x1,y1;
unsigned char seg[10]{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
WDTCTL WDTPW WDTHOLD; //设置看门狗控制寄存器关看门狗
TACTL TASSEL0 TACLR; // 设置定时器 A 控制寄存器 // TASSEL00x0100选择辅助时钟ACLK // TACLR0x0004清除定时器 A计数器
CCTL0 CCIE; //设置捕获/比较控制寄存器CCIE0x0010使能捕获比较中断
CCR0 16384; //设置捕获/比较寄存器初始值为 16384对于 32768Hz 的频率相当于0.5s
TACTL | MC0; //设置定时器A 控制寄存器MC00x0010使计数模式为增计数
_EINT(); //使能中断这是一个 C 编译器支持的内部过程。 P3DIR 0XFF; //P3 为输出 P4DIR0XFF;//P4 为输出 P5DIR0XFF;//P5 为输出 P1DIR0x00; // P1 口为输入 P2DIR0x00; // P2 口为输入 P1IFG0x00; //清除 P1口的中断标志 P2IFG0x00; //清除 P2口的中断标志 P1IES0xff; //设置 P1口中断是下降沿触发 P2IES0xff; //设置 P2口中断是下降沿触发 P1IE0xff; //允许 P1口中断 P2IE0xff; //允许 P2口中断
state0;
keyvaluep17; P3OUT0XFF;
while(1) //无限次 while循环 { x1data1%10; //个位 y1data1/10; //十位 P4OUTseg[x1]; //显示个位 P5OUTseg[y1]; //显示十位 if( state0 keyvaluep10 ) {P3OUT0XFC; state1; keyvaluep17;} if(state1 keyvaluep10) {P3OUT0XFE; state2; keyvaluep17; data10;} if( state2 data115)//data1 应该为90s {P3OUT0XFF; state0; keyvaluep17; }
}
interrupt[TIMERA0_VECTOR] void Timer_A (void) //定时器 A 的CC0 中断处理程序 //TIMERA0_VECTOR6*2,等于基地址 0xFFE0120xFFEC
{ //P3OUT ^ BIT7; //将P3.7 引脚取反就是使发光二极管闪烁 data1; if (data191) data10;
} void delay(int v) //延时子程序 { while(v!0) v--; } //以下是 port1的中断服务程序
interrupt[PORT1_VECTOR] void PORT1 (void) { unsigned temp1; //局部变量//temp 暂时存放端口的中断标志寄存器中的值 delay(2666); // 消除抖动延时 if ((P1IN0xff)!0xff) //如果有键按下 { temp1P1IFG; //temp1 记录中断标志 switch(temp1) { case 1: keyvaluep10;break; case 2: keyvaluep11;break; case 4: keyvaluep12;break; case 8: keyvaluep13;break; case 16: keyvaluep14;break; case 32: keyvaluep15;break; case 64: keyvaluep16;break; case 128: keyvaluep17;break; //default: keyvaluep10;break; } } P1IFG0X00; //清除中断标志返回主程序 } 例 4. 乡村小路交叉大路的交通灯程序
说明小路有传感器p1.0有车时两路按照时间交换红绿灯无车时大路一直绿灯小路绿灯时若
无车立即向小路红灯、大路绿灯转换。
#include msp430x14x.h
interrupt[TIMERA0_VECTOR] void Timer_A (void);
void Key(void);
void delay(int v); //延时子程序
unsigned data1;//全局变量用于传递时间信值
unsigned data2; //全局变量用于传递计满数就停止计数的时间值
unsigned kk;
void main (void)
{
unsigned state;
unsigned x1,y1;
unsigned char seg[10]{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
WDTCTL WDTPW WDTHOLD; //设置看门狗控制寄存器关看门狗
TACTL TASSEL0 TACLR; // 设置定时器 A 控制寄存器 // TASSEL00x0100选择辅助时钟ACLK // TACLR0x0004清除定时器 A计数器
CCTL0 CCIE; //设置捕获/比较控制寄存器CCIE0x0010使能捕获比较中断
CCR0 16384; //设置捕获/比较寄存器初始值为 16384对于 32768Hz 的频率相当于0.5s TACTL | MC0; //设置定时器A 控制寄存器MC00x0010使计数模式为增计数
_EINT(); //使能中断这是一个 C 编译器支持的内部过程。 P3DIR 0XFF; //P3 为输出 P4DIR0XFF;//P4 为输出 P5DIR0XFF;//P5 为输出 P1DIR0x00; // P1 口为输入 state0; P3OUT0XFF; data10; kk1;
while(1) //无限次 while循环 { x1data1%10; //个位 y1state;//P1IN;//data1/10; //十位 P4OUTseg[x1]; //显示个位 P5OUTseg[y1]; //显示十位 Key(); if( state0 data14 ) {P3OUT0X7D; //主路红小路绿 state1; data10; data20;} if(state1 data27 kk1) {P3OUT0X7B; //主路红小路黄 state2; data10;} if( state2 data14 ) {P3OUT0XD7; //主路绿小路黄 state3; data10;} if(state3 (data19 || kk0)) {P3OUT0XB7; state0; data10;} //0 状态主路黄小路红 }
} interrupt[TIMERA0_VECTOR] void Timer_A (void) //定时器 A 的CC0 中断处理程序 //TIMERA0_VECTOR6*2,等于基地址 0xFFE0120xFFEC
{ //P3OUT ^ BIT7; //将P3.7 引脚取反就是使发光二极管闪烁 data1; if (data191) data10; data2; //产生一个大于 7 就等于 7的计数值 if (data27) data27;
}
void delay(int v) //键盘判断延时子程序 { while(v!0) v--; } void Key(void) //接 P1.0 的按键函数
{ if(P1IN0xFE)//如果按键按下 { delay(2666); if(P1IN 0xFE) //如果按键按下 kk0; } else kk1; }
例 5. 两路模拟量 AD转换
说明按钮 P1.0 控制交替显示P1.1 显示P6.0输入的模拟电压P1.2 显示P6.1输入的模
拟电压。
#includemsp430x14x.h
unsigned int Volt0,Volt10; //设置电压变量
unsigned long int Volttem0,Volttem1;
unsigned data00,data10,kk00,kk10,counter0,keyvaluep1;
unsigned int ADresult0,ADresult1; //设置A/D转换结果变量
void Adcvolt (void);
void main(void)
{
unsigned int a[10]{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//数码管不带小数点译码
unsigned int b[10]{0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//数码管带小数点译码
WDTCTLWDTPWWDTHOLD; //停看门狗
BCSCTL1~XT2OFF; //开启 XT2CLK振荡器ACLK32768Hz
BCSCTL2|SELM_2SELS; //主时钟 MCLK 选择8MHz时钟子时钟 SMCLK8MHz
P1DIR0x00; //P1 口为输入
P1IFG0x00; //清除 P1口的中断标志
P1IES0xff; //设置 P1口中断是下降沿触发
P1IE0xff; //允许 P1口中断
P4DIR0xFF; //P4口外接数码管
P4OUT0xFF; //熄灭 P4口数码管
P5DIR0xFF; //P5口外接数码管
P5OUT0xFF; //熄灭 P5口数码管
P3DIR0XFF;
P6SEL|BIT0BIT1; //P6.0P6.1用于模拟输入通道
TACTLTASSEL0TACLR; //TIMERA初始化时钟源为 ACLK32768
CCTL0CCIE; //TIMERA中断使能
CCR02048; //设置比较值定时 1S
TACTL|MC0; //TIMERA增计数模式同时启动 TIMERA
Adcvolt (); //AD 初始化
_EINT(); //总中断使能
while(1) { if(kk01) //按键P1.0 和P1.1控制下只显示第1路采样值 { P5OUTb[Volt0/10]; //P5 口显示第1 路采样值的十位 P4OUTa[Volt0%10]; //P4口显示第 1 路采样值的个位 P3OUT|0X0F; P3OUT0XFE; } if(kk02) //按键P1.0 和P1.1控制下只显示第2路采样值 { P5OUTb[Volt1/10]; //P5 口显示第2 路采样值的十位 P4OUTa[Volt1%10]; //P4口显示第 2 路采样值的个位 P3OUT|0X0F; P3OUT0XFD; } if(data10kk00) //自动交替显示下data1 为零期间显示第 1路采样值 { P5OUTb[Volt0/10]; //P5 口显示第1 路采样值的十位 P4OUTa[Volt0%10]; //P4口显示第 1 路采样值的个位 P3OUT|0X0F; P3OUT0XFE; } if(data11kk00) //自动交替显示下data1 为1期间显示第 2路采样值 { P5OUTb[Volt1/10]; //P5 口显示第 2 路采样值的十位 P4OUTa[Volt1%10]; //P4 口显示第2 路采样值的十位 P3OUT|0X0F; P3OUT0XFD; } }
}
void Adcvolt (void) //进行电压转换时ADC12的初始化
{
ADC12CTL0~ENC; //ENC 为低电平设置 AD控制寄存器
ADC12CTL0|ADC12ONMSC; //打开ADC12可以进行 AD 转换参考电压选 3.3V
ADC12CTL1CSTARTADD_0CONSEQ_1SHP; //单通道单次转换采样频率源自采样定时器
ADC12MCTL0INCH_0; //选择模拟输入通道 2
ADC12MCTL1EOSINCH_1; //选择模拟输入通道 2
ADC12IE|BIT0BIT1; //AD 转换中断允许
ADC12CTL0|ENC; //转换允许
ADC12CTL0|ADC12SC; //开始A/D 转换
}
interrupt[PORT1_VECTOR] void PORT1 (void) { unsigned temp,i; //局部变量 temp暂时存放端口的中断标志寄存器中的值 for(i0;i2000;i); //消除抖动延时 if ((P1IN0xff)!0xff)//如果有键按下 { tempP1IFG; //temp 记录中断标志 switch(temp) { case 1: keyvaluep10;break; case 2: keyvaluep11;break; case 4: keyvaluep12;break; case 8: keyvaluep13;break; case 16: keyvaluep14;break; case 32: keyvaluep15;break; case 64: keyvaluep16;break; case 128: keyvaluep17;break; default: keyvaluep18;break; } } if(keyvaluep10 ) //P1.0? {kk00; P3OUT | 0XF0; P3OUT 0X7F; } if(keyvaluep11 ) // {kk01; P3OUT | 0XF0; P3OUT 0XBF;} if(keyvaluep12) {kk02; P3OUT | 0XF0; P3OUT 0XDF;} P1IFG0X00; //清除中断标志返回主程序 }
interrupt[ADC_VECTOR] void ADC(void) //A/D 转换中断子程序
{ ADresult0ADC12MEM0; //转换结果寄存器给了变量 ADresult0 Volttem0((long)ADresult0*33)/4095; //计算实际电压值 ADresult1ADC12MEM1; //转换结果寄存器给了变量 ADresult1 Volttem1((long)ADresult1*33)/4095; //计算实际电压值 Volt0Volttem0; Volt1Volttem1;
}
interrupt[TIMERA0_VECTOR] void Timer_A(void) //TIMERA中断子程序
{ data0; if(data030) data11; else data10; if (data060) data00; P3OUT ^ BIT3; ADC12CTL0|ADC12SC; //每隔一定时间进行一次转换
} 例 6. PWM 方式控制发光二极管的亮度
说明 按钮控制 PWM 输出使 P4.1的发光二极管数码管的 b 段 由亮到灭分为 8 级控制一个
按钮增加亮度另外一个减少亮度,数码管显示亮度等级,P1.0控制变亮P1.1控制变暗.
#include msp430x14x.h
unsigned int count0; //定义亮度等级变量
const unsigned char seg[]{0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80}; //显示段码表
void main(void)
{
WDTCTLWDTPWWDTHOLD; //停止看门狗
TBCTLTBSSEL_2TBCLRMC0;
//定时器 B 的时钟是 SMCLK800K16 位计数只用 CCR0增计数模式允许中断
TBCCTL1OUTMOD_3; //PWM输出模式置位/复位
TBCCR08000; //PWM中断周期
TBCCR11000; //PWM的低电平时间
P4DIR0X02; //P4.1 输出P4.1受 TBCCR1控制
P4SEL0X02; //P4.1 作为定时器B 的 PWM输出
P1DIR0xFC; //P1.0 和P1.1 输入
P1IE0x03; //允许中断 P1.0和 P1.1
P1IES0xfc; //上升沿中断
P5DIR0XFF; //P5 口为输出
P5OUT0xf9; //输出等级为1
_EINT(); //开总中断
while(1);
}
interrupt [PORT1_VECTOR] void PORT1_INTERRUPT(void)
{
unsigned int i; //定义延时常数
for(i8000;i0;i--); //延时消抖 if (P1IFGBIT0) { if(TBCCR18000) //如果已达到最亮则复位重新开始 { TBCCR11000; //低电平时间不变 count0; //亮度等级不变 P5OUTseg[count]; //显示亮度等级 1~8 } else { TBCCR1TBCCR11000; countcount1; //亮度等级递增 P5OUTseg[count]; //显示亮度等级 1~8
//如果 P1.0 的按键确实是按下了一次则低电平时间增长一次P4.0 的发光亮度增强一次
}
}
if (P1IFGBIT1) //如果 P1.1 的按键确实是按下了一次 { if (TBCCR11000) //则判断是否是最低亮度 { TBCCR11000; //如果是则亮度不变 count0; //亮度等级不变 P5OUTseg[count]; //显示亮度等级 1~8 } else { TBCCR1TBCCR1-1000; //如果不是则亮度递减 countcount-1; //亮度等级递减 P5OUTseg[count]; //显示亮度等级 1~8 } }
P1IFG0X00; //清除按键中断标志
} //中断返回