uC/OS-II 学习笔记:信号量实验

通过LED0、LED1发光二极管的闪烁显示来体现信号量的效果:

已知  设定信号量初值为0,LED0任务请求信号量(信号量+1),LED1发送信号量(信号量-1)

变量定义:  OS_EVENT *pSemaphore;  
                     INT8U err;

 对应函数:          pSemaphore = OSSemCreate(0);  //创建信号量,初值为0;

                             OSSemPost(pSemaphore);         //请求信号量

                             OSSemPend(pSemaphore, 0, &err);  //发送信号量

实验一:

      LED0:

                {    LED0=!LED0;   delay_ms(1000);  }

      LED1:

                {    LED1=!LED1;   delay_ms(500);  }

      现象:LED0、LED1同时闪烁,延时1000ms;

     解释:

            由于当LED1到达500ms延时时,由于信号量值为0,所以发送信号量失败,等到延时达到1000ms时,由于LED0请求信号量致使信号量值为1,此时可以发送信号量,所以在LED0=!LED0时,LED1!=LED1,出现的效果就是同时闪烁。

实验二:

      LED0:

                {    LED0=!LED0;   delay_ms(500);  }

      LED1:

                {    LED1=!LED1;   delay_ms(1000);  }

      现象:LED0闪烁周期为500ms*2;LED1闪烁周期为1000ms*2;信号量不能体现影响。

     解释:

            当LED0到达500ms延时时,由于LED0为请求信号量,信号量+1,所以请求成功并且信号量值+1,所以当到达1000ms时,LED1发送信号量时初值不为0,所以也可以成功。


附:完整代码(库函数除外)

#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h" 
#include "includes.h"
//开始任务
#define START_TASK_PRIO       10   //优先级
#define START_STK_SIZE   64  //任务堆栈大小
OS_STK START_TASK_STK[START_STK_SIZE]; //任务堆栈
void start_task(void *pdata);

//LED0任务
#define LED0_TASK_PRIO   7
#define LED0_STK_SIZE   64
OS_STK LED0_TASK_STK[LED0_STK_SIZE];
void led0_task(void *pdata);

//LED1任务
#define LED1_TASK_PRIO      6
#define LED1_STK_SIZE   64
OS_STK LED1_TASK_STK[LED1_STK_SIZE];
void led1_task(void *pdata);


//变量定义
OS_EVENT *pSemaphore;  
INT8U err;


int main(void)
{  
Stm32_Clock_Init(9);
delay_init(72);    
LED_Init();
LED_Init();  
OSInit();   
pSemaphore = OSSemCreate(0); //declare
OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );
OSStart();    

}

void start_task(void *pdata)
{
    OS_CPU_SR cpu_sr=0;
pdata = pdata; 
  OS_ENTER_CRITICAL();//进入临界区(避免被中断打断)     
  OSTaskCreate(led0_task,(void *)0,(OS_STK*)&LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO);  
  OSTaskCreate(led1_task,(void *)0,(OS_STK*)&LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO);
OSTaskSuspend(START_TASK_PRIO);//挂起起始任务
OS_EXIT_CRITICAL();    //退出临界区
}


//LED0
void led0_task(void *pdata)
{
while(1)
{

                OSSemPost(pSemaphore);
LED0=!LED0;
      delay_ms(1000);
};
}

//LED1
void led1_task(void *pdata)
{  
while(1)
{
     OSSemPend(pSemaphore, 0, &err);
LED1=!LED1;
delay_ms(500);
};
}

体会:改变任务的优先级对此代码的影响没有体现效果,分析原因是LED0、LED1谁先执行某一句代码效果一样。通过观察灯的闪烁看不出来区别。  


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值