串口接收中断函数一次只能接收一个字,接收一个字符串并存下常用方法:
①设置标志位:如在末尾加入标志位’\r’,’\n’;前缀+数据+后缀
②定时判断接收数据的长度,如果在规定时间内,长度没有什么变化,证明已经接收了任意长度的字符。
下面我用设置标志位的方式实现接收字符串,并根据不同字符串执行不同的操作。
代码与仿真
串口助手收发情况
打开板子,电脑端收到
MADE BY PengChengIT.
G2553 UART
READY!!!
E5是前缀,E6为后缀,发送7个指令,执行了7种操作(收到7种不同的字符串)
测试成功!
接收字符串例子
接收并存储字符串有很多用途,如指令常常是一组字符串;其他设备、串口助手发送的指令来控制实验板。
代码说明
1、msp430g2553串口通信:
可以参考:msp430g2553串口通信
2、接收字符串:
在串口接收中断函数中调用void Receive(char x)函数,每次出现E5(前缀)开始存储字符串,到E6标志(后缀)出现为止,结束存储;
char a_a[13]={0}为全局字符串,char b_b[13]={0}为局部字符串,这两个字符串的长度决定了接收的字符串长度,在13内都可,可以根据需要改变;a_a为全局变量,会保留前一次存储结果,本次位数少于上次时,只刷新本次位数,a_a中上次多的位任保留,因此要一个局部的b_b,每次结束存储后把a_a中前rxcnt位赋给b_b;
3、指令执行
用了 #include "string.h"库中int a=strcmp(s,m_ready)函数
(把m_ready字符串和接收的指令相比)
和 if(a==0)
{
putstr(n_feature);//填写要执行的内容
}
#include <msp430.h>
#include "string.h"
void putchar(unsigned char tx_data);
void putstr(char *s);
void Receive(char x);
void result(char *s);
char RX_DATA;
char rxcnt=0;
char temp1;
char temp2;
char flag=0;
char *string1="MADE BY PengchengIT\n";
char string2[]="G2553 UART\nREADY!!!\n";
char n_feature[]="E5050958443130303031FDE6";
char m_ready[11]="E5010001E6";
char m_start[13]="E506010108E6";
char m_emulate[13]="E51B01021EE6";
char m_up[11]="E5190019E6";
char m_down[11]="E51A001AE6";
char m_auto[13]="E51B01011DE6";
char m_end[11]="E51C001CE6";
char a_a[13]={0};
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
if (CALBC1_1MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
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
P1DIR = BIT0; //p1.0外接LED为输出状态
P1OUT &= ~BIT0;
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; // Enable USCI_A0 RX interrupt
putstr(string1);
putstr(string2);
__bis_SR_register(LPM0_bits+GIE); // Enter LPM0, interrupts enabled
}
void Receive(char x)
{
temp2=temp1;
temp1=x;
if((temp1=='5')&&(temp2=='E'))
{
flag=1;
rxcnt=0;
memset(a_a,0,0);
a_a[0]='E';
rxcnt=1;
}
if((temp1=='6')&&(temp2=='E'))
{
flag=0;
a_a[rxcnt]='6';
char b_b[13]={0};
strncpy(b_b,a_a,rxcnt+1);
// putstr(b_b);
result(b_b);
}
if(flag==1)
{
a_a[rxcnt]=x;
rxcnt++;
}
}
void result(char *s)
{
int a=strcmp(s,m_ready);
int b=strcmp(s,m_end);
int c=strcmp(s,m_up);
int d=strcmp(s,m_down);
int e=strcmp(s,m_start);
int f=strcmp(s,m_emulate);
int g=strcmp(s,m_auto);
if(a==0)
{
putstr(n_feature);
}
if(b==0)
{
putstr("End of the test");
}
if(c==0)
{
putstr("The lights have been turned on");
}
if(d==0)
{
putstr("The lights have been dimmed");
}
if(e==0)
{
putstr("Begin to test\n");
putstr("E51101 A FCS+E6\n...");
}
if(f==0)
{
putstr("Enter simulation mode");
}
if(g==0)
{
putstr("Enter auto mode");
}
}
void putchar(unsigned char tx_data) //发送字符函数
{
while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? 等待TX buffer为空
UCA0TXBUF = tx_data;// TX -> RXed character? 发送字符c
}
void putstr(char *s)//发送字符串函数
{
IE2 &= ~UCA0RXIE;//发送时先关闭接收中断,不接收
//如果没有发完,就继续循环发送
while((*s)!='\0')
{
putchar(*s);
s++;
}
IE2 |= UCA0RXIE; //发送完了打开接收中断
}
// Echo back RXed character, confirm TX buffer is ready first
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCIAB0RX_VECTOR))) USCI0RX_ISR (void)
#else
#error Compiler not supported!
#endif
{
while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? 等待TX buffer为空
//UCA0TXBUF = UCA0RXBUF; // TX -> RXed character? 发送接收到的数据
RX_DATA=UCA0RXBUF;
Receive(RX_DATA);
}
硬件测试用板(TI的MSP-EXP430G2ET)
注意:图中绿圈跳帽的接法!