• uCOSii中的事件标志组


    事件标志管理 (EVENT FLAGS MANAGEMENT)

    OSFlagAccept() 无等待查询事件标志组的事件标志位是否建立

    OSFlagPend() 需要等待事件标志组的事件标志位建立

    OSFlagCreate() 建立一个事件标志组

    OSFlagDel() 删除一个事件标志组

    OSFlagPost() 置位或清0事件标志组中的标志位

    OSFlagQuery() 查询事件标志组的当前事件标志状态

    如果有条件,还是事先去看uCOSii中的事件标志管理函数,很多人没有写函数功能,很难理解。

    //函数功能:无需等待,接收事件标志组的事件标志位

    wait_typebit7=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_typebit71, 要求清除事件标志位

        wait_type &= ~OS_FLAG_CONSUME;//wait_typebit70

            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_typebit7=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_typebit7=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_typebit7=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_typebit7=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_typebit7=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_typebit71, 要求清除事件标志位

            wait_type &= (INT8U)~(INT8U)OS_FLAG_CONSUME;

            consume    = OS_TRUE;

    }

    else

    {//发现wait_typebit70, 不要求清除事件标志位

            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_typebit7=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_typebit7=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_typebit7=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_typebit7=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_typebit7=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_SETopt=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);

    }

    1. #include "My_Task_Priority.h"
    2. __align(8) OS_STK START_TASK_STACK[START_TASK_STACK_SIZE]; //START_TASK任务堆栈
    3. __align(8) OS_STK LED0_TASK_STACK[LED0_TASK_STACK_SIZE]; //LED0_TASK任务堆栈
    4. __align(8) OS_STK LED1_TASK_STACK[LED1_TASK_STACK_SIZE]; //LED1_TASK任务堆栈
    5. __align(8) OS_STK KEY_TASK_STACK[KEY_TASK_STACK_SIZE]; //KEY_TASK任务堆栈
    6. //如果任务中使用printf来打印浮点数据的话一点要8字节对齐
    7. OS_FLAG_GRP *EventFlags; //事件标志组指针,Event Flag Group
    1. //My_Task_Priority.h
    2. #ifndef __MY_TASK_PRIORITY_H
    3. #define __MY_TASK_PRIORITY_H
    4. #include "includes.h"
    5. //当OS_LOWEST_PRIO=63时,μC/OS-II有64个优先级,优先级的高低按编号从0(最高)到63(最低)排序;
    6. //OS_TASK_IDLE_PRIO为63,是空闲任务优先级,OS_TASK_IDLE_ID为65535
    7. //OS_TASK_STAT_PRIO为62,是统计任务优先级,OS_TASK_STAT_ID为65534
    8. //uCOSii至少有两个任务,分别是"空闲任务""统计任务"
    9. /*
    10. 为了保证“启动任务”能够连续运行,必须将“启动任务”的优先级选择为最高。
    11. 否则,当“启动任务”创建一个优先级高于自己的任务时,刚刚创建的任务就
    12. 会立即进入运行状态,而与这个任务关联的其它任务可能还没有创建,它使
    13. 用的通信工具也还没有创建,系统必然出错。
    14. */
    15. #define START_TASK_PRIORITY 4 //设置START_TASK任务优先级,开始任务的优先级设置为最高
    16. #define START_TASK_STACK_SIZE 192 //设置START_TASK任务堆栈大小,为8的倍数
    17. extern OS_STK START_TASK_STACK[START_TASK_STACK_SIZE]; //START_TASK任务堆栈
    18. #define LED0_TASK_PRIORITY 5 //设置LED0_TASK任务优先级为5
    19. #define LED0_TASK_STACK_SIZE 56 //设置LED0_TASK任务堆栈大小为56,为8的倍数
    20. extern OS_STK LED0_TASK_STACK[LED0_TASK_STACK_SIZE]; //LED0_TASK任务堆栈
    21. #define LED1_TASK_PRIORITY 6 //设置LED1_TASK任务优先级为6
    22. #define LED1_TASK_STACK_SIZE 72 //设置LED1_TASK任务堆栈大小为72,为8的倍数
    23. extern OS_STK LED1_TASK_STACK[LED1_TASK_STACK_SIZE]; //LED1_TASK任务堆栈
    24. #define KEY_TASK_PRIORITY 7 //设置KEY_TASK任务优先级为7
    25. #define KEY_TASK_STACK_SIZE 56 //设置KEY_TASK任务堆栈大小为56,为8的倍数
    26. extern OS_STK KEY_TASK_STACK[KEY_TASK_STACK_SIZE]; //KEY_TASK任务堆栈
    27. extern OS_FLAG_GRP *EventFlags; //事件标志组指针,Event Flag Group
    28. /OS_FLAGS数据的位数///
    29. //在os_cfg.h中定义OS_FLAGS_NBITS=16,表示"OS_FLAGS数据的位数为16"
    30. #define KEY0_FLAG 0x0001 //KEY0位于bit0
    31. #define KEY1_FLAG 0x0002 //KEY1位于bit1
    32. #define KEY2_FLAG 0x0004 //KEY2位于bit2
    33. #define KEY3_FLAG 0x0008 //KEY3位于bit3
    34. #define KEY4_FLAG 0x0010 //KEY4位于bit4
    35. #define KEY5_FLAG 0x0020 //KEY5位于bit5
    36. #define KEY6_FLAG 0x0040 //KEY6位于bit6
    37. #define KEY7_FLAG 0x0080 //KEY7位于bit7
    38. #define KEY8_FLAG 0x0001 //KEY8位于bit8
    39. #define KEY9_FLAG 0x0002 //KEY9位于bit9
    40. #define KEY10_FLAG 0x0004 //KEY10位于bit10
    41. #define KEY11_FLAG 0x0008 //KEY11位于bit11
    42. #define KEY12_FLAG 0x0010 //KEY12位于bit12
    43. #define KEY13_FLAG 0x0020 //KEY13位于bit13
    44. #define KEY14_FLAG 0x0040 //KEY14位于bit14
    45. #define KEY15_FLAG 0x0080 //KEY15位于bit15
    46. #endif
    1. #include "Start_Task.h"
    2. #include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
    3. #include "LED.h"
    4. #include "key.h"
    5. #include "My_Task_Priority.h"
    6. #include "LED0_Task.h"
    7. #include "LED1_Task.h"
    8. #include "Key_Task.h"
    9. void Start_Task(void *pdata);
    10. const char Start_Task_rn_REG[]="\r\n";
    11. const char Start_Task_Initialise_REG[]="Start_Task Initialise";
    12. //Start_Task任务
    13. void Start_Task(void *pdata)
    14. {
    15. OS_CPU_SR cpu_sr=0;
    16. u8 err;
    17. pdata = pdata;
    18. printf("%s",Start_Task_rn_REG);
    19. printf("%s",Start_Task_Initialise_REG);
    20. LED0_Init();
    21. LED1_Init();
    22. KEY_Init();
    23. OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断),需要定义cpu_sr变量
    24. EventFlags=OSFlagCreate(0,&err);
    25. //建立一个事件标志组
    26. OSTaskCreate( LED0_Task,/* 函数指针*/
    27. (void *)0,/* 建立任务时,传递的参数*/
    28. (OS_STK*)&LED0_TASK_STACK[LED0_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
    29. LED0_TASK_PRIORITY/* 任务优先级*/
    30. );
    31. OSTaskCreate( LED1_Task,/* 函数指针*/
    32. (void *)0,/* 建立任务时,传递的参数*/
    33. (OS_STK*)&LED1_TASK_STACK[LED1_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
    34. LED1_TASK_PRIORITY/* 任务优先级*/
    35. );
    36. OSTaskCreate( Key_Task,/* 函数指针*/
    37. (void *)0,/* 建立任务时,传递的参数*/
    38. (OS_STK*)&KEY_TASK_STACK[KEY_TASK_STACK_SIZE-1],/* 指向堆栈任务栈顶的指针*/
    39. KEY_TASK_PRIORITY/* 任务优先级*/
    40. );
    41. //OSTaskSuspend(START_TASK_PRIO); //挂起起始任务Start_Task(),但不删除
    42. OSTaskDel(OS_PRIO_SELF); //删除自己
    43. OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)
    44. }
    1. #include "LED0_Task.h"
    2. #include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
    3. #include "LED.h"
    4. #include "My_Task_Priority.h"
    5. void LED0_Task(void *pdata);
    6. const char LED0_Task_rn_REG[]="\r\n";
    7. const char LED0_Task_Initialise_REG[]="LED0_Task Initialise";
    8. //LED0_Task任务
    9. void LED0_Task(void *pdata)
    10. {
    11. u8 err;
    12. OS_FLAGS retFlag,inputFlag;
    13. printf("%s",LED0_Task_rn_REG);
    14. printf("%s",LED0_Task_Initialise_REG);
    15. while(1)
    16. {
    17. inputFlag=(OS_FLAGS)(KEY0_FLAG|KEY2_FLAG);
    18. // retFlag=OSFlagPend(
    19. // EventFlags,//事件标志组指针&err
    20. // inputFlag,//接收"事件标志组的第0位和第2位"
    21. // OS_FLAG_WAIT_SET_AND,//"事件标志组的第0位和第2位"同时置为1时为有效,否则将任务挂在这里
    22. // 0,//无限等待,直到收到为止
    23. // &err );
    24. // printf("LED0事件标志组EventFlags的值:%d\r\n",retFlag);
    25. // LED0=!LED0;
    26. // OSFlagPost(
    27. // EventFlags,//事件标志组指针
    28. // (OS_FLAGS)KEY0_FLAG,//给事件标志组的第0位发信号
    29. // OS_FLAG_CLR,//将事件标志组的第0位置0
    30. // &err
    31. // );
    32. // if( err==OS_ERR_NONE && (retFlag&KEY0_FLAG)==KEY0_FLAG)//事件标志发送正确
    33. // {
    34. // }
    35. retFlag=OSFlagAccept(
    36. EventFlags,//事件标志组指针&err
    37. inputFlag,//接收"事件标志组的第0位和第2位"
    38. OS_FLAG_WAIT_SET_AND,//"事件标志组的第0位和第2位"同时置为1时为有效,否则将任务挂在这里
    39. &err );
    40. if( err==OS_ERR_NONE && (inputFlag&retFlag)==inputFlag)//接收正确
    41. {
    42. printf("LED0事件标志组EventFlags的值:%d\r\n",retFlag);
    43. LED0=!LED0;
    44. inputFlag=KEY0_FLAG;
    45. retFlag=OSFlagPost(
    46. EventFlags,//事件标志组指针
    47. inputFlag,//给事件标志组的第0位发信号
    48. OS_FLAG_CLR,//将事件标志组的第0位置0
    49. &err
    50. );
    51. if( err==OS_ERR_NONE && (retFlag&inputFlag)==inputFlag)//事件标志发送正确
    52. {
    53. }
    54. }
    55. OSTimeDlyHMSM(0,0,0,500);//延时500ms
    56. }
    57. }
    1. #include "LED1_Task.h"
    2. #include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
    3. #include "LED.h"
    4. #include "My_Task_Priority.h"
    5. void LED1_Task(void *pdata);
    6. const char LED1_Task_rn_REG[]="\r\n";
    7. const char LED1_Task_Initialise_REG[]="LED1_Task Initialise";
    8. //LED1_Task任务
    9. void LED1_Task(void *pdata)
    10. {
    11. u8 err;
    12. OS_FLAGS retFlag,inputFlag;
    13. printf("%s",LED1_Task_rn_REG);
    14. printf("%s",LED1_Task_Initialise_REG);
    15. while(1)
    16. {
    17. inputFlag=KEY2_FLAG;
    18. //若等待事件标志没有发生 该函数挂起该任务
    19. retFlag=OSFlagPend(
    20. EventFlags,//事件标志组指针
    21. inputFlag,//接收"事件标志组的第2位"
    22. OS_FLAG_WAIT_SET_ALL,//"事件标志组的第2位"置为1时为有效,否则将任务挂在这里
    23. 0,//无限等待,直到收到为止
    24. &err );
    25. printf("LED1事件标志组EventFlags的值:%d\r\n",retFlag);
    26. LED1=!LED1;
    27. retFlag=OSFlagPost(
    28. EventFlags,//事件标志组指针
    29. inputFlag,//给事件标志组的第2位发信号
    30. OS_FLAG_CLR,//将事件标志组的第2位置0
    31. &err
    32. );
    33. if( err==OS_ERR_NONE && (retFlag&inputFlag)==inputFlag)//事件标志发送正确
    34. {
    35. }
    36. OSTimeDlyHMSM(0,0,0,200);//延时200毫秒
    37. }
    38. }
    1. #include "Key_Task.h"
    2. #include "delay.h"
    3. #include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
    4. #include "key.h"
    5. #include "My_Task_Priority.h"
    6. #include "LED1_Task.h"
    7. const char Key_Task_rn_REG[]="\r\n";
    8. const char Key_Task_Initialise_REG[]="Key_Task Initialise";
    9. void Key_Task(void *pdata);
    10. //Key_Task任务
    11. void Key_Task(void *pdata)
    12. {
    13. u8 key,err;
    14. OS_FLAGS retFlag,inputFlag;
    15. printf("%s",Key_Task_rn_REG);
    16. printf("%s",Key_Task_Initialise_REG);
    17. while(1)
    18. {
    19. key=KEY_Scan(0);
    20. if(key==Cursor_Up)
    21. {
    22. inputFlag=KEY0_FLAG;
    23. retFlag=OSFlagPost(
    24. EventFlags,//事件标志组指针
    25. (OS_FLAGS)inputFlag,//给事件标志组的第0位发信号
    26. OS_FLAG_SET,//将事件标志组的第0位置1
    27. &err );
    28. if( err==OS_ERR_NONE && (inputFlag&retFlag)==inputFlag)//事件标志发送正确
    29. printf("\r\nKey事件标志组EventFlags的值:%d\r\n",retFlag);
    30. }
    31. else if (key==Cursor_Down)
    32. {
    33. inputFlag=KEY2_FLAG;
    34. retFlag=OSFlagPost(
    35. EventFlags,//事件标志组指针
    36. inputFlag,//给事件标志组的第2位发信号
    37. OS_FLAG_SET,//将事件标志组的第2位置1
    38. &err );
    39. if( err==OS_ERR_NONE && (retFlag&inputFlag)==inputFlag )//事件标志发送正确
    40. printf("\r\nKey事件标志组EventFlags的值:%d\r\n",retFlag);
    41. }
    42. else if (key==Cursor_Left)
    43. {
    44. inputFlag=(OS_FLAGS)(KEY0_FLAG|KEY2_FLAG);
    45. retFlag=OSFlagPost(
    46. EventFlags,//事件标志组指针
    47. inputFlag,//给事件标志组的第0位和第2位发信号
    48. OS_FLAG_SET,//将事件标志组的第0位和第2位置1
    49. &err );
    50. if( err==OS_ERR_NONE && (inputFlag&retFlag)==inputFlag)//事件标志发送正确
    51. printf("\r\nKey事件标志组EventFlags的值:%d\r\n",retFlag);
    52. }
    53. OSTimeDlyHMSM(0,0,0,500);//延时500ms
    54. }
    55. }
    1. #include "LED.h"
    2. void LED0_Init(void)
    3. {
    4. GPIO_InitTypeDef GPIO_InitStructure;
    5. //使用GPIO_InitTypeDef定义一个结构变量GPIO_InitStructure;
    6. RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOE, ENABLE ); //在配置外设之前,必须先使能GPIOE的外设时钟
    7. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4; //选择第4
    8. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置引脚的最高输出速率为50MHz
    9. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //设置引脚工作模式为推挽输出方式
    10. GPIO_Init( GPIOE, &GPIO_InitStructure); //根据GPIO_InitStructure结构变量指定的参数初始化GPIOE的外设寄存器
    11. }
    12. void LED1_Init(void)
    13. {
    14. GPIO_InitTypeDef GPIO_InitStructure;
    15. //使用GPIO_InitTypeDef定义一个结构变量GPIO_InitStructure;
    16. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); //使能GPIOE的外设时钟
    17. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //选择第5
    18. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚工作模式为推挽输出方式
    19. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚的最高输出速率为50MHz
    20. GPIO_Init(GPIOE, &GPIO_InitStructure);
    21. //根据GPIO_InitStructure结构变量指定的参数初始化GPIOE的外设寄存器
    22. }
    23. void LED_Init(void)
    24. {
    25. LED0_Init();
    26. LED1_Init();
    27. }
    1. #include "KEY.h"
    2. #include "delay.h"
    3. void KEY_Init(void);
    4. u8 KEY_Scan(u8 mode);
    5. //函数功能:将PB12,PB13,PB14,PB15,PD8初始化为输入口
    6. void KEY_Init(void)
    7. {
    8. GPIO_InitTypeDef GPIO_InitStructure;
    9. //使用GPIO_InitTypeDef定义一个结构变量GPIO_InitStructure;
    10. RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOB, ENABLE ); //在配置外设之前,必须先使能GPIOB的外设时钟
    11. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; //选择第12,13,1415
    12. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置引脚的最高输出速率为50MHz
    13. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //输入上拉,按钮输入低电平有效
    14. GPIO_Init( GPIOB, &GPIO_InitStructure);
    15. //根据GPIO_InitStructure结构变量指定的参数初始化GPIOB的外设寄存器
    16. RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOD, ENABLE ); //在配置外设之前,必须先使能GPIOD的外设时钟
    17. GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8; //选择第8
    18. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //设置引脚的最高输出速率为50MHz
    19. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //输入上拉,按钮输入低电平有效
    20. GPIO_Init( GPIOD, &GPIO_InitStructure);
    21. //根据GPIO_InitStructure结构变量指定的参数初始化GPIOD的外设寄存器
    22. }
    23. //函数功能:按键扫描,按键检测时间为50ms
    24. u8 KEY_Scan(u8 mode)
    25. {
    26. u8 i;
    27. u8 ch0;
    28. u8 ch1;
    29. u8 retData;
    30. static u8 key_backup=1;//记录按键被释放
    31. if(mode == 1) key_backup=1;//记录按键被释放
    32. retData=0;//假定无按键按下
    33. ch0=0;ch1=0;
    34. if(key_backup==1)
    35. {
    36. if( KEY2==0) ch0=Cursor_Right; //记录按键值
    37. if( KEY3==0) ch0=Cursor_Up; //记录按键值
    38. if( KEY1==0) ch0=Cursor_Left; //记录按键值
    39. if( KEY4==0) ch0=Cursor_Down; //记录按键值
    40. if( KEY5==0) ch0=OK; //记录按键值
    41. }
    42. if(ch0) i=0;
    43. else i=200;
    44. for(;i<20;)
    45. {
    46. i++;
    47. ch1=0;
    48. delay_ms(5);
    49. if(KEY2==0) ch1=Cursor_Right; //记录按键值,向右
    50. if(KEY3==0) ch1=Cursor_Up; //记录按键值,向上
    51. if(KEY1==0) ch1=Cursor_Left; //记录按键值,向左
    52. if(KEY4==0) ch1=Cursor_Down; //记录按键值,向下
    53. if(KEY5==0) ch1=OK; //记录按键值,确认
    54. if(ch1!=ch0) i=100;
    55. }
    56. if(i==20) retData=ch0;
    57. else retData=0;
    58. ch1=0;
    59. if(KEY1==1) ch1=1;
    60. if(KEY2==1) ch1=(u8)(ch1<<1);
    61. if(KEY3==1) ch1=(u8)(ch1<<1);
    62. if(KEY4==1) ch1=(u8)(ch1<<1);
    63. if(KEY5==1) ch1=(u8)(ch1<<1);
    64. if(ch1==0x20) key_backup=1;//记录按键被释放
    65. return retData;
    66. }
    1. #ifndef __KEY_H
    2. #define __KEY_H
    3. #include "stm32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
    4. #include "sys.h" //启用bool定义
    5. /宏定义/
    6. #define Cursor_Left 1
    7. #define Cursor_Right 2
    8. #define Cursor_Up 3
    9. #define Cursor_Down 4
    10. #define OK 5
    11. #define KEY3 PBin(14) //PB14,向上
    12. #define KEY4 PBin(13) //PB13,向下
    13. #define KEY1 PBin(15) //PB15,向左
    14. #define KEY2 PDin(8) //PD8,向右
    15. #define KEY5 PBin(12) //PB12,确认
    16. extern void KEY_Init(void);
    17. extern u8 KEY_Scan(u8 mode);
    18. #endif

  • 相关阅读:
    硬件设计——关于Type-C 口的讲解和设计
    每日一题9.17打家劫舍2
    设计模式系列详解 -- 建造者模式
    C/C++学习 -- HMAC算法
    Gson解析会丢失默认属性值
    Linux下网络编程
    封闭岛屿数量 -- 二维矩阵的dfs算法
    【算法题】1488. 避免洪水泛滥
    什么是电源高压测试标准?如何测试?测试时要注意什么?
    华为云如何实现实时音视频全球低时延网络架构
  • 原文地址:https://blog.csdn.net/weixin_42550185/article/details/130905948