如何实现单片机 串口接受不同长度氛数据
串口接收数据的时候 接收一个字节进入一次中断,此时SBUF寄存器里面存放的是接收的数据,只要把SBUF里面的数据取出来就可以了,同时中断里要把RI清零,以便下次进入中断接收数据,
上面数据的是一个字节一个字节的接收数据, 接收一串数据,有成一帧数据的时候,怎么接收呢
。定义一个足够长的数组,比如 一帧数据 最长会有20个字节,那么定义的数组长度,要大于等于20 ;
定义一个计数变量,在中断里 对接收的数据进行计数 ; 例如
void interruptUartS1() interrupt 4
{
if(RI)
{
RI = 0;
bufS1Rxd[cntS1Rxd++] = SBUF;
idletmrS1 = 0;
}
if(TI)
{
TI = 0;
flagS1Txd = 1;
}
}
bufS1Rxd 就是定义的一个数组,用于存放数据, cntS1Rxd 就是计数变量,用于记录接收的数据长度,
3,。那么如何判断一帧数据什么时候接收完毕呢 , 这里就用到了idletmr这个变量,,这个就是在定时器中端里 不停的累加的一个计时变量,,定时器初值1ms 累加一次就是1ms 的时间, 一般是判断间隔30ms左右的时间 没有接收数据,那么 就表示一帧数据接收完毕,,,这个间隔时间跟波特率有关的,,因为,,波特率就是数据传输的速度,,,
void interrupttimer0() interrupt 1
{
static uint16 t = 0;
t++;
if(t >= 1000)
{
t = 0;
}
if(idletmrS1 < 10)
{
idletmrS1++;
if(idletmrS1 >= 10)
{
CmdArrivedS1 = 1;
}
}
}
上面就是定时器中断的内容, 采用的是16位自动重装模式,是STC15系列单片机独有的定时器模式, 我这里是9600的波特率,10ms没有接收数据就会把 CmdArrived 这个标志位置1 ,用此判断 已经一帧数据接收完毕, 如果在10ms以内接收到数据,就会把idletmr清零,重新计时的
4, 一般防止干扰引起的数据错误,会加入校验位,这里有奇偶校验,CRC校验== ,很多校验方式, 一般采用CRC校验,,还有更简单的和校验,, 和校验就是把一帧数据中的不是校验位的数据 累加起来,取和的低8位,这个就是和校验的高字节,,和校验的低字节就是 高字节的补码‘
以上就是简单的介绍些一帧数据的接收原理,,
实际应用中, 还会有加入固定数据 进行判断,==之类的校验,,都是防止数据被干扰