OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5104|回复: 7

用ucos执行个简单的任务总是想不通

[复制链接]

2

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2013-5-30
在线时间
0 小时
发表于 2013-12-24 20:06:52 | 显示全部楼层 |阅读模式
我想按下一个按键,让LED闪烁三次(此功能用原子例子消息邮箱已经实现),在闪烁三次期间,按下另一个按键,让这个LED立即熄灭,如果在建立个任务,按下按键让这个LED熄灭,那么那个LED闪烁三次的任务也会执行,这样是关闭不掉LED的。像处理这样的任务该怎么办啊?
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

54

主题

1008

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2382
金钱
2382
注册时间
2012-11-22
在线时间
403 小时
发表于 2013-12-24 20:19:04 | 显示全部楼层
你可以把闪烁的那个任务挂起或者删除。
态度决定一切
回复 支持 反对

使用道具 举报

2

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2013-5-30
在线时间
0 小时
 楼主| 发表于 2013-12-24 20:34:00 | 显示全部楼层
回复【2楼】冰封嗜魔:
---------------------------------
谢谢你的回答!我是新手,我想让这个任务能循环,就是按下按键一LED闪烁三次,在闪烁三次期间,如果按下按键二,让LED立即熄灭,如果不按按键二,将闪烁三次熄灭。然后再按下按键一LED闪烁三次。。。。。。这样子
回复 支持 反对

使用道具 举报

54

主题

1008

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2382
金钱
2382
注册时间
2012-11-22
在线时间
403 小时
发表于 2013-12-25 12:30:29 | 显示全部楼层
说不清楚,帮你写了个,你试试。
 #include "led.h"
#include "beep.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"  
#include "includes.h"   

//ALIENTEK????STM32??·?°????é54
//UCOSII???é2-2-???????¨?????????????????? 
//?????§????www.openedv.com
//?????????í??×?????????????  
 
/////////////////////////UCOSII?????????è??///////////////////////////////////
//START ????
//?è????????????
#define START_TASK_PRIO       10 //?????????????????è????×???
//?è???????????ó??
#define START_STK_SIZE   64
//???¨????????????
OS_STK START_TASK_STK[START_STK_SIZE];
//????????????
void start_task(void *pdata);
     
//LED????
//?è????????????
#define LED_TASK_PRIO        5 
//?è???????????ó??
#define LED_STK_SIZE        64
//???¨????????????
OS_STK LED_TASK_STK[LED_STK_SIZE];
//????????????
void led_task(void *pdata);


//°??ü?¨?è????
//?è????????????
#define KEY_TASK_PRIO        3 
//?è???????????ó??
#define KEY_STK_SIZE   64
//???¨????????????
OS_STK KEY_TASK_STK[KEY_STK_SIZE];
//????????????
void key_task(void *pdata);

u8 flag=0;
 int main(void)
 {  
delay_init();       //???±??????????   
NVIC_Configuration();   //?è??NVIC????·?×é2:2??????????????2???ì????????
LED_Init();    //????????LED??????????????
KEY_Init(); //°??ü??????
OSInit();     //??????UCOSII     
  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;         
OSStatInit(); //??????????????.?????á???±1????×ó??
  OS_ENTER_CRITICAL(); //??????????(??·¨±??????ò??)                      
  OSTaskCreate(key_task,(void *)0,(OS_STK*)&KEY_TASK_STK[KEY_STK_SIZE-1],KEY_TASK_PRIO);      
  OSTaskSuspend(START_TASK_PRIO); //????????????.
OS_EXIT_CRITICAL(); //??????????(????±??????ò??)
}   
  
//·??ù?÷????
void led_task(void *pdata)
{
while(1)
{  
if(flag==1)
{
LED1=0;
  delay_ms(500);
LED1=1;
  delay_ms(500);
LED1=0;
  delay_ms(500);
LED1=1;
  delay_ms(500);
LED1=0;
  delay_ms(500);
LED1=1;
delay_ms(500);
flag=0;
}
delay_ms(100);
}  
}

//°??ü?¨?è????
void key_task(void *pdata)
{
u8 key;       
while(1)
{
key=KEY_Scan(0);

if (key==KEY_2)
{
OSTaskDel(LED_TASK_PRIO);
LED1=1;
}
else if(key==KEY_1)
{
 OSTaskCreate(led_task,(void *)0,(OS_STK*)&LED_TASK_STK[LED_STK_SIZE-1],LED_TASK_PRIO);//???????¨????beep  
 flag=1;
}   
  delay_ms(10);
}
}
态度决定一切
回复 支持 反对

使用道具 举报

2

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2013-5-30
在线时间
0 小时
 楼主| 发表于 2013-12-25 13:44:05 | 显示全部楼层
回复【4楼】冰封嗜魔:
---------------------------------
谢谢你的回复,我理解你的意思了
回复 支持 反对

使用道具 举报

2

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2013-5-30
在线时间
0 小时
 楼主| 发表于 2013-12-26 20:23:46 | 显示全部楼层
回复【4楼】冰封嗜魔:
---------------------------------
你好!我有个疑问,刚才试了下用删除创建任务来达到我的目的,我是 把 你用的flag 更改成了消息邮箱,每次删除的时候 ,第一次按下按键,led灯不闪烁,按下第二次时候才闪烁,不知道为什么,用 flag 就可以了,我把代码贴下,麻烦你你帮我看下,

//控制DS0的亮灭.
void TaskLed(void *pdata)  //优先级为6
{ u8 result=0;
while(1)
{ result= *((u8 *)OSMboxPend(Str_Box,0,&err)); //请求消息邮箱
if(result ==3)

  LED0=!LED0;
  OSTaskDel(LED1_TASK_Prio);  //删除那个闪烁的任务
  LED1=1;                                  //让闪烁的那个LED灭掉
}
OSTimeDlyHMSM(0,0,0,2);
}
}
//任务2
//控制DS1的亮灭.
void TaskLed1(void *pdata)   //优先级 为5
{ u8 result=0;
u8 i;
while(1)
{  // result= *((u8 *)OSMboxPend(Str_Box,0,&err));//请求消息邮箱 
  //  if(result ==2)
   if(flag)           //在这里如果要是用 上面的消息邮箱的话,第一次按下按键不闪烁

 for(i=0;i<6;i++)//led闪烁三次
 {
  LED1=!LED1;
  OSTimeDlyHMSM(0,0,0,400);
 }
 flag = 0;
}
OSTimeDlyHMSM(0,0,0,1);
}
}

//任务3
//按键检测  
 void TaskKey(void *pdata)
 {
  u8  key=0,i=0;
   
    while(1){
  key=KEY_Scan();
  if(key==1) 
  {
     i=1;
   OSMboxPost(Str_Box,&i); //发送消息1
  }
  else if(key==2)
  {
   i=2;
   OSTaskCreate(TaskLed1, (void * )0, (OS_STK *)&TASK_LED1_STK[LED1_STK_SIZE-1], LED1_TASK_Prio);  
   flag = 1;
  // OSMboxPost(Str_Box,&i); //发送消息2  
  }
  else if(key==3)
  {
   i=3;
   OSMboxPostOpt(Str_Box,&i,OS_POST_OPT_BROADCAST); //向所有任务广播消息3
    }
  OSTimeDlyHMSM(0,0,0,20);  
}
 }

这是为什么呢?像传输按键这种信息,是不是没必要 用消息邮箱呢?
还有个问题就是 在原子这个例程里,当有两个任务在等待消息邮箱时候,为什么只让高优先级的任务收到消息,低优先级和高优先级里等待的内容不一样,像上面那个例子一个i = 1,一个i=2,为什么这块要这样设计呢?
回复 支持 反对

使用道具 举报

54

主题

1008

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2382
金钱
2382
注册时间
2012-11-22
在线时间
403 小时
发表于 2013-12-31 15:01:10 | 显示全部楼层
你广播消息后肯定是高优先级任务先运行,当它运行完后,此消息指针已被清零,笑一个低优先级任务肯定接收不到这个消息呀。所以才有了向所有任务广播消息这个功能。
态度决定一切
回复 支持 反对

使用道具 举报

2

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2013-5-30
在线时间
0 小时
 楼主| 发表于 2014-1-2 18:56:29 | 显示全部楼层
回复【7楼】冰封嗜魔:
---------------------------------
我明白了,我还是用全部变量吧
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 22:54

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表