版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wowocpp/article/details/83062133
围绕 DP-51 单片机仿真实验仪的硬件电路,
阐述Small RTOS51 操作系统的设计原理。
详细的介绍了RS232 ,I2C,USB1.1和CANBUS等一系列外围器件及其功能部件的应用设计。
本书的原理篇,以Small RTOS V1.12.1版本为基础,
微型嵌入式实时操作系统的网址为: http://www.smallrtos.org/
数据包长度为NBYTE,起始字节为STARTBYTE1,
STARTBYTE2,最后一个字节为校验和,中间字节,不可能连续出现,STARTBYTE1,STARTBYTE2.
第一种方法---- 在中断中处理协议.
程序清单 0.1
#define NBYTE 20
unsigned char Buf[NBYTE-2];
unsigned char GetRight = 0 ;
#define STARTBYTE1 0xAA
#define STARTBYTE2 0x77
void comm(void) interrupt 4
{
//串行口中断
static unsigned char Sum ,Flag = 0,i ;
unsigned char temp ;
if(RI == 1){
RI = 0 ;
temp = SBUF;
switch(Flag){
case 0 :
if(temp == STARTBYTE1){
Flag = 1 ;
}
break ;
case 1:
if(temp == STARTBYTE2){
Sum = STARTBYTE1 + STARTBYTE2 ;
i = 0 ;
Flag = 2 ;
break ;
}
if(temp==STARTBYTE1){
break ;
}
Flag = 0 ;
break ;
case 2 :
if(temp == STARTBYTE1){
Flag = 3 ;
break ;
}
Sum += temp ;
if((i >= (NBYTE - 3))&& (Sum == 0)){
GetRight = 1 ;
Flag = 0 ;
break ;
}
Buf[i++] = temp ;
break ;
case 3 :
if(temp == STARTBYTE2){
Sum = STARTBYTE1 +STARTBYTE2 ;
Flag = 2 ;
i = 0 ;
break ;
}
Sum += STARTBYTE1 ;
if((i >= (NBYTE -3))&& Sum == 0 ){
GetRight =1 ;
Flag = 0 ;
break ;
}
Buf[i++] = STARTBYTE1 ;
if(temp == STARTBYTE1){
break ;
}
Sum += temp ;
if((i>=(NBYTE -3 ))&& Sum == 0){
GetRight =1 ;
Flag = 0 ;
break ;
}
Buf[i++] = temp ;
Flag = 2 ;
break ;
}
}
}
第2种方法 ,使用队列
void comm(void) interrupt 4
{
//串口中断
if(RI ==1){
RI = 0 ;
SBUF_In ;//SBUF 入队
}
}
unsigned char Buf[NBYTE -2];
unsigned char ReadSerial(unsigned char *cp)
{
unsigned char i ;
unsigned char temp ,Sum ;
temp = 队列中数据个数 ;
if(temp < (NBYTE)){
return 0;
}
SBUF 出队列 ;
if(temp != STARTBYTE1){
return 0 ;
}
temp = 队列首字节;
if(temp != STARTBYTE2){
return 0;
}
.......
}
第3种方法:
void comm(void ) interrupt 4
{
//串口中断
OS_INT_ENTER();
if(RI == 1){
RI = 0 ;
OSIntSendSignal(RECIVE_TASK_ID);
}
OSIntExit();
}
void Receive(void)
{
unsigned char temp ,temp1,Sum,i;
OSWait(K_SIG,0);
temp = SBUF;
while(1){
while(1){
OSWait(K_SIG,0);
temp1 = SBUF;
if((temp == STARTBYTE1)&&(temp1== STARTBYTE2)){
break ;
}
temp = temp1 ;
}
Sum = STARTBYTE1 +STARTBYTE2 ;
OSWait(K_SIG,0);
temp = SBUF ;
for(i=0;i<NBYTE -3 ;i++){
OSWait(K_SIG,0);
temp1 = SBUF;
if((temp == STARTBYTE1)&&(temp1 == STARTBYTE2)){
OSWait(K_SIG,0);
temp = SBUF;
i = -1 ;
Sum = STARTBYTE1 + STARTBYTE2 ;
continue ;
}
Buf[i] = temp ;
Sum += temp ;
temp = temp1 ;
}
Sum += temp1 ;
if(Sum == 0 ){
OSSendSignal("命令解释任务ID");
}
}
}
为啥要用队列
情况1:接收超时处理
情况2:如果数据来得太快,命令处理程序来不及处理,丢弃数据