下面对msp430g2553串口通信总结并给出代码,从收发字节到中断函数的使用;再到收发字符串和指令;再到收发{0xE6,…,0xE6}有前后缀指令的通信协议。 收发字符 (链接中有例程) 收什么发什么,可以控制发送字节,字符串 msp430g2553软件串口 msp430g2553硬件串口 发送中断函数 msp430g2553发送中断函数 接收字符串 接收字符串涉及存储问题,何时开始存储,何时结束存储。 msp430g2553接收字符串 串口协议 更复杂的是,使用队列接收,这样数据的可靠性会更好 以下实例说明 串口采用TTL电平,波特率9600,1停止位,采用帧格式传输。 E5,帧尾为E6.长度表示数据域的字节长度,FCS为验证码,表示从命令码到数据域的数据加和(模256)。帧格式如图1所示.1所示。
名称 | 帧头 | 命令码 | 长度 | 数据域 | FCS | 帧尾 |
---|---|---|---|---|---|---|
字节数 | 1 | 1 | 1 | n | 1 | 1 |
内容 | E5 | xx | n | xx,xx,xx,xx | yy | E6 |
图 1.1 帧格式
智能照明实验命令如表3.1.特征码是学生在平台注册时获得的特征码,由9个字节组成(例如XD学校代码(2位)依次为1010001) 学院代码(1位) 题目编号(2位) 学生ID(4位)。
实验命令
类型 | 命令码 | 数据域 | 功能 |
---|---|---|---|
①接收 | 0x01 | / | 物联网实验平台发送准备就绪命令 |
②发送 | 0x05 | 特征码(9字节) | 将实验请求(开始命令)发送到物联网实验平台 |
③接收 | 0x06 | 0x01,01 | 确认信息, 第一个字节表示标题类型;第二个字节,01:自动模式,02:模拟模式 |
④发送 | 0x11 | xx | 光照度阈值发送到物联网实验平台 |
⑤发送 | 0x12 | xx | 向物联网实验平台发送延时时间(以秒为单位) |
⑥发送 | 0x13 | xx | 将当前的光照发送到物联网实验平台 |
⑦发送 | 0x15 | 01/00 | 将当前有人/无人状态发送到物联网实验平台 |
⑧发送 | 0x16 | 00/01 | 发送到物联网实验平台LED状态:灭/亮 |
⑨接收 | 0x19 | / | 接收到LED调亮命令 |
⑩接收 | 0x1A | / | 接收到LED调暗命令 |
?接收 | 0x1B | 01/02 | 接收模式切换命令, 01:自动模式 |
?接收 | 0x1C | / | 接收实验结束命令 |
①~③:实验开始时,等待物联网实验平台的开始按钮。按下按钮后,实验系统将特征代码发送到物联网实验平台,接收物联网实验平台的返回信息,默认进入自动模式。 ④~⑧:发送命令,自动模式下的任何状态都需要发送到物联网实验平台,模拟模式下只发送照明和灯的状态变化。 ⑨~⑩: 接收命令,按下模拟模式下的按钮↑(↓)之后,物联网实验平台会发送相应的指令,需要对应的灯亮(暗)。 ?~?:接收命令,按下自动/模拟按钮后发送的命令,需要切换实验模式;接收此指令后,需要完成实验操作。
实现下面的代码,模拟,自动,自由切换结束模式(while逻辑),按照上述协议与物联网平台通信。 不同的功能(灯的亮暗,ad采样电位器,光敏电阻)
实验内容 1.给定5PIN插座(2.54mm),依次提供 12V, 5V,GND,TXD(输入),RXD (输出); 2.设计以MSP以热释电模块、高亮度为核心的智能照明控制系统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 包装,易于更换。kB512非易失存储器B的RAM,8通道10位ADC,2 16位计数器,1路串口,1IIc,至少1个SPI接口。一般引脚16 个。 智能照明系统功能要求 实现以下功能的智能照明系统需要设计: (1)上电后,需要等待基本系统准备就绪,通过串口收到基本系统发送的准备就绪命令后,向基本系统发送开始命令(特征码); (2)收到基本系统发送的确认信息 表示基本系统已接受实验请求命令,并已做好实验准备; (3)向基本系统发送光照度阈值; (4)向基本系统发送延迟时间; (5)在自动模式下,每100ms收集一次光照信息并发送给基本系统; (6)在自动模式下检测人体传感器,如果有人,将有人状态发送到基本系统;此时,如果光照小于阈值,则打开 LED,产生 20%的 PWM 向基本系统发送信号LED开灯状态;以±5%的 PWM 信号逐渐增加 LED 光照度使检测到的光照度达到设定值(阈值),调整时间间隔100ms,直到光照度等于阈值(偏差范围内); (7)在自动模式下,如果检测到有人变成无人状态,则将无人状态发送到基本系统,并打开延迟计数器;如果检测到延迟,则关闭 LED 将灯发送到基本系统LED关灯状态;如果在延迟期间检测到有人状态,取消延迟计数器,将有人状态发送到基本系统,重复(6)。在模拟模式下,光照度由基本系统发送的指令控制。如果收到增加/减少的命令,PWM输出(控制灯亮度)每次增加/减少10%,直到达到最大亮度/最低亮度。在这种模式下,每 100ms 检测光照并发送给基本系统。

代码如下
#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
{
}