uc/os -Ⅱ操作系统实验

1.基础实验

1.1 跑马灯
两个任务,分别是按键和灯,按键控制跑马灯任务开始运行和停止挂起,跑马灯任务重4个LED灯轮流亮起熄灭。
1.2夜间自动照明系统
采集光敏传感器信号,将光照度大小显示在 LCD 显示屏上,并判断光照是
否小于预先设置的阈值,若小于,则高亮 LED 灯亮且维持 5 秒,并在 LCD 显示屏上提示“光照不足,开启照明”,若大于设置的阈值,关闭高亮 LED 灯,在LCD 显示屏上提示“光照充足,关闭照明”。通过按键 1、2 调节阈值光照强度。

2. 系统设计

2.1 模块图
在这里插入图片描述
实验一有三个任务,系统初始化任务,LED显示任务以及键盘扫描任务。
在这里插入图片描述
实验二有四个任务,分别为:光敏传感器监听任务,键盘扫描任务,系统初始化任务,LED显示任务。
2.2 流程图
在这里插入图片描述
该内容是实现LED灯的跑马灯,每一个DX_off()函数后面的延时可以取消。
在这里插入图片描述
该内容是实验一的键盘扫描函数,键盘输入“1”可挂起LED任务,键盘输入“2”可恢复LED任务。
在这里插入图片描述
光敏传感器监听任务与LED显示任务通过GtoLbox邮箱通信,键盘扫描任务与光敏传感器监听任务通过msg_key邮箱进行通信。
在这里插入图片描述
该任务是根据接收来自光敏任务的信息,来对LED进行控制,LED灯亮后,会持续五秒。
在这里插入图片描述
该任务作用是通过对键盘输入值的判断,来改变预先设定的光敏任务的阈值。
在这里插入图片描述
该任务,根据键盘扫描任务发送的消息来改变预定的阈值,并时刻读取传感器的值,进而判断是否对LED显示任务发送LED高亮任务,以及是否在LCD屏幕上显示提醒文字的作用。
2.3 开发环境
windows10

3.系统实现

3.1实验一 LED显示任务
算法描述:
1.D5_on(),睡眠0.25秒
2.D5_off(),睡眠0.25秒
3.D6_on(),睡眠0.25秒
4.D6_off(),睡眠0.25秒
5.D7_on(),睡眠0.25秒
6.D7_off(),睡眠0.25秒
7.D8_on(),睡眠0.25秒
8.D8_off(),睡眠0.25秒
9.回到步骤1
代码:

void TaskMy(void *p_arg)
{
	
    (void)p_arg;
    while (1)
    {
      //  OS_ENTER_CRITICAL();	//进入临界段(关中断)
     //   USART1Write("hello\n", sizeof("hello\n"));
      //  OS_EXIT_CRITICAL();		//退出临界段(开中断)
        D5_on();
        OSTimeDlyHMSM(0, 0, 0, 250);
        D5_off();
        OSTimeDlyHMSM(0, 0, 0, 250);
        D6_on();
        OSTimeDlyHMSM(0, 0, 0, 250);
        D6_off();
        OSTimeDlyHMSM(0, 0, 0, 250);
        D7_on();
        OSTimeDlyHMSM(0, 0, 0, 250);
        D7_off();
        OSTimeDlyHMSM(0, 0, 0, 250);
        D8_on();
        OSTimeDlyHMSM(0, 0, 0, 250);
        D8_off();
        OSTimeDlyHMSM(0, 0, 0, 250);
    }
}

3.2实验一 键盘扫描任务
算法描述:
1.使用key=key_board_scan();获取键盘输入值
2.判断key的值
2.1如果key等于1,挂起LED显示任务
2.2如果key等于2,复苏LED显示任务
3.回到步骤1
代码:

void TaskYou(void *p_arg)
{
    (void)p_arg;
    u8 key;	
    INT8U err;
    while (1)
    {
    key=key_board_scan();
    if(key == 8){
      err = OSTaskSuspend(1);
    }
    if(key == 12)
    {
      err = OSTaskResume(1);
    }}
}

3.3实验二 LED显示任务系统实现
初始设置:
//LED任务
//设置任务优先级
#define LED_TASK_PRIO 8
//设置任务堆栈大小
#define LED_STK_SIZE 512
//创建任务堆栈空间
OS_STK LED_TASK_STK[LED_STK_SIZE];
//任务函数接口
void led_task(void pdata);
算法描述:
1.使用OSMboxPend函数接收GtoLbox邮箱的值,并赋值给指针Led
2.判断Led指针指向的内容
2.1如果
Led 为1,调用D5_on(),持续五秒
3.睡眠1一秒
4.回到步骤1
代码:

void led_task(void *pdata)
{   
    (void)pdata;
    INT8U *Led;
    INT8U err;
	while(1)
	{ 
          Led = (INT8U *)OSMboxPend( ,0,&err);
          printf("Led %d",*Led);
          if(*Led == 1){
            D5_on();
            OSTimeDlyHMSM(0, 0, 5, 0);
            D5_off();
            
          }
            OSTimeDlyHMSM(0, 0, 1, 0);
	}									 
}	

3.4 实验二 光敏传感器监听系统任务实现
初始设置:
//光照任务
//设置任务优先级
#define Gmin_TASK_PRIO 9
//设置任务堆栈大小
#define Gmin_STK_SIZE 512
//创建任务堆栈空间
OS_STK Gmin_TASK_STK[BEEP_STK_SIZE];
//任务函数接口
void Gmin_task(void *pdata);
OS_EVENT GtoLbox;
算法描述:
1.使用OSMboxAccept接收邮箱msg_key的值并赋值给指针Limit
2.使用read_ADC()函数读取光敏传感器的值,fPhotoRes/ 4096.0 * 3.3并赋值给fPhotoRes
3.判断 Limit的值
3.1如果
Limit的值是1,阈值减小0.1
3.2如果
Limit的值是2,阈值增加0.1
4.如果fPhotoRes的值大于阈值
4.1LCD屏幕显示“光照不足,开启照明”,使用OSMboxPost(GtoLbox,(INT8U *)&Gmin)向LED任务,传递消息。
4.2LCD屏幕显示“光照充足,关闭照明”,使用OSMboxPost(GtoLbox,(INT8U *)&Gmin)向LED任务,传递消息。
5.睡眠1秒。
6.回到步骤1
代码:

void gmin_task(void *pdata) 
{
   (void)pdata;  
   float fPhotoRes;
   INT8U err;
   INT8U Gmin;
   INT8U *Limit;
   float doit = 2;
    while(1)
    {    
      Limit = (INT8U *)OSMboxAccept(msg_key); 
      fPhotoRes = read_ADC();
      fPhotoRes = fPhotoRes/ 4096.0 * 3.3;
      if(*Limit == 1)
      {
        doit += 0.1;
        //printf("%.lf  xianzhi %.2f \n\r", fPhotoRes, doit);
      }
      if(*Limit == 2)
      {
        doit -= 0.1;
      }
      if(fPhotoRes >= doit)
      {
        lcd_var_write(TEXT_TITLE, msg1, strlen(msg1));
        Gmin = 1;
        OSMboxPost(GtoLbox,(INT8U *)&Gmin);
      }
      else
      {
        lcd_var_write(TEXT_TITLE, msg2, strlen(msg2));
        Gmin = 0;
        OSMboxPost(GtoLbox,(INT8U *)&Gmin);
      }
      printf("doit = %.2f fPhotoRes = %.2f",doit,fPhotoRes);
      OSTimeDlyHMSM(0, 0, 1, 0);
    }
}

3.5实验二 键盘扫描系统任务实现
初始设置:
//按键扫描任务
//设置任务优先级
#define KEY_TASK_PRIO 10
//设置任务堆栈大小
#define KEY_STK_SIZE 512
//创建任务堆栈空间
OS_STK KEY_TASK_STK[KEY_STK_SIZE];
//任务函数接口
void key_task(void *pdata);
OS_EVENT *msg_key; //按键邮箱事件块指针
算法描述:
1.调用key_board_scan()获取键盘输入值
2.判断输入值
2.1如果输入值是1就向光敏传感器监听任务发送消息 1
2.2如果输入值是2就向光敏传感器监听任务发送消息2
3.回到步骤1
代码:

void key_task(void *pdata)
{	
  (void)pdata;
  u8 key;
  INT8U Keys;
  while(1)
  {
    key=key_board_scan();
    if(key == 8)
    {
      Keys = 1;
      OSMboxPost(msg_key,(INT8U *)&Keys);
    }
    if(key == 12)
    {
      Keys = 2;
      OSMboxPost(msg_key,(INT8U *)&Keys);
    }
  }
}

3.6 实验二 开始任务
初始设置:
//START 任务
//设置任务优先级
#define START_TASK_PRIO 18 //开始任务的优先级设置为最低
//设置任务堆栈大小
#define START_STK_SIZE 512
//创建任务堆栈空间
OS_STK START_TASK_STK[START_STK_SIZE];
//任务函数接口
void start_task(void pdata);
算法描述:
1.创建两个邮箱GtoLbox ,msg_key 使用函数OSMboxCreate((void
)0);
2.创建三个任务,分别为led_task,key_task,gmin_task。
代码:

OSStatInit();				//初始化统计任务.这里会延时1秒钟左右	
OS_ENTER_CRITICAL();			//进入临界区(无法被中断打断)    
GtoLbox = OSMboxCreate((void*)0); // 创建邮箱
msg_key = OSMboxCreate((void*)0);
OSTaskCreate(led_task,(void*)0,(OS_STK*)&LED_TASK_STK[LED_STK_SIZE-1],LED_TASK_PRIO);	
OSTaskCreate(key_task,(void*)0,(OS_STK*)&KEY_TASK_STK[KEY_STK_SIZE-1],KEY_TASK_PRIO);	
OSTaskCreate(gmin_task,(void*)0,(OS_STK*)&Gmin_TASK_STK[Gmin_STK_SIZE-1],Gmin_TASK_PRIO);
OS_EXIT_CRITICAL();				//退出临界区(可以被中断打断)

4.调试分析

4.1原理分析
实验一:
在实验一中,LED显示任务的优先级高于键盘扫描任务,键盘扫描任务在LED显示任务睡眠后,运行。
实验二:
整个项目从main函数开始运行,然后在main函数中创建了开始任务,以及所用设备的初始化,开始任务创建后开始执行开始任务,开始任务的内容是创建了两个邮箱,以及三个新任务,三个新任务的优先级都是高于开始任务的,此时任务队列中有四个函数,优先级关系为:LED显示任务>光敏传感器扫描任务>键盘扫描任务>开始任务。
因为LED显示任务执行了OSMboxPend()函数,但此时没有任务向其传递消息,所以LED任务被挂起,然后执行了光敏传感器扫描任务,执行完成后睡眠一秒,并向LED任务传递了消息,然后执行了LED任务,然后LED任务睡眠,然后在上述两个任务苏醒之前,执行键盘扫描任务。
4.2分析
实验一:
实验一调试过程十分流畅,任务挂起函数为OSTaskSuspend(),任务复苏函数为OSTaskResume().
实验二:
光敏传感器的使用样例在《STM32+ucosii试验箱光盘内容》中,该样例能正常运行,直接使用可移植模板会报错,需要将样例中的abc.c文件覆盖模板中的该文件,这样就可以正常运行,但是出现了任务一直处于睡眠的情况,原因是堆栈空间过小,增加空间后就可规避该问题。再后来就是OSMboxPend()函数和OSMboxAccept()函数的使用区别,OSMboxPend()函数如果没有收到消息会让任务挂起,但是OSMboxAccept()函数不会,实验要求是可以通过键盘来改变设定的阈值大小,如果光敏传感器监听任务使用OSMboxPend()函数来接收键盘扫描任务的消息,会变成只有键盘扫描任务向光敏任务发送消息,光敏任务才能执行。通过实践,这种方式带来的用户体验很差,使用OSMboxAccept()函数就可规避这个问题,并且光敏任务优先级高于键盘任务,并且执行完成后睡眠1秒,光敏任务的实际执行时间很短,光敏任务睡眠和LED任务睡眠的时间占了很大一部分比例,这也就说明键盘扫描函数的执行时间远远高于其余任务,这样可以让用户感觉不到输入时延,提高用户体验。最终持续在这样的逻辑下能够正常运行。

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dearzcs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值