1. 程式人生 > >RTOS_TINY中實現串列埠傳送字串控制LED

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 }