单片机串口接收多字节数据
2019-04-15 12:10发布
生成海报
http://bbs.elecfans.com/jishu_409918_1_1.html
各位大侠看一下,我下面的程序为什么不能接收两个字节的数据呢?
#include
#define uchar unsigned char
#define uint unsigned int
void rs232_init();
uchar flag,i,g,d;
uchar code table[]="I get ";
//sbit led=P1^0;
main()
{
rs232_init();
while(1)
{
if(flag==1)
{
ES=0;
for(i=0;i<6;i++)
{
SBUF=table[i];
while(!TI);
TI=0;
}
SBUF=g;
while(!TI);
TI=0;
SBUF=d;
while(!TI);
TI=0;
ES=1;
flag=0;
}
}
}
void rs232_init()
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
}
void ser()interrupt 4
{
RI=0;
g=SBUF;
d=SBUF;
flag=1;
}
我用串口调试助手调试时,上位机给单片机发送两个字节的数据,例如发送ck两个字母时,只接收到cc两个字母呢?
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
首先数据发送是一位一位发送的,串口接收也是一位一位接收的,当接收8位数据后,申请中断。
你的程序中,程序进入中断后,你用了g=SBUF,d=SBUF,程序之所以进入中断是因为串口接收到了八位数据,是八位数据,不是十六位数据,也就是你发送的字母ck中的c,k还没有发送完呢,所以g和d都被赋值了c,打印结果当然是cc了。
你要了解串口是接收八位数据后申请中断,你必须在下一个八位数据接收完(下一次中断到来前)以前取走这个数据,不然这个数据将会丢失。
我给你改 的程序如下,我定义一个宏N,N就是你每次发送的数据个数,然后一个数组,数组有N个元素,用于存储串口接受的数据。
当串口有中断时,我立即把这个数据存储到数组中,同时将数组指针指向下一位,然后当下一个中断来时重复上面步骤,直到接收数据个数到达N。
这里中断中程序不能太长,如果程序很长,我本次数据还没存储好,下一个数据已经到了,会丢失数据。
-
#include
-
#define uchar unsigned char
-
#define uint unsigned int
-
#define N 2 //可一次接收数据量
-
void rs232_init();
-
uchar flag,i; //删除无用变量
-
uchar code table[]="I get ";
-
uchar table1[N]; //接收缓存数组
-
uchar j=0; //接收计数器
-
//sbit led=P1^0;
-
main()
-
{
-
rs232_init();
-
while(1)
-
{
-
if(flag==1)
-
{
-
ES=0;
-
for(i=0;i<6;i++)
-
{
-
SBUF=table[i];
-
while(!TI);
-
TI=0;
-
}
-
for(j=0;j
-
{
-
SBUF=table1[j];
-
while(!TI);
-
TI=0;
-
}
-
j=0; //清零接收计数器
-
ES=1;
-
flag=0;
-
}
-
}
-
}
-
void rs232_init()
-
{
-
TMOD=0x20;
-
TH1=0xfd;
-
TL1=0xfd;
-
TR1=1;
-
SM0=0;
-
SM1=1;
-
REN=1; //先设定号工作方式,在打开允许接收
-
EA=1;
-
ES=1;
-
}
-
void ser()interrupt 4
-
{
-
RI=0;
-
table1[j++]=SBUF; //存数据到接收缓存
-
if(j==N) //数组满时,允许发送
-
flag=1;
-
}
复制代码
受此贴启发,Starsky项目中,串口中断接收更改如下成功接收多字节:
/* 串口接收数据中断服务函数 */
#pragma vector = 0x14 //设置串口接收中断向量号 = 0X14 = 20
__interrupt void UART1_RX_RXNE(void)
{
static int cnt=0;
UART1_SR_RXNE = 1; //清除中断标志
if(cnt == (COMBUFNUM-1)) //receive data done
{
bufRec[cnt]= UART1_DR; //last byte
recCmd = bufRec[1];
dutyPwm = (int) bufRec[2];
cnt =0;
}
else{
bufRec[cnt]= UART1_DR;
cnt++;
}
}
其中bufRec为接收buffer;
UART1_DR为STM8S003F6 UART接收数据寄存器。
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮