[LOOK] LOOK+红杏头文件 学习第二帖:2个KEY控制4个LED闪烁

[复制链接]
 楼主| Swallow_0322 发表于 2011-5-29 21:59 | 显示全部楼层 |阅读模式
本帖最后由 hotpower 于 2011-6-19 01:24 编辑

       因为工作比较忙,最近对LOOK及M0的关注比较少,今天稍有清闲,在第一帖的基础上再增加一个中断类任务,即助学板上KEY1配置为下降沿中断,在中断服务函数内完成数码管显示模式的调整。完全参照HOT大叔例程,通过Lee老师的LOOK手册进行学习,完全照猫画虎,暂时只能这样爬行了,接触多了自然知道自己该补什么了,望高手不要见笑!
       任务描述:①  助学板上四个LED小灯轮流点亮,有两种显示模式,方式1为LED1--->LED2--->LED3--->LED4--->LED1循环,方式2为LED4--->LED3--->LED2--->LED1--->LED4循环,初始化为方式1;
      ②  助学板上KEY2通过查询的方式判断按下调整LED的循环方式;
      ③  助学板上KEY1设置为下降沿中断,中断服务函数内调整LED的循环方式。


源程序如下:
LED.h
  1. #include "look_config.h"
  2. #include <look.h>
  3. #include <instantiate>

  4. // 任务类 task_led_t 的定义
  5. class task_led_t : public task_t {
  6. public:
  7. task_led_t() __OPT_ATTR__; // 构造函数

  8. protected:
  9. void routine(); // 任务例程

  10. };

  11. // 任务类 task_led_t 的构造函数
  12. __OPT_INLINE__ task_led_t::task_led_t()
  13. {
  14. // TODO: 在此初始化 task_led_t 的类成员
  15. }

  16. // 任务类 task_key_t 的定义
  17. class task_key_t : public task_t {
  18. public:
  19. task_key_t() __OPT_ATTR__; // 构造函数
  20. int8_t key_read() __OPT_ATTR__;

  21. protected:
  22. void routine(); // 任务例程

  23. };


  24. // 任务类 task_key_t 的构造函数
  25. __OPT_INLINE__ task_key_t::task_key_t()
  26. {
  27. // TODO: 在此初始化 task_led_t 的类成员
  28. }


  29. extern instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led;
  30. extern instantiate::task<task_key_t, LOOK_STACK_SIZE> task_key;


LED.CPP
  1. #include "NUC1xx.h"
  2. #include "NUC1xxM051Seriescfg.h"
  3. #include "led.h"
  4. /*
  5. LOOK实现三个小任务: ① 助学板上四个LED小灯轮流点亮,有两种显示模式,方式1为
  6. LED1--->LED2--->LED3--->LED4--->LED1循环,方式2为LED4
  7. --->LED3--->LED2--->LED1--->LED4循环,初始化为方式1;
  8. ② 助学板上KEY2通过查询的方式判断按下调整LED的循环方式;
  9. ③ 助学板上KEY1设置为下降沿中断,中断服务函数内调整LED的循环方式。
  10. */

  11. uint8_t **_FlashMode = TRUE;

  12. class Key_t : public interrupt_t { //创建继承于interrupt_t的中断抽象类
  13. public:
  14. Key_t() __OPT_ATTR__; //构造函数

  15. protected:
  16. bool isr(int vector); //中断服务例程
  17. void dsr(int vector, uintptr_t count); //中断滞后服务例程
  18. };

  19. // Key_t 构造函数
  20. inline Key_t::Key_t()
  21. {
  22. attach(EINT1_IRQn); //连接外部中断1
  23. GPIOBs.IEN.Bits.Bit15 = 1; //GB15 使能下降沿或低电平中断
  24. GPIOBs.IMD.Bits.Pin15 = 0; //GB15 中断模式为边沿触发中断
  25. vector_t::enable(EINT1_IRQn); //使能外部中断1
  26. }

  27. // Key_t 中断服务例程
  28. bool Key_t::isr(int vector)
  29. {
  30. GPIOBs.ISRC.Regs = GPIOBs.ISRC.Regs; // 清中断 flag
  31. return true; //返回true 表示需要调度器调度本对象的 dsr() 例程,进行后续处理。
  32. }

  33. // Key1_t 中断滞后服务例程
  34. void Key_t::dsr(int vector, uintptr_t count)
  35. {
  36. if (vector == EINT1_IRQn)
  37. {
  38. **_FlashMode = !**_FlashMode;
  39. }
  40. }

  41. Key_t Key; // 创建Key对象


  42. // 任务类 task_led_t 的例程
  43. void task_led_t::routine()
  44. {
  45. // TODO: 在此编写 task_led_t 例程的内容
  46. GPIOAs.DMASK.Regs = ~0b111100;
  47. GPIOAs.DOUT.Regs = ~0b100;
  48. while (true) {
  49. // TODO: 在此编写 task_led_t 例程的内容
  50. uint32_t data = GPIOAs.DOUT.Regs & 0b111100;
  51. if (**_FlashMode)
  52. {
  53. data <<= 1;
  54. data += data >> 4;

  55. }
  56. else
  57. {
  58. data >>= 1;
  59. data += data << 4;
  60. }
  61. GPIOAs.DOUT.Regs = data;
  62. delay(LOOK_TICKS_PER_SEC);
  63. }
  64. }

  65. // 任务类 task_key_t 的例程
  66. void task_key_t::routine()
  67. {
  68. // TODO: 在此编写 task_led_t 例程的内容

  69. while (true) {
  70. // TODO: 在此编写 task_led_t 例程的内容
  71. if (key_read())
  72. **_FlashMode = !**_FlashMode;
  73. delay(LOOK_TICKS_PER_SEC/10);
  74. }
  75. }

  76. // 任务类 task_key_t 的成员函数
  77. __OPT_INLINE__ int8_t task_key_t::key_read()
  78. {
  79. uint32_t Key_Tmp = TRUE;
  80. static uint32_t Key_Record = TRUE; //按键记录

  81. Key_Tmp = GPIOBs.PIN.Bits.Pin14;
  82. if(Key_Tmp==TRUE) //无有效按键按下
  83. {
  84. Key_Record = TRUE; //清除按键记录
  85. return FALSE; //程序退出
  86. }
  87. if(Key_Record!=Key_Tmp) //为新按键
  88. {
  89. Key_Record=Key_Tmp; //保存本次结果
  90. delay(LOOK_TICKS_PER_SEC/100); //延时去抖动
  91. Key_Tmp = GPIOBs.PIN.Bits.Pin14;
  92. if(Key_Tmp==Key_Record)
  93. return TRUE;
  94. }
  95. return FALSE;
  96. }


  97. #ifdef LOOK_SCHEDULING_PRIORITY
  98. instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led(0);
  99. #else
  100. instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led;
  101. #endif

  102. #ifdef LOOK_SCHEDULING_PRIORITY
  103. instantiate::task<task_key_t, LOOK_STACK_SIZE> task_key(0);
  104. #else
  105. instantiate::task<task_key_t, LOOK_STACK_SIZE> task_key;
  106. #endif


     工程结构
     

     因为不同的安装路径下工程可能无法编译就不上传工程文件了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
dong_abc 发表于 2011-5-29 22:03 | 显示全部楼层
我也掉队了,出差中,没带电脑,天天逛书店
hotpower 发表于 2011-5-29 22:39 | 显示全部楼层
鼓励,但是有些问题。
因为OS里中断与任务的同步,应该用同步对象,而不应该用标志的轮询。
weshiluwei6 发表于 2011-5-29 23:01 | 显示全部楼层
大叔说:应该用 OS的思想编写OS的程序
 楼主| Swallow_0322 发表于 2011-5-30 07:50 | 显示全部楼层
3# hotpower

呵呵! 多谢大叔鼓励!衣服应该一件一件加,否则热得受不了,(*^__^*) 嘻嘻!
LOOK才刚刚起步,俺要一步一步从裸奔过渡!
hotpower 发表于 2011-5-30 08:07 | 显示全部楼层
三心爱意要看看《嵌入式系统的实时概念》这本书。
859419016 发表于 2011-5-31 00:34 | 显示全部楼层
啥也没说~~~~~
hotpower 发表于 2011-5-31 11:08 | 显示全部楼层
今晚的群课就用这个例程说rtos中中断与任务及任务和任务之间的同步即通讯。
hotpower 发表于 2011-5-31 11:13 | 显示全部楼层
可以用裸奔的思维学rtos,但绝不应该用裸奔的手法编写rtos程序
 楼主| Swallow_0322 发表于 2011-5-31 11:20 | 显示全部楼层
:victory:坚决服从大叔教导!
abin0415 发表于 2011-6-2 21:18 | 显示全部楼层
学习
JACK_1986 发表于 2011-6-24 15:49 | 显示全部楼层
学习
yifeidengdai 发表于 2012-12-25 15:08 | 显示全部楼层
学习
dake1478 发表于 2014-3-20 14:29 | 显示全部楼层
顶个
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:播种一种行为,收获一种习惯;播种一种习惯,收获一种性格;播种一种性格,收获一种人生!

121

主题

1393

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部