OpenEdv-开源电子网

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

按键中断实现置位事件标志位

[复制链接]

46

主题

199

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1118
金钱
1118
注册时间
2016-3-25
在线时间
363 小时
发表于 2018-3-18 17:01:37 | 显示全部楼层 |阅读模式
本帖最后由 Mr.liu 于 2018-3-18 17:05 编辑

今天在折腾FreeRTOS中实现中断程序里实现置位事件组中的某一位或多位事件标志位。

实验背景:在跑FreeRTOS的板子中,很多都是通过轮询方式获取按键的状态。总觉得这样效率太低,很浪费资源(可能自己有些强迫症吧)。

               所以想通过事件组的方式来获取按键信息。平时这个任务一直等待按键按下而进入阻塞状态。直到按键中断中把相应的事件标志位置1,任务才就绪,从而进行相应的逻辑处理,处理完又等待按键事件,周而复始。


实现方法:

  1.移植好FreeRTOS(最简单的时拿正点原子提供的例程)

  2.配置相应的GPIO为中断输入,映射到相应的Line上,分好组。(具体看正点原子的例程或者视频教程)

3.写按键中断程序。(下面是最终写好的程序)
   
     void EXTI0_IRQHandler(void)
  {
    //delay_ms(10);//防抖
      BaseType_t xHigherPriorityTaskWoken=pdTRUE;   //pdFAIL
    //ÔÚÕâÀïÌí¼ÓÐźÅÁ¿
    xEventGroupSetBitsFromISR(EventGroupHandler, EVENTBIT_1 ,&xHigherPriorityTaskWoken);
     portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    printf("key1 is pressed\r\n");
    EXTI_ClearITPendingBit(EXTI_Line0); //清除中断标志
  }

这里需要注意几个问题。
   
  a.这里的延时(防抖)有严格的要求。经测试,延时在MS级,系统就会异常(OS是的嘀嗒时间好像就是1MS,可能与这个有关)。在MS以下不会,我是通过串口查看打印信息发现。但是不延时,每次都会产生两次中断。但是通过测试 ,中断中有操作时,可以不用防抖,操作的时间相当于延时了(谬论哈,我是这样理解的。)

b.关于xEventGroupSetBitsFromISR函数的最后一个参数。配置成pdFAIL,portYIELD_FROM_ISR(xHigherPriorityTaskWoken);也不调用。系统也会异常,同样是通过串口可以看到提示信息。这个参数配置成pdTRUE,而后面调用 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);,这样系统就运行正常了。这里可能是我的任务优先级不是最高吧,不知道设置成最高会是怎样,没试过。

c.关于中断的响应优先级必须比系统最高优先级小,不然也会从串口中看到系统异常。默认操作系统的范围是:
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY            15                      //中断最低优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5                       //系统可管理的最高中断优先级

只要中断 优先级在系统可管理的中断优先级范围内(5——15)即可。我这里设置的是6,
    //中断配置
    NVIC_InitTypeDef NVIC_InitStructure;                            //¶¨Òå½á¹¹Ìå
    NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn;                  //ʹÄÜÍⲿÖжÏËùÔÚͨµÀ
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x06;    //ÇÀÕ¼ÓÅÏȼ¶ÉèÖÃ
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;           //ÏìÓ¦ÓÅÏȼ¶
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //ʹÄÜÍⲿÖжÏͨµÀ
    NVIC_Init(&NVIC_InitStructure);                                 //¸ù¾Ý½á¹¹ÌåÐÅÏ¢½øÐÐÓÅÏȼ¶³õʼ»¯
   
    NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn;                  //ʹÄÜÍⲿÖжÏËùÔÚͨµÀ
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x06;    //ÇÀÕ¼ÓÅÏȼ¶ÉèÖÃ
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;           //ÏìÓ¦ÓÅÏȼ¶
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //ʹÄÜÍⲿÖжÏͨµÀ
    NVIC_Init(&NVIC_InitStructure);                                 //¸ù¾Ý½á¹¹ÌåÐÅÏ¢½øÐÐÓÅÏȼ¶³õʼ»¯

  
      遇到好多问题,绕了很多弯,这也是自己没有熟悉操作系统,是直接拿来用。表达能力有限,勿喷。


   参与 :http://www.mamicode.com/info-detail-1907369.html     (FreeRTOS 事件标志组)这里描述更清楚


备注:这样很多事件都可以通过这种方式来提高效率,比如用W5500,就可以用它的nRST来触发事件,通知任务有数据来了,需要进行处理,效率会比轮询方式更高。但也要把数据处理任务的优先级设置的合理,能使任务马上可以进入就绪。



代写STM32各类驱动,DEMO程序
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-1-31 21:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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