单片机RTOS随想曲
单片机RTOS随想曲
本文标为随想曲,是说明这不是一篇结构严谨的文章,而是想到哪写到哪,希望读者能喜欢这种风格。以下为本文正文:
对于搞单片机的特别用8051系列工程师来说,谈到单片机的RTOS,很多时候会问一句:“为什么要用RTOS?单片机就这一点资源,使用RTOS能保证效率吗?”
对于这个问题,我会反问:“你用单片机的目的是什么?是为了用单片机的C编程,单片机的汇编编程甚至于用单片机的二进制指令编程?”上个世纪80年代,工程师用二进制指令给Z80编程,现在还有谁在用?现在还有人死抱着汇编不放,但越来越多的人工程师使用C编程(我起初也是使用汇编的),为什么?因为我们的目的是在有限的时间甚至是不充足的时间内把项目保质保量的完成!使用是么工具和方法是次要的(如果你的项目以成本放在第一位,则另当别论,这时,也是要考虑开发时间的)。时间就是金钱啊,一个产品在单片机上增加些许成本是可以接受的。况且,使用8051系列单片机时,单片机资源也常有富余,CPU一般情况也只是空转,这就为它使用RTOS创造了条件。
那么,使用RTOS的好处呢?我举一个例子吧。假设我们编一个串行通讯程序,通讯协议如下:
数据包长度为NBYTE,起始字节为STARTBYTE1,STARTBYTE2,最后一个字节为检验和,中间字节不可能出现连续出现STARTBYTE1,STARTBYTE2。
第一种方法,在中断中处理协议:
unsigned char Buf[NBYTE-2];
bit GetRight=0;
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;
}
}
}
第二种方法,使用队列
中断函数:
void comm(void) interrupt 4
//"串行口中断"
{
if(RI==1)
{
RI=0;
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;
出队temp;
if(temp!=STARTBYTE1) return 0;
temp=队列首字节;
if(temp!=STARTBYTE2) return 0;
出队temp;
sum=STARTBYTE1+STARTBYTE2;
for(i=0;i
temp=队列首字节;
if(temp==STARTBYTE1)
{
temp=队列次首字节;
if(temp==STARTBYTE2) return 0;
}
出队temp;
*cp++=temp;
Sum+=temp;
}
temp=队列首字节;
Sum+=temp;
if(Sum!=0) return 0;
出队temp;
return 1;
}
第三种方法,使用RTOS
中断函数:
void comm(void) interrupt 4
//"串行口中断"
{
OS_INT_ENTER();
if(RI==1)
{
RI=0;
OSIntSendSignal(RECIVE_TASK_ID);
}
OSIntExit();
}
ID为RECIVE_TASK_ID的任务
void Recuve(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;
非常好我支持^.^
(0) 0%
不好我反对
(0) 0%