RTOS_TINY中實現串列埠傳送字串控制LED
阿新 • • 發佈:2018-11-01
題目內容
在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
}