[LOOK] LOOK+红杏头文件 学习第五帖:信号灯+AD转换(查询法)

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

-----------------------2011-06-12 AM-----------------------
在原基础上作如下调整:
① 取消中断抽象类任务Key_t,该任务实现的功能整合至一般任务类task_key_t中的key_read中;
② 增加中断抽象类任务uart0_t,该任务主要实现UART输出和接收功能,接收到字符'1'为同步蜂鸣器响3次任务,接收到字符'2'实现与KEY2按下相同功能;
③ task_beep_t中增加蜂鸣器响之前发送字符串"Buzzer rang three times!\n"。
初始化设置: PB.0选择多功能输入RXD0 PB.1选择多功能输入TXD0
            UART时钟选择外部12MHZ,并使能UART0时钟
-----------------------2011-06-12 PM-----------------------
在原基础上做如下调整:
①  增加任务类task_ad_t,完成对AD1的单次AD转换并通过串口发送转换结果;
②  使用信号灯作为在UART0接收字符'3'时AD转换任务的同步。


初始化设置:ADC时钟选择外部12MHz,分频为3 并使能ADC时钟
                PA.1配置为AD引脚功能


源程序:
led.h

  1. #include "look_config.h"
  2. #include <look.h>
  3. #include <instantiate>
  4. #define KEY_NO_DOWN    ((1<<14)|(1<<15))  //无按键按下时管脚PIN值
  5. // 任务类 task_led_t 的定义
  6. class task_led_t : public task_t {
  7. public:
  8. task_led_t() __OPT_ATTR__; // 构造函数
  9. protected:
  10. void routine(); // 任务例程
  11. };
  12. // 任务类 task_led_t 的构造函数
  13. __OPT_INLINE__ task_led_t::task_led_t()
  14. {
  15. // TODO: 在此初始化 task_led_t 的类成员
  16. }

  17. // 任务类 task_key_t 的定义
  18. class task_key_t : public task_t {
  19. public:
  20. task_key_t() __OPT_ATTR__; // 构造函数
  21. int32_t key_read() __OPT_ATTR__;
  22. protected:
  23. void routine(); // 任务例程
  24. };
  25. // 任务类 task_key_t 的构造函数
  26. __OPT_INLINE__ task_key_t::task_key_t()
  27. {
  28. // TODO: 在此初始化 task_key_t 的类成员
  29. }

  30. // 任务类 task_beep_t 的定义
  31. class task_beep_t : public task_t {
  32. public:
  33. task_beep_t() __OPT_ATTR__; // 构造函数
  34. protected:
  35. void routine(); // 任务例程
  36. };
  37. // 任务类 task_beep_t 的构造函数
  38. __OPT_INLINE__ task_beep_t::task_beep_t()
  39. {
  40. // TODO: 在此初始化 task_beep_t 的类成员
  41. }

  42. // 任务类 task_ad_t 的定义
  43. class task_ad_t : public task_t {
  44. public:
  45. task_ad_t() __OPT_ATTR__;  // 构造函数
  46. sem_t sem;      // 信号灯为AD转换提供同步
  47. protected:
  48. void routine();     // 任务例程
  49. };
  50. // 任务类 task_beep_t 的构造函数
  51. __OPT_INLINE__ task_ad_t::task_ad_t():sem(0)
  52. {
  53. // TODO: 在此初始化 task_ad_t 的类成员
  54. }
  55. extern instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led;
  56. extern instantiate::task<task_key_t, LOOK_STACK_SIZE> task_key;
  57. extern instantiate::task<task_beep_t, LOOK_STACK_SIZE> task_beep;
  58. extern instantiate::task<task_ad_t, LOOK_STACK_SIZE> task_ad;

  59. led.cpp
  60. [code]
  61. #include "NUC1xx.h"
  62. #include "NUC1xxM051Seriescfg.h"
  63. #include "led.h"

  64. flag_t Flag(0); //位0为LED闪烁模式 位1为KEY1控制蜂鸣器任务同步标志 位2为UART通信控制蜂鸣器任务同步标志

  65. // uart0_t 类为应用层提供了简单的 uart 同步输出功能及接收功能。
  66. class uart0_t : public interrupt_t {
  67. public:
  68. uart0_t() __OPT_ATTR__; //构造函数
  69. void puts(const char* str); //串口输出函数
  70. protected:
  71. bool isr(int vector); //中断服务例程
  72. void dsr(int vector, uintptr_t count); //中断滞后服务例程
  73. private:
  74. void fillfifo(const char* str); //填充FIFO
  75. private:
  76. const char* buffer; // 输出缓冲区
  77. task_t* task; // 正在输出的任务
  78. };

  79. // uart0 构造函数
  80. __OPT_INLINE__ uart0_t::uart0_t()
  81. {
  82. attach(UART0_IRQn);
  83. vector_t::enable(UART0_IRQn);
  84. SYSs.IPRSTC2.Bits.UART0_RST = 1; //UART0 模块复位
  85. SYSs.IPRSTC2.Bits.UART0_RST = 0; //UART0 模块正常工作
  86. UART0s.FCR.Bits.TFR = 1; //TX 软件复位
  87. UART0s.FCR.Bits.RFR = 1; //RX 软件复位
  88. UART0s.FCR.Bits.RFITL = 0x00; //Rx FIFO中断 (INT_RDA) 触发级别 1位

  89. UART0s.LCR.Bits.SPE = 0; //无校验 奇偶使能位
  90. UART0s.LCR.Bits.EPE = 0; // 0----奇校验 1----偶校验
  91. UART0s.LCR.Bits.PBE = 0;
  92. UART0s.LCR.Bits.WLS = 0b011; //字长度选择 8bits
  93. UART0s.LCR.Bits.NSB = 0; //1位停止位

  94. UART0s.BAUD.Bits.BRD = 0x66; //外部12MHz 115200bps 对波特率分频寄存器的设置波特率分频设置即该句必须放在第一位
  95. UART0s.BAUD.Bits.DIV_X_EN = 1; //使能分频X
  96. UART0s.BAUD.Bits.DIV_X_ONE = 1; //Divider X equal 1

  97. UART0s.IER.Bits.RDA_IEN = 1; //使能接收中断
  98. /*
  99. DIV_X_EN DIV_X_ONE Divider X BRD 波特率公式
  100. Disable 0 B A UART_CLK / [16 * (A+2)]
  101. Enable 0 B A UART_CLK / [(B+1) * (A+2)] , B must >= 8
  102. Enable 1 B A UART_CLK / (A+2), A must >=3
  103. */
  104. }

  105. // uart0 输出
  106. void uart0_t::puts(const char* str)
  107. {
  108. fillfifo(str); // 填充 fifo
  109. UART0s.IER.Bits.THRE_IEN = 1; // 允许发送中断
  110. task = &scheduler.get_current_task();
  111. delay(); // 阻塞任务
  112. }

  113. // uart0 中断服务例程
  114. bool uart0_t::isr(int vector)
  115. {
  116. if (UART0s.ISR.Bits.THRE_INT==1)
  117. {
  118. //UART0发送中断
  119. const char* str = buffer;
  120. if (str == 0) { // 无数据
  121. UART0s.IER.Bits.THRE_IEN = 0; // 禁止发送中断
  122. return true;
  123. }
  124. fillfifo(str); // 填充 fifo
  125. return false;
  126. }
  127. if (UART0s.ISR.Bits.RDA_INT==1)
  128. {
  129. //UART0接收中断
  130. /* Get all the input characters */
  131. while(UART0s.ISR.Bits.RDA_IF)
  132. {
  133. /* Get the character from UART Buffer */
  134. uint8_t Received_Data = UART0s.DATA.Regs;
  135. if (Received_Data=='1')
  136. {
  137. //执行蜂鸣器响3次的任务
  138. Flag.do_set_bits(0b0100);
  139. }
  140. else if (Received_Data=='2')
  141. {
  142. //执行与KEY2相同的动作
  143. int ** = Flag.peek();
  144. if (**&0b01)
  145. Flag.do_mask_bits(~0b01); //清除事件标志 位0
  146. else
  147. Flag.do_set_bits(0b01); //置位事件标志 位0
  148. }
  149. else if (Received_Data=='3')
  150. {
  151. task_ad.sem.do_post(); //释放一个信号量资源
  152. }
  153. return false;
  154. }
  155. }
  156. return false;
  157. }

  158. // uart0 中断滞后服务例程
  159. // 所有数据发送完成后,dsr() 被调用
  160. void uart0_t::dsr(int vector, uintptr_t count)
  161. {
  162. task->do_wakeup(); // 唤醒任务
  163. }

  164. // uart0 填充 fifo
  165. void uart0_t::fillfifo(const char* str)
  166. {
  167. do {
  168. char ch;
  169. ch = *str++;
  170. if (ch == 0) {
  171. str = 0;
  172. break;
  173. }
  174. UART0s.DATA.Regs = ch;
  175. } while (!UART0s.FSR.Bits.TX_FULL);
  176. buffer = str;
  177. }

  178. uart0_t uart0; // 创建 uart0 对象

  179. // 任务类 task_led_t 的例程
  180. void task_led_t::routine()
  181. {
  182. // TODO: 在此编写 task_led_t 例程的内容
  183. GPIOAs.DMASK.Regs = ~0b111100;
  184. GPIOAs.DOUT.Regs = ~0b100;
  185. while (true)
  186. {
  187. // TODO: 在此编写 task_led_t 例程的内容
  188. uint32_t data = GPIOAs.DOUT.Regs & 0b111100;
  189. int flag = Flag.peek();
  190. if (flag)
  191. {
  192. data <<= 1;
  193. data += data >> 4;
  194. }
  195. else
  196. {
  197. data >>= 1;
  198. data += data << 4;
  199. }
  200. GPIOAs.DOUT.Regs = data;
  201. delay(LOOK_TICKS_PER_SEC);
  202. }
  203. }

  204. // 任务类 task_key_t 的例程
  205. void task_key_t::routine()
  206. {
  207. // TODO: 在此编写 task_key_t 例程的内容
  208. while (true)
  209. {
  210. // TODO: 在此编写 task_key_t 例程的内容
  211. uint32_t Key_Val = key_read();
  212. if ((Key_Val&(1<<14))==0)
  213. {
  214. //KEY2 按下
  215. int ** = Flag.peek();
  216. if (**&0b01)
  217. Flag.mask_bits(~0b01); //清除事件标志 位0
  218. else
  219. Flag.set_bits(0b01); //置位事件标志 位0
  220. }
  221. if ((Key_Val&(1<<15))==0)
  222. {
  223. //KEY1 按下
  224. Flag.do_set_bits(0b010);
  225. }
  226. delay(LOOK_TICKS_PER_SEC/10);
  227. }
  228. }

  229. // 任务类 task_key_t 的成员函数
  230. __OPT_INLINE__ int32_t task_key_t::key_read()
  231. {
  232. uint32_t Key_Tmp = TRUE;
  233. static uint32_t Key_Record = KEY_NO_DOWN; //按键记录
  234. Key_Tmp = GPIOBs.PIN.Regs&KEY_NO_DOWN;
  235. if(Key_Tmp==KEY_NO_DOWN) //无有效按键按下
  236. {
  237. Key_Record = KEY_NO_DOWN; //清除按键记录
  238. return KEY_NO_DOWN; //程序退出
  239. }
  240. if(Key_Record!=Key_Tmp) //为新按键
  241. {
  242. Key_Record = Key_Tmp; //保存本次结果
  243. delay(LOOK_TICKS_PER_SEC/100); //延时去抖动
  244. Key_Tmp = GPIOBs.PIN.Regs&KEY_NO_DOWN;
  245. if(Key_Tmp==Key_Record)
  246. return Key_Tmp;
  247. }
  248. return KEY_NO_DOWN;
  249. }

  250. // 任务类 task_beep_t 的例程
  251. void task_beep_t::routine()
  252. {
  253. // TODO: 在此编写 task_beep_t 例程的内容
  254. GPIOBs.DOUT.Bits.Pin10 = 0; //蜂鸣器不响
  255. while (true)
  256. {
  257. // TODO: 在此编写 task_beep_t 例程的内容
  258. int flag = Flag.wait(0b110, flag_t::ANY_CONSUME);
  259. if (flag)
  260. {
  261. uart0.puts("Buzzer rang three times!\n");
  262. for (uint32_t i = 0; i < 6; i ++)
  263. {
  264. //蜂鸣器响三次
  265. GPIOBs.DOUT.Bits.Pin10 ^= 1; //蜂鸣器响PB10=1,不响PB10=0
  266. delay(LOOK_TICKS_PER_SEC); //断续间隔
  267. }
  268. }
  269. }
  270. }

  271. // 任务类 task_ad_t 的例程
  272. void task_ad_t::routine()
  273. {
  274. // TODO: 在此编写 task_ad_t 例程的内容
  275. SYSs.IPRSTC2.Bits.ADC_RST = 1;
  276. SYSs.IPRSTC2.Bits.ADC_RST = 0; /* Reset ADC */

  277. //ADC时钟、分频及配置为AD引脚在look中配置

  278. ADCs.ADCR.Bits.ADEN = 1; //使能AD模块

  279. ADCs.ADCALR.Bits.CALEN = 1; //自校正使能
  280. while(!ADCs.ADCALR.Bits.CALDONE); //等待自校正结束

  281. ADCs.ADCR.Bits.DIFFEN = 0; //单端输入
  282. ADCs.ADCR.Bits.ADST = 0; //停止AD
  283. ADCs.ADCR.Bits.ADMD = 0; //单一转换
  284. ADCs.ADCHER.Bits.CHEN = 0x02; //模拟输入通道1使能
  285. ADCs.ADSR.Bits.ADF = 1; //清AD中断标志
  286. while (true)
  287. {
  288. // TODO: 在此编写 task_ad_t 例程的内容
  289. if (sem.wait())
  290. {
  291. ADCs.ADCR.Bits.ADST = 1; //启动AD
  292. while(!ADCs.ADSR.Bits.ADF); //等待转换结束
  293. ADCs.ADSR.Bits.ADF = 1; //清AD中断标志
  294. uint32_t AD_Result = ADCs.ADDR1.Regs&0xFFF;
  295. char str[4];
  296. char *p;
  297. str[0] = AD_Result/1000+'0';
  298. str[1] = AD_Result/100%10+'0';
  299. str[2] = AD_Result/10%10+'0';
  300. str[3] = AD_Result%10+'0';
  301. p = &str[0];
  302. uart0.puts("ADC_RESULT_AD1:");
  303. uart0.puts(p);
  304. }

  305. }
  306. }

  307. #ifdef LOOK_SCHEDULING_PRIORITY
  308. instantiate::task<task_key_t, LOOK_STACK_SIZE> task_key(0);
  309. instantiate::task<task_beep_t, LOOK_STACK_SIZE> task_beep(1);
  310. instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led(2);
  311. instantiate::task<task_ad_t, LOOK_STACK_SIZE> task_ad(3);
  312. #else
  313. instantiate::task<task_key_t, LOOK_STACK_SIZE> task_key;
  314. instantiate::task<task_beep_t, LOOK_STACK_SIZE> task_beep;
  315. instantiate::task<task_led_t, LOOK_STACK_SIZE> task_led;
  316. instantiate::task<task_ad_t, LOOK_STACK_SIZE> task_ad;
  317. #endif
hotpower 发表于 2011-6-12 20:05 | 显示全部楼层
好!俺在路上回家看。
刚与吴旭光教授和牛博士谈了look和ucos。
 楼主| Swallow_0322 发表于 2011-6-12 20:18 | 显示全部楼层
什么结果?等大叔好消息!
dake1478 发表于 2014-3-20 14:31 | 显示全部楼层
这个不错
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

121

主题

1393

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部
个人签名:播种一种行为,收获一种习惯;播种一种习惯,收获一种性格;播种一种性格,收获一种人生!

121

主题

1393

帖子

4

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