下面对msp430g2553串口通信做出总结并给出代码,从收发字节;到中断函数的使用;再到收发字符串,指令;再到如收发{0xE6,…,0xE6}有前后缀的指令的通信协议。 收发字符 (链接中有例程) 收什么发什么,可以控制发送字节,字符串 msp430g2553软件串口 msp430g2553硬件串口 发送中断函数 msp430g2553发送中断函数 接收字符串 接收字符串涉及到存储的问题,啥时候开始存,啥时候结束存。 msp430g2553接收字符串 串口协议 复杂一点的,常常使用队列接收,这样数据的可靠性会好一点 下面实例说明 串口通信协议及命令 串口采用TTL电平,波特率9600,1停止位,采用帧格式进行传送。帧头为 E5,帧尾为E6,长度表示数据域的字节长度,FCS为校验码,表示从命令码到数据域之间数据的加和(模256)。帧格式如图1.1所示。
名称帧头命令码长度数据域FCS帧尾字节数111n11内容E5xxnxx,xx,xx,xxyyE6图 1.1 帧格式
智能照明实验的命令如表3.1所示,其中特征码是学生在平台注册时获得的特征码,由9个字节组成(例如XD1010001),依次为学校代码(2位)+学院代码(1位)+题目编号(2位)+学生ID(4位)。
实验命令
类型命令码数据域功能①接收0x01/物联网实验平台发送“准备就绪”命令②发送0x05特征码(9字节)向物联网实验平台发送实验请求(开始命令)③接收0x060x01,01确认信息, 第一个字节表示题目类型;第二个字节,01:“自动”模式,02:“仿真”模式④发送0x11xx向物联网实验平台发送光照度阈值⑤发送0x12xx向物联网实验平台发送延时时间(以秒为单位)⑥发送0x13xx向物联网实验平台发送当前的光照度⑦发送0x1501/00向物联网实验平台发送当前有人/无人状态⑧发送0x1600/01向物联网实验平台发送LED状态:灭/亮⑨接收0x19/接收到LED调亮命令⑩接收0x1A/接收到LED调暗命令⑪接收0x1B01/02接收到模式切换命令, 01:“自动”模式,02:“仿真”模式⑫接收0x1C/接收到实验结束命令①~③:实验开始时先等待物联网实验平台的“开始”按键,按键按下后,实验系统向物联网实验平台发送特征码,这时会接收到物联网实验平台返回信息,默认进入自动模式。 ④~⑧:发送命令,自动模式下任一个状态有变化都需要向物联网实验平台发送,仿真模式下只需发送光照度和灯的状态变化。 ⑨~⑩: 接收命令,仿真模式下按下按键↑(↓)后,物联网实验平台会发送对应指令,需要进行对应灯增亮(降暗)操作。 ⑪~⑫:接收命令,⑪为自动/仿真按键按下后发送的命令,需要进行实验模式切换操作;⑫为接收到此指令后,需要结束实验操作。
下面的代码实现,仿真,自动,结束模式的自由切换(while逻辑),与物联网平台按照上述协议通信。 在不同模式下实现不同功能(灯的亮暗,ad采样电位器,光敏电阻)
实验内容 1.给定5PIN插座(2.54mm),依次提供+12V,+5V,GND,TXD(输入),RXD (输出); 2.设计以MSP430为核心的智能照明控制系统,包括热释电模块、高亮度LED 灯,光敏二极管、光照度阈值旋钮、延时时间旋钮、串口(TTL)等; 3.制作PCB板(8cm*5.6cm); 4.焊接,并调试硬件电路; 5.编写程序,实现下列功能: (a) 在自动模式下,检测人体红外信息,实现人来开灯,人走延时关 灯;如果环境光照度已经超过了光阈值,不开灯; (b) 在仿真模式下,不检测人体红外信息,通过按键“↑”“↓”,改变LED 的亮度,并实时检测光照度; (c) 可以设置人走关灯的延时时间; (d) 可以设置光照度阈值; (e) 通过串口实现实验系统与物联网实验平台的交互。 6. 实验任务: (1)设置光照度阈值,实现人来开灯,并自动调节光照度; (2)改变环境光照度,可以用纸盖住光敏传感器,实现自动调节光照度; (3)调节延时时间,实现人走关灯; (4)在仿真模式下,调节光照度从最小到最大;从最大到最小。 7. 建议: 采用+5V供电。MCU选用 MSP430G2553,或者MSP430G2513,PDIP20 封装,便于更换。16kB非易失存储器,512B的RAM,8通道10位ADC,2 个16位计数器,1路串口,1个IIc,至少1个SPI接口。通用引脚16 个。 智能照明系统功能要求 要求设计出一套实现如下功能的智能照明系统: (1)上电工作后,需要等待基本系统准备就绪,通过串口收到基本系统发送的准备就绪命令后,向基本系统发送开始命令(特征码); (2)接收到基本系统发送的“确认信息 06”,表示基本系统已经接受实验请求命令,且已经做好实验准备工作; (3)向基本系统发送“光照度阈值”; (4)向基本系统发送“延时时间”; (5)在自动模式下,每100ms采集一次光照度信息,并发送给“基本系统; (6)在自动模式下,检测人体传感器,如果有人,则向“基本系统”发送有人状态;这时,如果光照度小于阈值,打开 LED,产生 20%的 PWM 信号,向“基本系统”发送“LED”开灯状态;以±5%的 PWM 信号逐渐增加 LED 光照度,使检测的光照度达到设定值(阈值),调节时间间隔100ms,直到光照度等于阈值(偏差范围内); (7)在自动模式下,如果检测到有人变成无人状态,则向“基本系统”发送无人状态,开启延时计数器;如果检测到延时时间到,则关闭 LED 灯,向“基本系统”发送“LED”关灯状态;如果在延时时间未到期间,检测到有人状态,则取消延时计数器,并向“基本系统”发送有人状态”,重复(6)。在仿真模式下,此时光照度受基本系统发送的指令进行控制。若接收到增加/降低命令,则PWM输出(控制灯亮度)每次增加/降低10%,直到达到最大亮度/最低亮度便不再增加/降低。该模式下,每 100ms 检测一次光照度并发送给基本系统。
程序设计框图
msp430g2553板子与物联网平台对接
物联网平台通过NB联网把数据传到云端
实验板子原理图
代码如下
#include "MSP430G2553.h" #include "string.h" #include <stdlib.h> /************串口参数***********/ unsigned char m_feature[]={0XE5,0X05,0X09,0X58,0X44,0X31,0X30,0X31,0X30,0X30,0X34,0x37,0X07,0XE6}; //本组特征码 int m_ready[]={229,1,0,1,230}; int m_start[]={229,6,2,1,1,10,230}; int m_emulate[]={0xE5,0x1B,0x01,0x02,0x1E,0xE6}; int m_up[]={0xE5,0x19,0x00,0x19,0xE6}; int m_down[]={0xE5,0x1A,0x00,0x1A,0xE6}; int m_auto[]={0xE5,0x1B,0x01,0x01,0x1D,0xE6}; int m_end[]={0xE5,0x1C,0x00,0x1C,0xE6}; unsigned char m_init_light[]={0XE5,0X11,0X01,0X3C,0X4E,0XE6}; unsigned char m_init_delay[]={0XE5,0X12,0X01,0X3C,0X4F,0XE6}; unsigned char m_init_lightpower[]={0XE5,0X13,0X01,0X30,0X44,0XE6}; unsigned char m_init_people[]={0XE5,0X15,0X01,0X00,0X16,0XE6}; unsigned char m_init_LED[]={0XE5,0X16,0X01,0X01,0X18,0XE6}; int RxBuf[13]={0}; int RxBuf1[13]={0}; int temp1; int flag; int flag3=0; int rxcnt; int wp=0; int flag1=0; int flag2=0; /***********adc参数**************/ unsigned int adc_buf[]={0}; char ad_1;//照度 char ad_2;//延时 char ad_3;//阈值 /*************pwm波参数**************/ int pwm_frequency=1024; int pwm_percent=25;//占空比 int pwm_add=10; int pwm_subtract=10; /***********自动模式、仿真模式参数***********/ unsigned int a[5]={0}; unsigned int hw_flag=0; unsigned int TK_flag=0; unsigned int LD_Val =0; unsigned int YS_Val =0; /************声明函数***********/ void pwm_init(); //pwm波初始化 void io_init(); //端口初始化 void delay_us(int us); void delay_ms(int us); void result(int *s); void PutStr(unsigned char *p,unsigned char length); void PutChar(unsigned char data); void result_ready(int *s); void result_start_auto(int *s); void result_emulate(int *s); void adc10_input(); int numcmp(int *p,int *q); void UartInit(); /******************main***********/ int main( void ) { WDTCTL = WDTPW + WDTHOLD; io_init(); pwm_init(); UartInit(); __bis_SR_register(GIE); _EINT(); while(1)//持续等待 { __delay_cycles(100000); while(numcmp(RxBuf,m_ready))//准备就绪 { result_ready(RxBuf); } while(numcmp(RxBuf,m_start)||numcmp(RxBuf,m_auto))//开始模式,自动模式 { P2OUT &= ~BIT5;P2OUT|=BIT4; result_start_auto(RxBuf); __delay_cycles(100000); } while(numcmp(RxBuf,m_up)||numcmp(RxBuf,m_down)||numcmp(RxBuf,m_emulate))//仿真模式 { P2OUT &= ~BIT4;P2OUT|=BIT5; result_emulate(RxBuf); RxBuf[1]=0xFF; } while(numcmp(RxBuf,m_end))//结束模式 { P2OUT|=(BIT4+BIT5); } } } /****************io初始化*********************/ void io_init() { P2DIR |= BIT4+BIT5; // p2.4,p2.5贴片led P2OUT |= BIT4+BIT5; P2DIR &=~ BIT2; // p2.2红外输入端口 P2DIR |=BIT1; P2SEL |=BIT1; //pwm } /************pwm波*********************/ void pwm_init() { TA1CCR0 = pwm_frequency - 1; // PWM Period TA1CCTL1 = OUTMOD_7; // TACCR1 reset/set TA1CCR1 = pwm_frequency*pwm_percent/100; // TACCR1 PWM Duty Cycle TA1CTL = TASSEL_2 + MC_1; // SMCLK, upmode } /**********************************/ int numcmp(int *p,int *q) { for(int i =0;*(q+i)!=230;i++) { flag1=*(p+i); if(flag1!=*(q+i)) { return 0; } } return 1; } /*****************ADC10*******************/ void adc10_input() { ADC10CTL1=INCH_4+CONSEQ_1; ADC10CTL0=ADC10SHT_1+MSC+ADC10ON+ADC10IE; ADC10DTC1=0X05; ADC10AE0|=BIT4+BIT3+BIT0; } /*****************特征码检测*******************/ void result_ready(int *s) { PutStr(m_feature,13); } /****************仿真模式**********************/ void result_emulate(int *s) { int isup=0; int isdown=0; isup = numcmp(s,m_up); isdown = numcmp(s,m_down); if(isup ==1) { TA1CCR1 =TA1CCR1+20; m_init_lightpower[3]+=10; m_init_lightpower[4]+=10; PutStr(m_init_lightpower,6); } else if(isdown ==1) { TA1CCR1 =TA1CCR1-20; m_init_lightpower[3]-=10; m_init_lightpower[4]-=10; PutStr(m_init_lightpower,6); } } /****************自动模式************************/ void result_start_auto(int *s) { adc10_input(); while(numcmp(RxBuf,m_start)||numcmp(RxBuf,m_auto)) { P2DIR|=BIT1; ADC10CTL0&=~ENC; ADC10SA=(unsigned int)a;//0光照度阈值1延时时间4当前光照度 while(ADC10CTL1&ADC10BUSY); ADC10CTL0|=ENC+ADC10SC; m_init_delay[3]=256*a[1]/1024; m_init_delay[4]=m_init_delay[1]+m_init_delay[2]+m_init_delay[3]; m_init_light[3]=256*a[0]/700; m_init_light[4]=m_init_light[1]+m_init_light[2]+m_init_light[3]; m_init_lightpower[3]=a[4]; m_init_lightpower[4]=m_init_lightpower[1]+m_init_lightpower[2]+m_init_lightpower[3]; if(m_init_light[3]>m_init_lightpower[3]) { TA1CCR1 = pwm_frequency*a[0]/100; m_init_LED[3]=0X01; m_init_LED[4]=m_init_LED[1]+m_init_LED[2]+m_init_LED[3]; m_init_people[3]=0x01; m_init_people[4]=m_init_people[1]+m_init_people[2]+m_init_people[3]; } else { TA1CCR1=0; m_init_LED[3]=0X00; m_init_LED[4]=m_init_LED[1]+m_init_LED[2]+m_init_LED[3]; m_init_people[3]=0x01; m_init_people[4]=m_init_people[1]+m_init_people[2]+m_init_people[3]; } PutStr(m_init_light,6); PutStr(m_init_delay,6); PutStr(m_init_lightpower,6); PutStr(m_init_people,6); PutStr(m_init_LED,6); } } /****************串口初始化**********************/ void UartInit() { DCOCTL = 0; // Select lowest DCOx and MODx settings BCSCTL1 = CALBC1_1MHZ; // Set DCO DCOCTL = CALDCO_1MHZ; P1SEL |= BIT1 + BIT2; // P1.1 = RXD, P1.2=TXD P1SEL2 |= BIT1 + BIT2; // P1.1 = RXD, P1.2=TXD UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0BR0 = 104; // 1MHz 9600 UCA0BR1 = 0; // 1MHz 9600 UCA0MCTL = UCBRS0; // Modulation UCBRSx = 1 UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** IE2 |= UCA0RXIE; } /*********串口发送数据程序************/ void PutChar(unsigned char data) { while((UC0IFG&UCA0TXIFG)==0); UCA0TXBUF=data; } void PutStr(unsigned char *p,unsigned char length) { int i =0; for(i=0;i<length;i++) { PutChar(*(p+i)); } } /*********串口中断服务程序************/ #pragma vector=USCIAB0RX_VECTOR __interrupt void USCI0RX_ISR(void) { if(UCA0RXIFG) { IFG2 &=~UCA0RXIFG; RxBuf[wp]=UCA0RXBUF; wp++; if(RxBuf[wp-1]==0xE6) { RxBuf[wp]=0; wp=0; } } } // ADC10 interrupt service routine #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(ADC10_VECTOR))) ADC10_ISR (void) #else #error Compiler not supported! #endif { }