题目内容
在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
}