事件标志管理 (EVENT FLAGS MANAGEMENT)
OSFlagAccept() 无等待查询”事件标志组的事件标志位”是否建立
OSFlagPend() 需要等待”事件标志组的事件标志位”建立
OSFlagCreate() 建立一个事件标志组
OSFlagDel() 删除一个事件标志组
OSFlagPost() 置位或清0事件标志组中的标志位
OSFlagQuery() 查询事件标志组的当前事件标志状态
如果有条件,还是事先去看uCOSii中的事件标志管理函数,很多人没有写函数功能,很难理解。
//函数功能:无需等待,接收事件标志组的事件标志位
wait_type的bit7=1,若接收到的事件标志组的位值正确,则同时把事件标志组的位值清除掉,这个带”清除事件标志组的位”功能;
OS_FLAG_WAIT_CLR_ALL= OS_FLAG_WAIT_CLR_AND=0u
OS_FLAG_WAIT_CLR_ANY= OS_FLAG_WAIT_CLR_OR=1
OS_FLAG_WAIT_SET_ALL= OS_FLAG_WAIT_SET_AND=2
OS_FLAG_WAIT_SET_ANY= OS_FLAG_WAIT_SET_OR=3
wait_type可以取上面的值
pgrp为事件标志组指针
根据flags接收指定的事件标志组的位值
perr = OS_ERR_NONE,表示发送正确,返回值与 flags相与后等于flags;
perr != OS_ERR_NONE,表示发送错误,返回值与 flags相与后不等于flags;
OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp,
OS_FLAGS flags,
INT8U wait_type,
INT8U *perr)
{
OS_FLAGS flags_rdy;
INT8U result;
BOOLEAN consume;
#if OS_CRITICAL_METHOD == 3u
/* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICAL
if (perr == (INT8U *)0)
{// perr指针为0
OS_SAFETY_CRITICAL_EXCEPTION();
}
#endif
#if OS_ARG_CHK_EN > 0u
if (pgrp == (OS_FLAG_GRP *)0)
{//事件标志组指针为零
*perr = OS_ERR_FLAG_INVALID_PGRP;
return ((OS_FLAGS)0);
}
#endif
if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG)
{//若不是”事件标志组类型”
*perr = OS_ERR_EVENT_TYPE;
return ((OS_FLAGS)0);
}
result = (INT8U)(wait_type & OS_FLAG_CONSUME);
//OS_FLAG_CONSUME=0x80
if (result != (INT8U)0)
{ //发现wait_type的bit7为1, 要求清除事件标志位
wait_type &= ~OS_FLAG_CONSUME;//将wait_type的bit7置0
consume = OS_TRUE;
}
else
{//wait_type正确
consume = OS_FALSE;
}
*perr = OS_ERR_NONE;//假定没有错误
OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量
switch (wait_type)
{
case OS_FLAG_WAIT_SET_ALL:
flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags);
// 根据flags读取”事件标志组”中的位值
if (flags_rdy == flags)
{//接收到的事件信号正确
if (consume == OS_TRUE)
{// wait_type的bit7=1,需要清除接收到事件标志
pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy;
}
}
else
{//接收到的事件信号错误
*perr = OS_ERR_FLAG_NOT_RDY;
//OS_ERR_FLAG_NOT_RDY=112
}
OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)
break;
case OS_FLAG_WAIT_SET_ANY:
flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags);
// 根据flags读取”事件标志组”中的位值
if (flags_rdy != (OS_FLAGS)0)
{//接收到的事件信号正确
if (consume == OS_TRUE)
{// wait_type的bit7=1,需要清除接收到事件标志
pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy;
}
}
else
{//接收到的事件信号错误
*perr = OS_ERR_FLAG_NOT_RDY;
}
OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)
break;
#if OS_FLAG_WAIT_CLR_EN > 0u
case OS_FLAG_WAIT_CLR_ALL:
flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags;
// 根据flags读取”事件标志组”中的位值
if (flags_rdy == flags)
{//接收到的事件信号正确
if (consume == OS_TRUE)
{// wait_type的bit7=1,需要清除接收到事件标志
pgrp->OSFlagFlags |= flags_rdy;
}
}
else
{//接收到的事件信号错误
*perr = OS_ERR_FLAG_NOT_RDY;
}
OS_EXIT_CRITICAL();
break;
case OS_FLAG_WAIT_CLR_ANY:
flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags;
// 根据flags读取”事件标志组”中的位值
if (flags_rdy != (OS_FLAGS)0)
{//接收到的事件信号正确
if (consume == OS_TRUE)
{// wait_type的bit7=1,需要清除接收到事件标志
pgrp->OSFlagFlags |= flags_rdy;
}
}
else {//接收到的事件信号错误
*perr = OS_ERR_FLAG_NOT_RDY;
}
OS_EXIT_CRITICAL();
break;
#endif
default:
OS_EXIT_CRITICAL();
flags_rdy = (OS_FLAGS)0;
*perr = OS_ERR_FLAG_WAIT_TYPE;
break;
}
return (flags_rdy);
}
//函数功能:等待接收事件标志组的事件标志位
wait_type的bit7=1,若接收到的事件标志组的位值正确,则同时把事件标志组的位值清除掉,这个带”清除事件标志组的位”功能;
OS_FLAG_WAIT_CLR_ALL= OS_FLAG_WAIT_CLR_AND=0u
OS_FLAG_WAIT_CLR_ANY= OS_FLAG_WAIT_CLR_OR=1
OS_FLAG_WAIT_SET_ALL= OS_FLAG_WAIT_SET_AND=2
OS_FLAG_WAIT_SET_ANY= OS_FLAG_WAIT_SET_OR=3
wait_type可以取上面的值
pgrp为事件标志组指针
根据flags接收指定的事件标志组的位值
perr = OS_ERR_NONE,表示发送正确,返回值与 flags相与后等于flags;
perr != OS_ERR_NONE,表示发送错误,返回值与 flags相与后不等于flags;
Timeout=0表示一直等待信号,直到条件满足为止
OS_FLAGS OSFlagPend (OS_FLAG_GRP *pgrp,
OS_FLAGS flags,
INT8U wait_type,
INT32U timeout,
INT8U *perr)
{
OS_FLAG_NODE node;
OS_FLAGS flags_rdy;
INT8U result;
INT8U pend_stat;
BOOLEAN consume;
#if OS_CRITICAL_METHOD == 3u
OS_CPU_SR cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICAL
if (perr == (INT8U *)0)
{ //perr指针为0
OS_SAFETY_CRITICAL_EXCEPTION();
}
#endif
#if OS_ARG_CHK_EN > 0u
if (pgrp == (OS_FLAG_GRP *)0)
{ //pgrp指针为0
*perr = OS_ERR_FLAG_INVALID_PGRP;
return ((OS_FLAGS)0);
}
#endif
if (OSIntNesting > 0u)
{//中断嵌套级别
*perr = OS_ERR_PEND_ISR;
return ((OS_FLAGS)0);
}
if (OSLockNesting > 0u)
{
*perr = OS_ERR_PEND_LOCKED;
return ((OS_FLAGS)0);
}
if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG)
{//若不是”事件标志组类型”
*perr = OS_ERR_EVENT_TYPE;
return ((OS_FLAGS)0);
}
result = (INT8U)(wait_type & OS_FLAG_CONSUME);
//OS_FLAG_CONSUME=0x80
if (result != (INT8U)0)
{//发现wait_type的bit7为1, 要求清除事件标志位
wait_type &= (INT8U)~(INT8U)OS_FLAG_CONSUME;
consume = OS_TRUE;
}
else
{//发现wait_type的bit7为0, 不要求清除事件标志位
consume = OS_FALSE;
}
OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量
switch (wait_type)
{
case OS_FLAG_WAIT_SET_ALL:
flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags);
// 根据flags读取”事件标志组”中的位值
if (flags_rdy == flags)
{ //接收到的事件信号正确
if (consume == OS_TRUE)
{ // wait_type的bit7=1,需要清除接收到事件标志
pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy;
}
OSTCBCur->OSTCBFlagsRdy = flags_rdy;
// 保存事件标志组信号,后面需要读回该值
OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)
*perr= OS_ERR_NONE;
return (flags_rdy);
}
else
{//接收到的事件信号错误
OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
OS_EXIT_CRITICAL();
}
break;
case OS_FLAG_WAIT_SET_ANY:
flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & flags);
// 根据flags读取”事件标志组”中的位值
if (flags_rdy != (OS_FLAGS)0)
{ //接收到的事件信号正确
if (consume == OS_TRUE)
{// wait_type的bit7=1,需要清除接收到事件标志
pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy;
}
OSTCBCur->OSTCBFlagsRdy = flags_rdy;
// 保存事件标志组信号,后面需要读回该值
OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)
*perr = OS_ERR_NONE;
return (flags_rdy);
}
else
{//接收到的事件信号错误
OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)
}
break;
#if OS_FLAG_WAIT_CLR_EN > 0u
case OS_FLAG_WAIT_CLR_ALL:
flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags;
// 根据flags读取”事件标志组”中的位值
if (flags_rdy == flags)
{ //接收到的事件信号正确
if (consume == OS_TRUE)
{// wait_type的bit7=1,需要清除接收到事件标志
pgrp->OSFlagFlags |= flags_rdy;
}
OSTCBCur->OSTCBFlagsRdy = flags_rdy;
// 保存事件标志组信号,后面需要读回该值
OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)
*perr= OS_ERR_NONE;
return (flags_rdy);
}
else
{//接收到的事件信号错误
OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)
}
break;
case OS_FLAG_WAIT_CLR_ANY:
flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & flags;
// 根据flags读取”事件标志组”中的位值
if (flags_rdy != (OS_FLAGS)0)
{//接收到的事件信号正确
if (consume == OS_TRUE)
{// wait_type的bit7=1,需要清除接收到事件标志
pgrp->OSFlagFlags |= flags_rdy;
}
OSTCBCur->OSTCBFlagsRdy = flags_rdy;
// 保存事件标志组信号,后面需要读回该值
OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)
*perr = OS_ERR_NONE;
return (flags_rdy);
}
else
{//接收到的事件信号错误
OS_FlagBlock(pgrp, &node, flags, wait_type, timeout);
OS_EXIT_CRITICAL();//退出临界区(可以被中断打断)
}
break;
#endif
default:
OS_EXIT_CRITICAL();
flags_rdy = (OS_FLAGS)0;
*perr = OS_ERR_FLAG_WAIT_TYPE;
return (flags_rdy);
}
OS_Sched(); //任务调度
OS_ENTER_CRITICAL();//进入临界区(无法被中断打断),需要定义cpu_sr变量
if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK)
{//若发现超时等待或中止等待
pend_stat = OSTCBCur->OSTCBStatPend;
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;
OS_FlagUnlink(&node);
OSTCBCur->OSTCBStat = OS_STAT_RDY;
OS_EXIT_CRITICAL();
flags_rdy = (OS_FLAGS)0;
switch (pend_stat)
{
case OS_STAT_PEND_ABORT:
*perr = OS_ERR_PEND_ABORT;// 表明中止等待
break;
case OS_STAT_PEND_TO:
default:
*perr = OS_ERR_TIMEOUT; //表明超时等待
break;
}
return (flags_rdy);
}
/没有发现超时等待或中止等待//
flags_rdy = OSTCBCur->OSTCBFlagsRdy;//读回保存的”事件标志组信号”
if (consume == OS_TRUE)
{ // wait_type的bit7=1,需要清除接收到事件标志
switch (wait_type)
{
case OS_FLAG_WAIT_SET_ALL:
case OS_FLAG_WAIT_SET_ANY: /* Clear ONLY the flags we got */
pgrp->OSFlagFlags &= (OS_FLAGS)~flags_rdy;
break;
#if OS_FLAG_WAIT_CLR_EN > 0u
case OS_FLAG_WAIT_CLR_ALL:
case OS_FLAG_WAIT_CLR_ANY: /* Set ONLY the flags we got */
pgrp->OSFlagFlags |= flags_rdy;
break;
#endif
default:
OS_EXIT_CRITICAL();
*perr = OS_ERR_FLAG_WAIT_TYPE;
return ((OS_FLAGS)0);
}
}
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
return (flags_rdy);
}
//函数功能:将事件标志组中的标志位置位或清0
pgrp为事件标志组指针
根据flags发送指定的事件标志组的位值
perr = OS_ERR_NONE,表示发送正确,返回值与 flags相与后等于flags;
perr != OS_ERR_NONE,表示发送错误,返回值与 flags相与后不等于flags;
opt 取值为: opt= OS_FLAG_SET,opt=OS_FLAG_CLR
OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp,
OS_FLAGS flags,
INT8U opt,
INT8U *perr)
{
OS_FLAG_NODE *pnode;
BOOLEAN sched;
OS_FLAGS flags_cur;
OS_FLAGS flags_rdy;
BOOLEAN rdy;
#if OS_CRITICAL_METHOD == 3u
OS_CPU_SR cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICAL
if (perr == (INT8U *)0)
{// perr指针为0
OS_SAFETY_CRITICAL_EXCEPTION();
}
#endif
#if OS_ARG_CHK_EN > 0u
if (pgrp == (OS_FLAG_GRP *)0)
{// pgrp指针为0
*perr = OS_ERR_FLAG_INVALID_PGRP;
return ((OS_FLAGS)0);
}
#endif
if (pgrp->OSFlagType != OS_EVENT_TYPE_FLAG)
{//若不是”事件标志组类型”
*perr = OS_ERR_EVENT_TYPE;
return ((OS_FLAGS)0);
}
OS_ENTER_CRITICAL();
switch (opt)
{
case OS_FLAG_CLR:
pgrp->OSFlagFlags &= (OS_FLAGS)~flags;
//根据flags的值,将pgrp->OSFlagFlags相应的位置0
break;
case OS_FLAG_SET:
pgrp->OSFlagFlags |= flags;
//根据flags的值,将pgrp->OSFlagFlags相应的位置1
break;
default:
OS_EXIT_CRITICAL();
*perr = OS_ERR_FLAG_INVALID_OPT;
return ((OS_FLAGS)0);
}
sched = OS_FALSE;
pnode = (OS_FLAG_NODE *)pgrp->OSFlagWaitList;
while (pnode != (OS_FLAG_NODE *)0)
{/* Go through all tasks waiting on event flag(s) */
switch (pnode->OSFlagNodeWaitType)
{
case OS_FLAG_WAIT_SET_ALL:
flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & pnode->OSFlagNodeFlags);
if (flags_rdy == pnode->OSFlagNodeFlags)
{
rdy = OS_FlagTaskRdy(pnode, flags_rdy);
if (rdy == OS_TRUE)
{
sched = OS_TRUE;
}
}
break;
case OS_FLAG_WAIT_SET_ANY:
flags_rdy = (OS_FLAGS)(pgrp->OSFlagFlags & pnode->OSFlagNodeFlags);
if (flags_rdy != (OS_FLAGS)0)
{
rdy = OS_FlagTaskRdy(pnode, flags_rdy);
if (rdy == OS_TRUE)
{
sched = OS_TRUE;
}
}
break;
#if OS_FLAG_WAIT_CLR_EN > 0u
case OS_FLAG_WAIT_CLR_ALL:
flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
if (flags_rdy == pnode->OSFlagNodeFlags)
{
rdy = OS_FlagTaskRdy(pnode, flags_rdy);
if (rdy == OS_TRUE)
{
sched = OS_TRUE;
}
}
break;
case OS_FLAG_WAIT_CLR_ANY:
flags_rdy = (OS_FLAGS)~pgrp->OSFlagFlags & pnode->OSFlagNodeFlags;
if (flags_rdy != (OS_FLAGS)0)
{
rdy = OS_FlagTaskRdy(pnode, flags_rdy);
if (rdy == OS_TRUE)
{
sched = OS_TRUE;
}
}
break;
#endif
default:
OS_EXIT_CRITICAL();
*perr = OS_ERR_FLAG_WAIT_TYPE;
return ((OS_FLAGS)0);
}
pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;
/* Point to next task waiting for event flag(s) */
}
OS_EXIT_CRITICAL();
if (sched == OS_TRUE)
{
OS_Sched();
}
OS_ENTER_CRITICAL();
flags_cur = pgrp->OSFlagFlags;
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
return (flags_cur);
}
#include "My_Task_Priority.h"
__align(8) OS_STK START_TASK_STACK[START_TASK_STACK_SIZE]; //START_TASK任务堆栈
__align(8) OS_STK LED0_TASK_STACK[LED0_TASK_STACK_SIZE]; //LED0_TASK任务堆栈
__align(8) OS_STK LED1_TASK_STACK[LED1_TASK_STACK_SIZE]; //LED1_TASK任务堆栈
__align(8) OS_STK KEY_TASK_STACK[KEY_TASK_STACK_SIZE]; //KEY_TASK任务堆栈
//如果任务中使用printf来打印浮点数据的话一点要8字节对齐
OS_FLAG_GRP *EventFlags; //事件标志组指针,Event Flag Group
//My_Task_Priority.h
#ifndef __MY_TASK_PRIORITY_H
#define __MY_TASK_PRIORITY_H
#include "includes.h"
//当OS_LOWEST_PRIO=63时,μC/OS-II有64个优先级,优先级的高低按编号从0(最高)到63(最低)排序;
//OS_TASK_IDLE_PRIO为63,是空闲任务优先级,OS_TASK_IDLE_ID为65535
//OS_TASK_STAT_PRIO为62,是统计任务优先级,OS_TASK_STAT_ID为65534
//uCOSii至少有两个任务,分别是"空闲任务"和"统计任务"
/*
为了保证“启动任务”能够连续运行,必须将“启动任务”的优先级选择为最高。
否则,当“启动任务”创建一个优先级高于自己的任务时,刚刚创建的任务就
会立即进入运行状态,而与这个任务关联的其它任务可能还没有创建,它使
用的通信工具也还没有创建,系统必然出错。
*/
#define START_TASK_PRIORITY 4 //设置START_TASK任务优先级,开始任务的优先级设置为最高
#define START_TASK_STACK_SIZE 192 //设置START_TASK任务堆栈大小,为8的倍数
extern OS_STK START_TASK_STACK[START_TASK_STACK_SIZE]; //START_TASK任务堆栈
#define LED0_TASK_PRIORITY 5 //设置LED0_TASK任务优先级为5
#define LED0_TASK_STACK_SIZE 56 //设置LED0_TASK任务堆栈大小为56,为8的倍数
extern OS_STK LED0_TASK_STACK[LED0_TASK_STACK_SIZE]; //LED0_TASK任务堆栈
#define LED1_TASK_PRIORITY 6 //设置LED1_TASK任务优先级为6
#define LED1_TASK_STACK_SIZE 72 //设置LED1_TASK任务堆栈大小为72,为8的倍数
extern OS_STK LED1_TASK_STACK[LED1_TASK_STACK_SIZE]; //LED1_TASK任务堆栈
#define KEY_TASK_PRIORITY 7 //设置KEY_TASK任务优先级为7
#define KEY_TASK_STACK_SIZE 56 //设置KEY_TASK任务堆栈大小为56,为8的倍数
extern OS_STK KEY_TASK_STACK[KEY_TASK_STACK_SIZE]; //KEY_TASK任务堆栈
extern OS_FLAG_GRP *EventFlags; //事件标志组指针,Event Flag Group
/OS_FLAGS数据的位数///
//在os_cfg.h中定义OS_FLAGS_NBITS=16,表示"OS_FLAGS数据的位数为16"
#define KEY0_FLAG 0x0001 //KEY0位于bit0
#define KEY1_FLAG 0x0002 //KEY1位于bit1
#define KEY2_FLAG 0x0004 //KEY2位于bit2
#define KEY3_FLAG 0x0008 //KEY3位于bit3
#define KEY4_FLAG 0x0010 //KEY4位于bit4
#define KEY5_FLAG 0x0020 //KEY5位于bit5
#define KEY6_FLAG 0x0040 //KEY6位于bit6
#define KEY7_FLAG 0x0080 //KEY7位于bit7
#define KEY8_FLAG 0x0001 //KEY8位于bit8
#define KEY9_FLAG 0x0002 //KEY9位于bit9
#define KEY10_FLAG 0x0004 //KEY10位于bit10
#define KEY11_FLAG 0x0008 //KEY11位于bit11
#define KEY12_FLAG 0x0010 //KEY12位于bit12
#define KEY13_FLAG 0x0020 //KEY13位于bit13
#define KEY14_FLAG 0x0040 //KEY14位于bit14
#define KEY15_FLAG 0x0080 //KEY15位于bit15
#endif
#include "Start_Task.h"
#include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "LED.h"
#include "key.h"
#include "My_Task_Priority.h"
#include "LED0_Task.h"
#include "LED1_Task.h"
#include "Key_Task.h"
void Start_Task(void *pdata);
const char Start_Task_rn_REG[]="\r\n";
const char Start_Task_Initialise_REG[]="Start_Task Initialise";
//Start_Task任务
void Start_Task(void *pdata)
{
OS_CPU_SR cpu_sr=0;
u8 err;
pdata = pdata;
printf("%s",Start_Task_rn_REG);
printf("%s",Start_Task_Initialise_REG);
LED0_Init();
LED1_Init();
KEY_Init();
OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断),需要定义cpu_sr变量
EventFlags=OSFlagCreate(0,&err);
//建立一个事件标志组
OSTaskCreate( LED0_Task,/* 函数指针*/
(void *)0,/* 建立任务时,传递的参数*/
(OS_STK*)&LED0_TASK_STACK[LED0_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
LED0_TASK_PRIORITY/* 任务优先级*/
);
OSTaskCreate( LED1_Task,/* 函数指针*/
(void *)0,/* 建立任务时,传递的参数*/
(OS_STK*)&LED1_TASK_STACK[LED1_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
LED1_TASK_PRIORITY/* 任务优先级*/
);
OSTaskCreate( Key_Task,/* 函数指针*/
(void *)0,/* 建立任务时,传递的参数*/
(OS_STK*)&KEY_TASK_STACK[KEY_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
KEY_TASK_PRIORITY/* 任务优先级*/
);
//OSTaskSuspend(START_TASK_PRIO); //挂起起始任务Start_Task(),但不删除
OSTaskDel(OS_PRIO_SELF); //删除自己
OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)
}
#include "LED0_Task.h"
#include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "LED.h"
#include "My_Task_Priority.h"
void LED0_Task(void *pdata);
const char LED0_Task_rn_REG[]="\r\n";
const char LED0_Task_Initialise_REG[]="LED0_Task Initialise";
//LED0_Task任务
void LED0_Task(void *pdata)
{
u8 err;
OS_FLAGS retFlag,inputFlag;
printf("%s",LED0_Task_rn_REG);
printf("%s",LED0_Task_Initialise_REG);
while(1)
{
inputFlag=(OS_FLAGS)(KEY0_FLAG|KEY2_FLAG);
// retFlag=OSFlagPend(
// EventFlags,//事件标志组指针&err
// inputFlag,//接收"事件标志组的第0位和第2位"
// OS_FLAG_WAIT_SET_AND,//若"事件标志组的第0位和第2位"同时置为1时为有效,否则将任务挂在这里
// 0,//无限等待,直到收到为止
// &err );
// printf("LED0事件标志组EventFlags的值:%d\r\n",retFlag);
// LED0=!LED0;
// OSFlagPost(
// EventFlags,//事件标志组指针
// (OS_FLAGS)KEY0_FLAG,//给事件标志组的第0位发信号
// OS_FLAG_CLR,//将事件标志组的第0位置0
// &err
// );
// if( err==OS_ERR_NONE && (retFlag&KEY0_FLAG)==KEY0_FLAG)//事件标志发送正确
// {
// }
retFlag=OSFlagAccept(
EventFlags,//事件标志组指针&err
inputFlag,//接收"事件标志组的第0位和第2位"
OS_FLAG_WAIT_SET_AND,//若"事件标志组的第0位和第2位"同时置为1时为有效,否则将任务挂在这里
&err );
if( err==OS_ERR_NONE && (inputFlag&retFlag)==inputFlag)//接收正确
{
printf("LED0事件标志组EventFlags的值:%d\r\n",retFlag);
LED0=!LED0;
inputFlag=KEY0_FLAG;
retFlag=OSFlagPost(
EventFlags,//事件标志组指针
inputFlag,//给事件标志组的第0位发信号
OS_FLAG_CLR,//将事件标志组的第0位置0
&err
);
if( err==OS_ERR_NONE && (retFlag&inputFlag)==inputFlag)//事件标志发送正确
{
}
}
OSTimeDlyHMSM(0,0,0,500);//延时500ms
}
}
#include "LED1_Task.h"
#include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "LED.h"
#include "My_Task_Priority.h"
void LED1_Task(void *pdata);
const char LED1_Task_rn_REG[]="\r\n";
const char LED1_Task_Initialise_REG[]="LED1_Task Initialise";
//LED1_Task任务
void LED1_Task(void *pdata)
{
u8 err;
OS_FLAGS retFlag,inputFlag;
printf("%s",LED1_Task_rn_REG);
printf("%s",LED1_Task_Initialise_REG);
while(1)
{
inputFlag=KEY2_FLAG;
//若等待事件标志没有发生 该函数挂起该任务
retFlag=OSFlagPend(
EventFlags,//事件标志组指针
inputFlag,//接收"事件标志组的第2位"
OS_FLAG_WAIT_SET_ALL,//若"事件标志组的第2位"置为1时为有效,否则将任务挂在这里
0,//无限等待,直到收到为止
&err );
printf("LED1事件标志组EventFlags的值:%d\r\n",retFlag);
LED1=!LED1;
retFlag=OSFlagPost(
EventFlags,//事件标志组指针
inputFlag,//给事件标志组的第2位发信号
OS_FLAG_CLR,//将事件标志组的第2位置0
&err
);
if( err==OS_ERR_NONE && (retFlag&inputFlag)==inputFlag)//事件标志发送正确
{
}
OSTimeDlyHMSM(0,0,0,200);//延时200毫秒
}
}
#include "Key_Task.h"
#include "delay.h"
#include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "key.h"
#include "My_Task_Priority.h"
#include "LED1_Task.h"
const char Key_Task_rn_REG[]="\r\n";
const char Key_Task_Initialise_REG[]="Key_Task Initialise";
void Key_Task(void *pdata);
//Key_Task任务
void Key_Task(void *pdata)
{
u8 key,err;
OS_FLAGS retFlag,inputFlag;
printf("%s",Key_Task_rn_REG);
printf("%s",Key_Task_Initialise_REG);
while(1)
{
key=KEY_Scan(0);
if(key==Cursor_Up)
{
inputFlag=KEY0_FLAG;
retFlag=OSFlagPost(
EventFlags,//事件标志组指针
(OS_FLAGS)inputFlag,//给事件标志组的第0位发信号
OS_FLAG_SET,//将事件标志组的第0位置1
&err );
if( err==OS_ERR_NONE && (inputFlag&retFlag)==inputFlag)//事件标志发送正确
printf("\r\nKey事件标志组EventFlags的值:%d\r\n",retFlag);
}
else if (key==Cursor_Down)
{
inputFlag=KEY2_FLAG;
retFlag=OSFlagPost(
EventFlags,//事件标志组指针
inputFlag,//给事件标志组的第2位发信号
OS_FLAG_SET,//将事件标志组的第2位置1
&err );
if( err==OS_ERR_NONE && (retFlag&inputFlag)==inputFlag )//事件标志发送正确
printf("\r\nKey事件标志组EventFlags的值:%d\r\n",retFlag);
}
else if (key==Cursor_Left)
{
inputFlag=(OS_FLAGS)(KEY0_FLAG|KEY2_FLAG);
retFlag=OSFlagPost(
EventFlags,//事件标志组指针
inputFlag,//给事件标志组的第0位和第2位发信号
OS_FLAG_SET,//将事件标志组的第0位和第2位置1
&err );
if( err==OS_ERR_NONE && (inputFlag&retFlag)==inputFlag)//事件标志发送正确
printf("\r\nKey事件标志组EventFlags的值:%d\r\n",retFlag);
}
OSTimeDlyHMSM(0,0,0,500);//延时500ms
}
}
#include "LED.h"
void LED0_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//使用GPIO_InitTypeDef定义一个结构变量GPIO_InitStructure;
RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOE, ENABLE ); //在配置外设之前,必须先使能GPIOE的外设时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4; //选择第4脚
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置引脚的最高输出速率为50MHz
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //设置引脚工作模式为推挽输出方式
GPIO_Init( GPIOE, &GPIO_InitStructure); //根据GPIO_InitStructure结构变量指定的参数初始化GPIOE的外设寄存器
}
void LED1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//使用GPIO_InitTypeDef定义一个结构变量GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); //使能GPIOE的外设时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //选择第5脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚工作模式为推挽输出方式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚的最高输出速率为50MHz
GPIO_Init(GPIOE, &GPIO_InitStructure);
//根据GPIO_InitStructure结构变量指定的参数初始化GPIOE的外设寄存器
}
void LED_Init(void)
{
LED0_Init();
LED1_Init();
}
#include "KEY.h"
#include "delay.h"
void KEY_Init(void);
u8 KEY_Scan(u8 mode);
//函数功能:将PB12,PB13,PB14,PB15,PD8初始化为输入口
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//使用GPIO_InitTypeDef定义一个结构变量GPIO_InitStructure;
RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOB, ENABLE ); //在配置外设之前,必须先使能GPIOB的外设时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; //选择第12,13,14和15脚
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置引脚的最高输出速率为50MHz
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //输入上拉,按钮输入低电平有效
GPIO_Init( GPIOB, &GPIO_InitStructure);
//根据GPIO_InitStructure结构变量指定的参数初始化GPIOB的外设寄存器
RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOD, ENABLE ); //在配置外设之前,必须先使能GPIOD的外设时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8; //选择第8脚
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置引脚的最高输出速率为50MHz
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //输入上拉,按钮输入低电平有效
GPIO_Init( GPIOD, &GPIO_InitStructure);
//根据GPIO_InitStructure结构变量指定的参数初始化GPIOD的外设寄存器
}
//函数功能:按键扫描,按键检测时间为50ms
u8 KEY_Scan(u8 mode)
{
u8 i;
u8 ch0;
u8 ch1;
u8 retData;
static u8 key_backup=1;//记录按键被释放
if(mode == 1) key_backup=1;//记录按键被释放
retData=0;//假定无按键按下
ch0=0;ch1=0;
if(key_backup==1)
{
if( KEY2==0) ch0=Cursor_Right; //记录按键值
if( KEY3==0) ch0=Cursor_Up; //记录按键值
if( KEY1==0) ch0=Cursor_Left; //记录按键值
if( KEY4==0) ch0=Cursor_Down; //记录按键值
if( KEY5==0) ch0=OK; //记录按键值
}
if(ch0) i=0;
else i=200;
for(;i<20;)
{
i++;
ch1=0;
delay_ms(5);
if(KEY2==0) ch1=Cursor_Right; //记录按键值,向右
if(KEY3==0) ch1=Cursor_Up; //记录按键值,向上
if(KEY1==0) ch1=Cursor_Left; //记录按键值,向左
if(KEY4==0) ch1=Cursor_Down; //记录按键值,向下
if(KEY5==0) ch1=OK; //记录按键值,确认
if(ch1!=ch0) i=100;
}
if(i==20) retData=ch0;
else retData=0;
ch1=0;
if(KEY1==1) ch1=1;
if(KEY2==1) ch1=(u8)(ch1<<1);
if(KEY3==1) ch1=(u8)(ch1<<1);
if(KEY4==1) ch1=(u8)(ch1<<1);
if(KEY5==1) ch1=(u8)(ch1<<1);
if(ch1==0x20) key_backup=1;//记录按键被释放
return retData;
}
#ifndef __KEY_H
#define __KEY_H
#include "stm32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "sys.h" //启用bool定义
/宏定义/
#define Cursor_Left 1
#define Cursor_Right 2
#define Cursor_Up 3
#define Cursor_Down 4
#define OK 5
#define KEY3 PBin(14) //PB14,向上
#define KEY4 PBin(13) //PB13,向下
#define KEY1 PBin(15) //PB15,向左
#define KEY2 PDin(8) //PD8,向右
#define KEY5 PBin(12) //PB12,确认
extern void KEY_Init(void);
extern u8 KEY_Scan(u8 mode);
#endif