RTOS_TINY中實現串口發送字符串控制LED

題目內容

在RTOS_TINY操作系統下實現以下目標:
有四個LED,使用AT89S52的4個引腳驅動它們分別以5Hz,8Hz,20Hz,32Hz的頻率閃爍。設使用12MHz的晶振。用串口助手,通過發送 “TURN on 1”,使得LED1持續閃爍,並回顯“LED1 on”;發送“TURN off 1”,使得LED1停止閃爍,並回顯“LED1 off”;通過編寫命令解釋器使得LED0、1、2、3都可以得到類似的響應。

分析

1、通過增加狀態量實現上述目標:
根據頻率設定每半週期引腳輸出翻轉一次控制燈閃爍;
時鐘週期1μs;
頻率 ~ 週期 ~ 半週期
5Hz ~ 200ms ~ 100ms
8Hz ~ 125ms ~ 62.5ms
20Hz ~ 50ms ~ 25ms
32Hz ~ 31.5ms 15.625ms
已設置定時間爲1ms,採用定時中斷,每1ms產生1次溢出,根據半週期設定累加取反次數。

2、在RTOS_TINY操作系統下實現:
參考教程文檔,在RTOS_TINY操作系統下內核週期爲10ms,可在CONF_TNY.A51文件裏將內核週期更改爲1ms。所以創建四個任務task1、2、3、4分別控制四個LED,設置task 0用於打開task 1、2、3、4及刪掉本任務;
使用os_wait(K_IVL,T)函數控制燈閃爍頻率。

3、字符串控制LED燈亮滅:
定累利用串口中斷髮送字符串,當檢測到1-4的數字時結束,存入數組。與指針變量比較後控制燈的亮滅。

實現

#include <reg52.h>
#include <string.h>
#include <rtx51tny.h>

/*LED燈使用IO口*/
sbit LED1 = P1^0;
sbit LED2 = P1^1;
sbit LED3 = P1^2;
sbit LED4 = P1^3;

/*聲明字符串到數組指針變量*/
unsigned char buf[10];   
unsigned char* ptr = buf;
unsigned char* a = "TURN on 1";
unsigned char* b = "TURN on 2";
unsigned char* c = "TURN on 3";
unsigned char* d = "TURN on 4";
unsigned char* e = "TURN off 1";
unsigned char* f = "TURN off 2";
unsigned char* g = "TURN off 3";
unsigned char* h = "TURN off 4";

int flag_1 = 1;
int flag_2 = 1;
int flag_3 = 1;
int flag_4 = 1;

unsigned char receiveData;

/*串口中斷配置*/
void UARTInit()
{     
   SCON=0x50; 
   TMOD=0x21;
   PCON=0x00;
   TH1=0xFD;   
   TL1=0xFD;
   REN=1;
   ET1=0;
   TR1=1;
   ES=1;
   EA=1;     
}

/*中斷服務函數*/
void Usart() interrupt 4
{
    receiveData=SBUF;
    RI = 0;
    *ptr=receiveData;
    ptr++;
    if(receiveData>='1' && receiveData<='4') //以1-4結尾代表收集結束
    {
        *ptr = 0;
        ptr = buf;
        os_send_signal(5);
    }
    SBUF=receiveData;
    while(!TI);
    TI=0;
}

 void job1(void)_task_ 1  {
       while(1) { 
          if(flag_1==1) {         
            LED1=~LED1;
            os_wait(K_TMO,100,0);
          }
          if(flag_1==0)
            LED1=1;      
       }
}  

void job2(void)_task_ 2 {
        while(1) {
          if(flag_2==1) {         
            LED2=~LED2;
            os_wait(K_TMO,63,0);
          }
          if(flag_2==0)
            LED2=1;      
        }
} 

void job3(void)_task_ 3 {
       while(1) {
          if(flag_3==1) {         
            LED3=~LED3;
            os_wait(K_TMO,25,0);
          }
          if(flag_3==0)
            LED3=1;      
       }
} 

void job4(void)_task_ 4 {
       while(1) {
          if(flag_4==1) {         
            LED4=~LED4;
            os_wait(K_TMO,16,0);
          }
          if(flag_4==0)
            LED4=1;      
       }
} 

void LED_control(void)_task_ 5
{              
     while(1)
     {  
       os_wait(K_SIG,0,0); 
       if(!(strcmp(ptr,a))) {flag_1 = 1;} //LED1亮   
       if(!(strcmp(ptr,b))) {flag_2 = 1;} //LED2亮   
       if(!(strcmp(ptr,c))) {flag_3 = 1;} //LED3亮           
       if(!(strcmp(ptr,d))) {flag_4 = 1;} //LED4亮    
       if(!(strcmp(ptr,e))) {flag_1 = 0;} //LED1滅  
       if(!(strcmp(ptr,f))) {flag_2 = 0;} //LED2滅 
       if(!(strcmp(ptr,g))) {flag_3 = 0;} //LED3滅         
       if(!(strcmp(ptr,h))) {flag_4 = 0;} //LED4滅                  
     }
}

void job0 (void)_task_ 0 //從task0開始運行
 {
     UARTIint();  
     os_create_task(1);     //創建任務1、2、3、4、5
     os_create_task(2);
     os_create_task(3);
     os_create_task(4);
     os_create_task(5);
     os_delete_task(0);     //刪除本任務0
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章