下面对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个字节组成(例如XD1010001),依次为学校代码(2位)+学院代码(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:“自动”模式,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
{
}