建立一個屬于自己的AVR的RTOS
TIMSK|=(1TOIE0);//T0溢出中斷允許
TCNT0=100;//置計(jì)數(shù)起始值
}
SIGNAL(SIG_OVERFLOW0)
{
IntNum++;//中斷嵌套+1
sei();//在中斷中,重開中斷
unsignedchari;
for(i=0;iOS_TASKS;i++)//任務(wù)時(shí)鐘
{
if(TCB[i].OSWaitTickTCB[i].OSWaitTick!=0xffff)
{
TCB[i].OSWaitTick--;
if(TCB[i].OSWaitTick==0)//當(dāng)任務(wù)時(shí)鐘到時(shí),必須是由定時(shí)器減時(shí)的才行
{
OSRdyTbl|=(0x01i);//使任務(wù)可以重新運(yùn)行
OSCoreState|=0x02;//要求任務(wù)切換的標(biāo)志位
}
}
}
TCNT0=100;
cli();
IntNum--;//中斷嵌套-1
IntSwitch();//進(jìn)行任務(wù)調(diào)度
}
unsignedchar__attribute__((progmem))proStrA[]=Task;
unsignedcharstrA[20];
SIGNAL(SIG_UART_RECV)//串口接收中斷
{
strA[0]=UDR;
}
/////////////////////////////////////串口發(fā)送
unsignedchar*pstr_UART_Send;
unsignedintnUART_Sending=0;
voidUART_Send(unsignedchar*Res,unsignedintLen)//發(fā)送字符串?dāng)?shù)組
{
if(Len>0)
{
pstr_UART_Send=Res;//發(fā)送字串的指針
nUART_Sending=Len;//發(fā)送字串的長度
UCSRB=0xB8;//發(fā)送中斷使能
}
}
//SIGNAL在中斷期間,其它中斷禁止
SIGNAL(SIG_UART_DATA)//串口發(fā)送數(shù)據(jù)中斷
{
IntNum++;//中斷嵌套+1,不充許中斷
if(nUART_Sending)//如果未發(fā)完
{
UDR=*pstr_UART_Send;//發(fā)送字節(jié)
pstr_UART_Send++;//發(fā)送字串的指針加1
nUART_Sending--;//等待發(fā)送的字串?dāng)?shù)減1
}
if(nUART_Sending==0)//當(dāng)已經(jīng)發(fā)送完
{
OSSemPost(0);
OSCoreState|=0x02;//要求任務(wù)切換的標(biāo)志位
UCSRB=0x98;
}
cli();//關(guān)發(fā)送中斷
IntNum--;
IntSwitch();//進(jìn)行任務(wù)調(diào)度
}
voidUARTInit()//初始化串口
{
#definefosc8000000//晶振8MHZUBRRL=(fosc/16/(baud+1))%256;
#definebaud9600//波特率
OSCCAL=0x97;//串口波特率校正值,從編程器中讀出
//UCSRB=(1RXEN)|(1TXEN);//允許發(fā)送和接收
UCSRB=0x98;
//UCSRB=0x08;
UBRRL=(fosc/16/(baud+1))%256;
UBRRH=(fosc/16/(baud+1))/256;
UCSRC=(1URSEL)|(1UCSZ1)|(1UCSZ0);//8位數(shù)據(jù)+1位STOP位
UCSRB=0xB8;
UDR=0;
}
//打印unsignedint到字符串中00000
voidstrPUT_uInt(unsignedchar*Des,unsignedinti)
{
unsignedcharj;
Des=Des+4;
for(j=0;j5;j++)
{
*Des=i%10+’0’;
i=i/10;
Des--;
}
}
voidstrPUT_Star(unsignedchar*Des,unsignedchari)
{
unsignedcharj;
for(j=0;ji;j++)
{
*Des++=’*’;
}
*Des++=13;
}
unsignedintstrPUT_TaskState(unsignedchar*Des,
unsignedcharTaskID,
unsignedcharNum)
{
//unsignedinti=0;
*(Des+4)=’0’+TaskID;
strPUT_uInt(Des+6,Num);
strPUT_Star(Des+12,TaskID);
return12+TaskID+1;
}
voidTask0()
{
unsignedintj=0;
while(1)
{
PORTB=j++;
if(OSTaskSemPend(0,0xffff))
{
unsignedintm;
m=strPUT_TaskState(strA,OSTaskRunningPrio,j);
UART_Send(strA,m);
}
OSTimeDly(200);
}
}
voidTask1()
{
unsignedintj=0;
while(1)
{
PORTC=j++;
if(OSTaskSemPend(0,0xffff))
{
unsignedintm;
m=strPUT_TaskState(strA,OSTaskRunningPrio,j);
UART_Send(strA,m);
}
OSTimeDly(100);
}
}
voidTask2()
{
unsignedintj=0;
while(1)
{
if(OSTaskSemPend(0,0xffff))
{
unsignedintm;
m=strPUT_TaskState(strA,OSTaskRunningPrio,j);
UART_Send(strA,m);
}
PORTD=j++;
OSTimeDly(50);
}
}
voidTaskScheduler()
{
OSSched();
while(1)
{
}
}
intmain(void)
{
strlcpy_P(strA,proStrA,20);
UARTInit();
TCN0Init();
OSRdyTbl=0;
IntNum=0;
OSTaskCreate(Task0,Stack[99],0);
OSTaskCreate(Task1,Stack[199],1);
OSTaskCreate(Task2,Stack[299],2);
OSTaskCreate(TaskScheduler,Stack[399],OS_TASKS);
OSStartTask();
}本文引用地址:http://butianyuan.cn/article/172857.htm
結(jié)束語
本文中的例子,基本上用WinAVR和Proteus調(diào)試仿真成功,一定可能存在某些方面的缺陷,因?yàn)楣ぷ魃蠒r(shí)間的壓力,就沒有進(jìn)一步查找。
評論