http://bbs.elecfans.com/jishu_409918_1_1.html
各位大侠看一下,我下面的程序为什么不能接收两个字节的数据呢?
#include<reg51.h>
#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。
这里中断中程序不能太长,如果程序很长,我本次数据还没存储好,下一个数据已经到了,会丢失数据。
受此贴启发,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接收数据寄存器。