下面介绍一段MSP430单片机通过232串口发送0x00,0x01,0x02,0x03,0x04控制IO端口P1,P2,P4,P5,P6输出6路PWM波形变化的程序,单片机发送0x05,IO端口P1,P2,P4,P5,P6输出PWM为0。单片机的电路如下图
程序如下:链接:https://pan.baidu.com/s/1-vcBVWfkaSu8C81LeTFqmw?;
提取码:18fo?https://share.weiyun.com/IHXUku45
/
程序功能:实现流水灯以三种流动方式和四种流动速度
?????的不同组合而进行点亮"流动"
通过232串口发送0x00,0x01,0x02,0x03,0x04调节P1,P2,P4,P5,P6的6个管脚输出PWM波形的频率由小变大
通过232串口发送0x05调节P1,P2,P4,P5,P6的6个管脚输出PWM波形为零
程序功能:MCU通过串口向PC机发送4X4键盘的键值
-----------------------------------------------------
通信格式:N.8.1,?9600
------------------------------------------------
拨码开关设置:将LED位拨至ON,其余拨至OFF
测试说明:观察流水灯流动顺序和速度的变化
/
#include?
//#include"flash.h"
typedefunsignedint?uint;
typedefunsignedcharuchar;
//voidwrite_flash_char();
voidwriteflashchar(unsignedintaddr,chararray,intcount);
voidwriteflashint(unsignedintaddr,intarray,intcount);
?void??Delay400ms();
?voiddelay();
?voidDelay5ms();
uinti=0,j=0,dir=0;
uintflag=0,speed=0;?//flag--灯光流动方式,speed--灯光流动速度
?uinttmp;
?uintm;
?//uinttmp1=12000;
?//uinttmp2=1200;
??//uinttmp3=12000;
??//uinttmp4=1200;
??//?uinttmp5=12000;
?ucharshuju;
?intshuju1;
/主函数/
voidmain(void)
{
??
??/下面六行程序关闭所有的IO口/
??P1DIR=0XFF;P1OUT=0XFF;
??P2DIR=0XFF;P2OUT=0XFF;
??P3DIR=0XFF;P3OUT=0XFF;
??P4DIR=0XFF;P4OUT=0XFF;
??P5DIR=0XFF;P5OUT=0XFF;
??P6DIR=0XFF;P6OUT=0X00;
??
??WDTCTL=WDTPW+WDTHOLD;????//关闭看门狗
??P6DIR|=BIT2;P6OUT|=BIT2;??//关闭电平转换
??P5OUT&=~BIT7;
???
??CCTL0=CCIE;??????????//使能CCR0中断
??CCR0=50000;
??TACTL=TASSEL_2+ID_3+MC_1;//定时器A的时钟源选择SMCLK,增计数模式
??P2DIR=0xff;??????????//设置P2口方向为输出
??P2OUT=0xff;
??P1DIR=0xff;??????????//设置P2口方向为输出
??P1OUT=0xff;
???P4DIR=0xff;??????????//设置P2口方向为输出
??P4OUT=0xff;
???P5DIR=0xff;??????????//设置P2口方向为输出
??P5OUT=0xff;
???P6DIR=0xff;??????????//设置P2口方向为输出
??P6OUT=0xff;
??//tmp=12000;
???
?//?LPM0;??????????????//CPU进入LPM0模式/
???
????
??P3SEL|=0x30;??????????????//选择P3.4和P3.5做UART通信端口
??ME1|=UTXE0+URXE0;???????????//使能USART0的发送和接受
??UCTL0|=CHAR;??????????????//选择8位字符
??UTCTL0|=SSEL0;?????????????//UCLK=ACLK
??UBR00=0x03;???????????????//波特率9600
??UBR10=0x00;???????????????//
??UMCTL0=0x4A;??????????????//Modulation
??UCTL0&=~SWRST;?????????????//初始化UART状态机
??IE1|=URXIE0;??????????????//使能USART0的接收中断
??_EINT();????????????//使能全局中断
???
????//?LPM1;????
??while(1)
??{
????//_EINT();????????????????//打开全局中断
?????
???//进入LPM1模式
????//while(!(IFG1&UTXIFG0));???????//等待以前的字符发送完毕
????//TXBUF0=RXBUF0;????????????//将收到的字符发送出去?
???//?write_flash_char(0xef,shuju,4);
????//write_flash_int(0xbf,shuju1,2);
????//voidwriteflashchar(0xff,0x01,2);
??//???charFlash_ptr;?//Flashpointer;
?//inti;
???/FCTL1=FWKEY+ERASE;?//seterasebit
?/?燜CTL3=FWKEY;????//ClearLockbit
?牋
?//?Flash_ptr=0;??//DummywritetoeraseFlashsegment
??/?燜CTL1=FWKEY+WRT;??/SetWRTbitforwriteoperation
??//?燜lash_ptr=0x1001;??/initializeflashpointer
?//??for(i=0;i ??//?{
??//??Flash_ptr++=array[i];??//writevaluetoflash
??//?}
??//?FCTL1=FWKEY;??/ClearWRTbit
???/FCTL3=FWKEY+LOCK;//SetLOCKbit
???牋
????/switch(shuju)
???//?switch(RXBUF0)
????//{
????//case0x00:
????/if(TXBUF0=0x00)
??????/if(shuju==0x00)
????//{
???????/tmp=12000;
?????//???m=5;
??????//??break;
????????/m++;
??????/tmp--;
??????????/?}
????//if(TXBUF0=0x01)
?????//if(shuju==0x01)
????//{
??????/tmp=1200;
????????/case0x01:
??????/m=10;
??????//break;
?????/tmp++;
????/}
??//if(TXBUF0=0X02)
????/?if(shuju==0x02)
?//?{
???//tmp=5000;
???//tmp=tmp;
??????/case0x02:
?????//m=25;
??????/break;
?//?}
????/if(TXBUF0=0X03)
?????/if(shuju==0x03)
?//?{
????/tmp=20000;
???//tmp=tmp;
????/?燾ase0x03:
????//m=40;
????//?break;
??/}
??????/if(TXBUF0=0X04)
????//?if(shuju==0x04)
??//{
???//tmp=100;
???//tmp=tmp;
????/?case0x04:
????//?m=50;
?????//break;
??/}
??????/?爄f(shuju==0x05)
??/{
????/tmp=50000;
???//tmp=tmp;
????//??case0x05:
?????//m=100;
?????//?break;
????//default:
????//?m=0;
?????//break;
????//}
??//}
??}
}
/
函数名称:Timer_A?
功??能:定时器A的中断服务函数,在这里通过标志
?????控制流水灯的流动方向和流动速度
参??数:无
返回值?:无
/
#pragmavector=TIMERA0_VECTOR
__interruptvoidTimer_A(void)
{??
??//if(flag==0)
??//{
????//P2OUT=~(0x80>>(i++));??//灯的点亮顺序D8->D1
???//P2OUT=~(0x80>>4);
??//?while(!(IFG1&UTXIFG0));???????//等待以前的字符发送完毕
????//TXBUF0=RXBUF0;????????????//将收到的字符发送出去?
????
??????
????
?//P2OUT&=~0x01;??
?P2OUT&=~0x3F;??
???//P2OUT=~(0x3F);
?//delay(tmp);
??Delay400ms(m);
??//delay(12000);
???/P2OUT=~(0x00>>1);
??燩2OUT=~(0x00);
??/delay(12000);
?//delay(tmp);
??Delay400ms(m);
????燩1OUT=~(0x3F);
?//delay(12000);
?//delay(tmp);
?燚elay400ms(m);
??燩1OUT=~(0x00);
???/delay(12000);
??//delay(tmp);
???Delay400ms(m);
??//delay(12000);
????燩4OUT=~(0x3F);
???/delay(12000);
???燚elay400ms(m);
??//delay(tmp);
??燩4OUT=~(0x00);
???/delay(12000);
????//delay(tmp);
????燚elay400ms(m);
???P5OUT=~(0x3F);
???//delay(12000);?
??//delay(tmp);
???Delay400ms(m);
???P5OUT=~(0x00);
??//delay(12000);
???//delay(tmp);?
???Delay400ms(m);
??P6OUT=~(0x3F);
??//delay(12000);
??//delay(tmp);
???Delay400ms(m);
???P6OUT=~(0x00);
??//delay(12000);
???Delay400ms(m);
??//delay(tmp);
???//}
??//elseif(flag==1)
??//{
??//??P2OUT=~(0x01<<(i++));??//灯的点亮顺序D1->D8
??//}
??//else?
??//{
???//?if(dir)?????????//灯的点亮顺序?D8->D1,D1->D8,循环绕圈?????????????
???//?{
???//???P2OUT=~(0x80>>(i++));
???//?}
????//else
????//{
????//??P2OUT=~(0x01<<(i++));
????//}
??//}
?//
??//if(i==8)?
?//?{
???//??i=0;
??//??dir=~dir;
??//}
??
??//j++;
?//?if(j==40)?
?//?{
???//??i=0;
???//?j=0;
???//?flag++;
???//?if(flag==4)flag=0;
????//switch(speed)
????//{
???//?case0:
????//???TACTL&=~(ID0+ID1);
????//???TACTL|=ID_3;
???//???break;
???//?case1:
???//????TACTL&=~(ID0+ID1);
????//???TACTL|=ID_2;
????//???break;
????//case2:
????//???TACTL&=~(ID0+ID1);
????//??TACTL|=ID_1;
????//??break;
????//case3:
???//???TACTL&=~(ID0+ID1);
???//???TACTL|=ID_0;
????//???break;
????//default:
????//??break;
???//?}
???//??if(flag!=3)??speed++;
???//?if(speed==4)speed=0;
??//}?
}
/
函数名称:Delay5ms
功??能:延时约5ms
参??数:无
返回值?:无
/
voidDelay5ms(void)
{?
??uinti=40000;
??while(i!=0)
??{
????i--;
??}
}
/
函数名称:Delay400ms
功??能:延时约400ms
参??数:无
返回值?:无
/
voidDelay400ms(uintm)
{
??//uchari=50;
??uintj;
??while(m--)
??{
??????//j=7269;
???j=1000;
??????while(j--);
??}
}
/
函数名称:delay
功??能:延时约15ms,完成消抖功能
参??数:无
返回值?:无
/
voiddelay(uinttmp)
{
??//uinttmp;
???
??//for(tmp=12000;tmp>0;tmp--);
??for(tmp=tmp;tmp>0;tmp--);
}
/
函数名称:UART0_RXISR
功??能:UART0的接收中断服务函数,在这里唤醒
?????CPU,使它退出低功耗模式
参??数:无
返回值?:无
/
#pragmavector=UART0RX_VECTOR
__interruptvoidUART0_RXISR(void)
{
??while(!(IFG1&UTXIFG0));???????//等待以前的字符发送完毕
????TXBUF0=RXBUF0;????????????//将收到的字符发送出去?
????shuju=RXBUF0;
?????switch(RXBUF0)
????{
????case0x00:
????//if(TXBUF0=0x00)
??????//if(shuju==0x00)
????//{
???????//tmp=12000;
????????m=5;
????????break;
????????//m++;
??????//tmp--;
??????
????//?}
????//if(TXBUF0=0x01)
?????//if(shuju==0x01)
????//{
??????//tmp=1200;
????????case0x01:
??????m=10;
??????break;
?????//tmp++;
????//}
??//if(TXBUF0=0X02)
????//?if(shuju==0x02)
?//?{
???//tmp=5000;
???//tmp=tmp;
??????case0x02:
?????m=25;
??????break;
?//?}
????//if(TXBUF0=0X03)
?????//if(shuju==0x03)
?//?{
????//tmp=20000;
???//tmp=tmp;
?????case0x03:
?????m=40;
?????break;
??//}
??????//if(TXBUF0=0X04)
????//?if(shuju==0x04)
??//{
???//tmp=100;
???//tmp=tmp;
?????case0x04:
?????m=50;
??????break;
??//}
??????//??if(shuju==0x05)
??//{
????//tmp=50000;
???//tmp=tmp;
?????case0x05:
?????m=100;
??????break;
????default:
?????m=0;
?????break;
????}
?????
????//tmp=TXBUF0;
?//LPM1_EXIT;?????????//退出低功耗模式
}
|
|