菜农NUC100笔记3(回调函数与COM接口技术)

[复制链接]
 楼主| hotpower 发表于 2010-12-9 02:23 | 显示全部楼层 |阅读模式
本帖最后由 hotpower 于 2010-12-27 03:54 编辑

1.comIRQ.h
  1. #include "main.h"

  2. #ifndef __NUC1xxcomIRQ_H__
  3. #define __NUC1xxcomIRQ_H__

  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif

  7. typedef void (*CALLBACK)(void);//回调函数指针

  8. #define interface struct
  9. typedef interface ICom_IRQ_Interface ICom_IRQ_Interface;//接口定义

  10. typedef struct ICom_IRQVtbl//回调函数指针或回调函数数组结构
  11. {
  12. union{
  13. CALLBACK FunctionArray[32];//回调函数数组
  14. struct{//回调函数指针结构
  15. void (*BOD_IRQCallbackPtr)(void);//0 DrvSYS.C已使用
  16. void (*WDT_IRQCallbackPtr)(void);//1
  17. void (*EINT0_IRQCallbackPtr)(void);//2
  18. void (*EINT1_IRQCallbackPtr)(void);//3
  19. void (*GPAB_IRQCallbackPtr)(void);//4
  20. void (*GPCDE_IRQCallbackPtr)(void);//5
  21. void (*PWMA_IRQCallbackPtr)(void);//6
  22. void (*PWMB_IRQCallbackPtr)(void);//7
  23. void (*TMR0_IRQCallbackPtr)(void);//8
  24. void (*TMR1_IRQCallbackPtr)(void);//9
  25. void (*TMR2_IRQCallbackPtr)(void);//10
  26. void (*TMR3_IRQCallbackPtr)(void);//11
  27. void (*UART02_IRQCallbackPtr)(void);//12
  28. void (*UART1_IRQCallbackPtr)(void);//13
  29. void (*SPI0_IRQCallbackPtr)(void);//14
  30. void (*SPI1_IRQCallbackPtr)(void);//15
  31. void (*SPI2_IRQCallbackPtr)(void);//16
  32. void (*SPI3_IRQCallbackPtr)(void);//17
  33. void (*I2C0_IRQCallbackPtr)(void);//18
  34. void (*I2C1_IRQCallbackPtr)(void);//19
  35. void (*CAN0_IRQCallbackPtr)(void);//20
  36. void (*CAN1_IRQCallbackPtr)(void);//21
  37. void (*SD_IRQCallbackPtr)(void);//22
  38. void (*USBD_IRQCallbackPtr)(void);//23
  39. void (*PS2_IRQCallbackPtr)(void);//24
  40. void (*ACMP_IRQCallbackPtr)(void);//25
  41. void (*PDMA_IRQCallbackPtr)(void);//26
  42. void (*I2S_IRQCallbackPtr)(void);//27
  43. void (*PWRWU_IRQCallbackPtr)(void);//28 DrvSYS.C已使用
  44. void (*ADC_IRQCallbackPtr)(void);//29
  45. void (*DAC_IRQCallbackPtr)(void);//30
  46. void (*RTC_IRQCallbackPtr)(void);//31
  47. }FunctionPtr;
  48. };
  49. }ICom_IRQVtbl, *pICom_IRQVtbl;//回调函数指针或回调函数数组结构

  50. interface ICom_IRQ_Interface//回调函数COM接口
  51. {
  52. ICom_IRQVtbl Callback;//回调函数指针或回调函数数组结构
  53. volatile int Count;//已成功安装的回调函数的个数
  54. };

  55. extern ICom_IRQ_Interface IComIRQ;//回调函数COM接口全局变量
  56. extern bool InstallIRQCallbackFunction(unsigned int IRQn, CALLBACK pFunction);//安装回调函数
  57. extern bool UnInstallIRQCallbackFunction(unsigned int IRQn);//卸载已安装的回调函数

  58. #ifdef __cplusplus
  59. }
  60. #endif

  61. #endif//__NUC1xxcomIRQ_H__
2.comIRQ.cpp

  1. #include "comirq.h"
  2. ICom_IRQ_Interface IComIRQ;//声明回调函数COM接口全局变量
  3. bool InstallIRQCallbackFunction(unsigned int IRQn, CALLBACK pFunction)
  4. {
  5. bool result = false;
  6. if (IRQn < 32 && pFunction != NULL && IComIRQ.Callback.FunctionArray[IRQn] == NULL)
  7. {
  8.   IComIRQ.Callback.FunctionArray[IRQn] = pFunction;
  9.   IComIRQ.Count++;
  10.   NVICs.ISER.Regs |= (1 << IRQn);//开中断
  11.   result = true;
  12. }
  13. return result;
  14. }
  15. bool UnInstallIRQCallbackFunction(unsigned int IRQn)
  16. {
  17. bool result = false;
  18. if (IRQn < 32 && IComIRQ.Callback.FunctionArray[IRQn] != NULL)
  19. {
  20.   IComIRQ.Callback.FunctionArray[IRQn] = (CALLBACK)NULL;
  21.   IComIRQ.Count--;
  22.   NVICs.ICER.Regs |= (1 << IRQn);//关中断
  23.   result = true;
  24. }
  25. return result;
  26. }
  27. /*
  28. extern "C" void __irq BOD_IRQHandler(void)
  29. {
  30. SYSs.BODCR.Bits.BOD_INTF = 1;
  31. if (IComIRQ.Callback.FunctionArray[BOD_IRQn])//测试回调函数是否安装
  32. {
  33.   IComIRQ.Callback.FunctionArray[BOD_IRQn]();//已安装才运行回调函数
  34. }
  35. }
  36. */
  37. extern "C" void __irq WDT_IRQHandler(void)
  38. {
  39. if (IComIRQ.Callback.FunctionArray[WDT_IRQn])//测试回调函数是否安装
  40. {
  41.   IComIRQ.Callback.FunctionArray[WDT_IRQn]();//已安装才运行回调函数
  42. }
  43. }
  44. extern "C" void __irq EINT0_IRQHandler(void)
  45. {
  46. if (IComIRQ.Callback.FunctionArray[EINT0_IRQn])//测试回调函数是否安装
  47. {
  48.   IComIRQ.Callback.FunctionArray[EINT0_IRQn]();//已安装才运行回调函数
  49. }
  50. }
  51. extern "C" void __irq EINT1_IRQHandler(void)
  52. {
  53. if (IComIRQ.Callback.FunctionArray[EINT1_IRQn])//测试回调函数是否安装
  54. {
  55.   IComIRQ.Callback.FunctionArray[EINT1_IRQn]();//已安装才运行回调函数
  56. }
  57. }
  58. extern "C" void __irq GPAB_IRQHandler(void)
  59. {
  60. if (IComIRQ.Callback.FunctionArray[BOD_IRQn])//测试回调函数是否安装
  61. {
  62.   IComIRQ.Callback.FunctionArray[BOD_IRQn]();//已安装才运行回调函数
  63. }
  64. }
  65. extern "C" void __irq GPCDE_IRQHandler(void)
  66. {
  67. if (IComIRQ.Callback.FunctionArray[GPCDE_IRQn])//测试回调函数是否安装
  68. {
  69.   IComIRQ.Callback.FunctionArray[GPCDE_IRQn]();//已安装才运行回调函数
  70. }
  71. }
  72. extern "C" void __irq PWMA_IRQHandler(void)
  73. {
  74. if (IComIRQ.Callback.FunctionArray[PWMA_IRQn])//测试回调函数是否安装
  75. {
  76.   IComIRQ.Callback.FunctionArray[PWMA_IRQn]();//已安装才运行回调函数
  77. }
  78. }
  79. extern "C" void __irq PWMB_IRQHandler(void)
  80. {
  81. if (IComIRQ.Callback.FunctionArray[PWMB_IRQn])//测试回调函数是否安装
  82. {
  83.   IComIRQ.Callback.FunctionArray[PWMB_IRQn]();//已安装才运行回调函数
  84. }
  85. }
  86. extern "C" void __irq TMR0_IRQHandler(void)
  87. {
  88. if (IComIRQ.Callback.FunctionArray[TMR0_IRQn])//测试回调函数是否安装
  89. {
  90.   IComIRQ.Callback.FunctionArray[TMR0_IRQn]();//已安装才运行回调函数
  91. }
  92. }
  93. extern "C" void __irq TMR1_IRQHandler(void)
  94. {
  95. if (IComIRQ.Callback.FunctionArray[TMR1_IRQn])//测试回调函数是否安装
  96. {
  97.   IComIRQ.Callback.FunctionArray[TMR1_IRQn]();//已安装才运行回调函数
  98. }
  99. }
  100. extern "C" void __irq TMR2_IRQHandler(void)
  101. {
  102. if (IComIRQ.Callback.FunctionArray[TMR2_IRQn])//测试回调函数是否安装
  103. {
  104.   IComIRQ.Callback.FunctionArray[TMR2_IRQn]();//已安装才运行回调函数
  105. }
  106. }
  107. extern "C" void __irq TMR3_IRQHandler(void)
  108. {
  109. if (IComIRQ.Callback.FunctionArray[TMR3_IRQn])//测试回调函数是否安装
  110. {
  111.   IComIRQ.Callback.FunctionArray[TMR3_IRQn]();//已安装才运行回调函数
  112. }
  113. }
  114. /*
  115. extern "C" void __irq UART02_IRQHandler(void)
  116. {
  117. if (IComIRQ.Callback.FunctionArray[UART02_IRQn])//测试回调函数是否安装
  118. {
  119.   IComIRQ.Callback.FunctionArray[UART02_IRQn]();//已安装才运行回调函数
  120. }
  121. }
  122. */
  123. extern "C" void __irq UART1_IRQHandler(void)
  124. {
  125. if (IComIRQ.Callback.FunctionArray[UART1_IRQn])//测试回调函数是否安装
  126. {
  127.   IComIRQ.Callback.FunctionArray[UART1_IRQn]();//已安装才运行回调函数
  128. }
  129. }
  130. extern "C" void __irq SPI0_IRQHandler(void)
  131. {
  132. if (IComIRQ.Callback.FunctionArray[SPI0_IRQn])//测试回调函数是否安装
  133. {
  134.   IComIRQ.Callback.FunctionArray[SPI0_IRQn]();//已安装才运行回调函数
  135. }
  136. }
  137. extern "C" void __irq SPI1_IRQHandler(void)
  138. {
  139. if (IComIRQ.Callback.FunctionArray[SPI1_IRQn])//测试回调函数是否安装
  140. {
  141.   IComIRQ.Callback.FunctionArray[SPI1_IRQn]();//已安装才运行回调函数
  142. }
  143. }
  144. extern "C" void __irq SPI2_IRQHandler(void)
  145. {
  146. if (IComIRQ.Callback.FunctionArray[SPI2_IRQn])//测试回调函数是否安装
  147. {
  148.   IComIRQ.Callback.FunctionArray[SPI2_IRQn]();//已安装才运行回调函数
  149. }
  150. }
  151. extern "C" void __irq SPI3_IRQHandler(void)
  152. {
  153. if (IComIRQ.Callback.FunctionArray[SPI3_IRQn])//测试回调函数是否安装
  154. {
  155.   IComIRQ.Callback.FunctionArray[SPI3_IRQn]();//已安装才运行回调函数
  156. }
  157. }
  158. extern "C" void __irq I2C0_IRQHandler(void)
  159. {
  160. if (IComIRQ.Callback.FunctionArray[I2C0_IRQn])//测试回调函数是否安装
  161. {
  162.   IComIRQ.Callback.FunctionArray[I2C0_IRQn]();//已安装才运行回调函数
  163. }
  164. }
  165. extern "C" void __irq I2C1_IRQHandler(void)
  166. {
  167. if (IComIRQ.Callback.FunctionArray[I2C1_IRQn])//测试回调函数是否安装
  168. {
  169.   IComIRQ.Callback.FunctionArray[I2C1_IRQn]();//已安装才运行回调函数
  170. }
  171. }
  172. extern "C" void __irq CAN0_IRQHandler(void)
  173. {
  174. if (IComIRQ.Callback.FunctionArray[CAN0_IRQn])//测试回调函数是否安装
  175. {
  176.   IComIRQ.Callback.FunctionArray[CAN0_IRQn]();//已安装才运行回调函数
  177. }
  178. }
  179. extern "C" void __irq CAN1_IRQHandler(void)
  180. {
  181. if (IComIRQ.Callback.FunctionArray[CAN1_IRQn])//测试回调函数是否安装
  182. {
  183.   IComIRQ.Callback.FunctionArray[CAN1_IRQn]();//已安装才运行回调函数
  184. }
  185. }
  186. extern "C" void __irq SD_IRQHandler(void)
  187. {
  188. if (IComIRQ.Callback.FunctionArray[SD_IRQn])//测试回调函数是否安装
  189. {
  190.   IComIRQ.Callback.FunctionArray[SD_IRQn]();//已安装才运行回调函数
  191. }
  192. }
  193. extern "C" void __irq USBD_IRQHandler(void)
  194. {
  195. if (IComIRQ.Callback.FunctionArray[USBD_IRQn])//测试回调函数是否安装
  196. {
  197.   IComIRQ.Callback.FunctionArray[USBD_IRQn]();//已安装才运行回调函数
  198. }
  199. }
  200. extern "C" void __irq PS2_IRQHandler(void)
  201. {
  202. if (IComIRQ.Callback.FunctionArray[PS2_IRQn])//测试回调函数是否安装
  203. {
  204.   IComIRQ.Callback.FunctionArray[PS2_IRQn]();//已安装才运行回调函数
  205. }
  206. }
  207. extern "C" void __irq ACMP_IRQHandler(void)
  208. {
  209. if (IComIRQ.Callback.FunctionArray[ACMP_IRQn])//测试回调函数是否安装
  210. {
  211.   IComIRQ.Callback.FunctionArray[ACMP_IRQn]();//已安装才运行回调函数
  212. }
  213. }
  214. extern "C" void __irq PDMA_IRQHandler(void)
  215. {
  216. if (IComIRQ.Callback.FunctionArray[PDMA_IRQn])//测试回调函数是否安装
  217. {
  218.   IComIRQ.Callback.FunctionArray[PDMA_IRQn]();//已安装才运行回调函数
  219. }
  220. }
  221. extern "C" void __irq I2S_IRQHandler(void)
  222. {
  223. if (IComIRQ.Callback.FunctionArray[I2S_IRQn])//测试回调函数是否安装
  224. {
  225.   IComIRQ.Callback.FunctionArray[I2S_IRQn]();//已安装才运行回调函数
  226. }
  227. }
  228. /*
  229. extern "C" void __irq PWRWU_IRQHandler(void)
  230. {
  231. SYSCLKs.PWRCON.Bits.PD_WU_STS = 1;
  232. if (IComIRQ.Callback.FunctionArray[PWRWU_IRQn])//测试回调函数是否安装
  233. {
  234.   IComIRQ.Callback.FunctionArray[PWRWU_IRQn]();//已安装才运行回调函数
  235. }
  236. }
  237. */
  238. extern "C" void __irq ADC_IRQHandler(void)
  239. {
  240. if (IComIRQ.Callback.FunctionArray[ADC_IRQn])//测试回调函数是否安装
  241. {
  242.   IComIRQ.Callback.FunctionArray[ADC_IRQn]();//已安装才运行回调函数
  243. }
  244. }
  245. extern "C" void __irq DAC_IRQHandler(void)
  246. {
  247. if (IComIRQ.Callback.FunctionArray[DAC_IRQn])//测试回调函数是否安装
  248. {
  249.   IComIRQ.Callback.FunctionArray[DAC_IRQn]();//已安装才运行回调函数
  250. }
  251. }
  252. extern "C" void __irq RTC_IRQHandler(void)
  253. {
  254. if (IComIRQ.Callback.FunctionArray[RTC_IRQn])//测试回调函数是否安装
  255. {
  256.   IComIRQ.Callback.FunctionArray[RTC_IRQn]();//已安装才运行回调函数
  257. }
  258. }
3.main.cpp

  1. #include "main.h"
  2. __noinit__ volatile unsigned int SystemRamTest;// = 0x19591119;//RAM不初始化
  3. volatile unsigned int ErrorCount = 0;
  4. /*-------------------------------------------
  5. 注意:
  6. 1.全局类对象实例的构造函数运行级别高于main()
  7. 2.类的构造函数的运行次序与申请次序一样
  8. --------------------------------------------*/
  9. SystemObj System;//自动调用构造函数
  10. SysTickObj SystemTick;//自动调用构造函数
  11. TimerObj  Timer;//自动调用构造函数
  12. RtcObj Rtc;//自动调用构造函数
  13. I2cObj I2c;//自动调用构造函数
  14. WdtObj  Wdt;//自动调用构造函数
  15. TargetObj Target;//自动调用构造函数
  16. /*-------------------------------------------
  17. main()将在以上构造函数的后面运行
  18. --------------------------------------------*/
  19. int main()
  20. {
  21. unsigned char Data;
  22. unsigned char TxBuff[] = "0123456789ABCDEF";
  23. unsigned char RxBuff[] = "FEDCBA9876543210";
  24. /*
  25. String s, s1 = "212";
  26. s = s1 + "212";
  27. if (s == "1212")
  28. {
  29.   __NOP();
  30. }
  31. */
  32. /*
  33. String s, s1, s2;
  34. s1 = "ded";
  35. s2 = "sdfdf";
  36. s = s1 + s2;
  37. s += s1;
  38. s += s2;
  39. s += "abcdef";
  40. s = s1 + s2;
  41. s = s1 + "323";
  42. s = s1 + "45";
  43. */
  44. __enable_irq();//开中断
  45. InstallIRQCallbackFunction(I2C0_IRQn, &I2cObj::Exec);//安装I2C回调函数,并打开I2C中断
  46. // UnInstallIRQCallbackFunction(I2C0_IRQn);//卸载I2C回调函数并关闭I2C中断
  47. if (I2c.WriteBuffer(0, TxBuff, 8) != I2C_BUS_OK)
  48. {
  49.   __NOP();//写入AT24C02失败
  50. }
  51. if (I2c.ReadBuffer(0, RxBuff, 8) != I2C_BUS_OK)
  52. {
  53.   __NOP();//读出AT24C02失败
  54. }
  55. if (I2c.WriteByte(0, 0x55) != I2C_BUS_OK)
  56. {
  57.   __NOP();//写入AT24C02失败
  58. }
  59. if (I2c.ReadByte(0, Data) != I2C_BUS_OK)
  60. {
  61.   __NOP();//读出AT24C02失败
  62. }
  63. while(1)
  64. {
  65.   if (SystemTick.Timer.Bits.T500mS)//0.5S到
  66.   {
  67.          PortLed.DOUT.Bits.PinLed ^= 1;//LED闪烁
  68.    SystemTick.Timer.Bits.T500mS = 0;
  69.   }
  70.   SystemTick.Timer.Bits.IntFlag = 0;//清除中断标志(主程序看门狗)
  71.   ::ErrorCount ++;//节拍中断看门狗
  72.   if (::ErrorCount > 0x8888)
  73.   {
  74.    __NOP();//10mS节拍中断错误停在此处!!!
  75.   }
  76. }
  77. }
  78. /*
  79. .\;
  80. ..\..\..\..\CMSIS\CM0\CoreSupport;
  81. ..\..\..\..\CMSIS\CM0\DeviceSupport\Nuvoton\NUC1xx;
  82. ..\..\..\Include;
  83. ..\..\..\Include\Driver;
  84. ..\..\..\Include\NUC1xx-LB_002
  85. .\;.\CMSIS\CM0\CoreSupport;.\CMSIS\CM0\DeviceSupport\Nuvoton\NUC1xx;.\CMSIS\CM0\DeviceSupport\Nuvoton\NUC1xx\startup;.\System;
  86. */
  87. /*
  88. */
4.回调函数指针及数组与COM接口技术的艳照
4.1 回调函数安装计数艳照


4.2 回调函数COM接口指针艳照


4.3 回调函数COM接口数组艳照


本帖子中包含更多资源

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

×
精益求精 发表于 2010-12-9 15:54 | 显示全部楼层
牛。
mtwumtwu 发表于 2010-12-9 17:16 | 显示全部楼层
so many setting maybe occupy many resource
bit6019 发表于 2010-12-9 17:33 | 显示全部楼层
大叔太牛了
yybj 发表于 2010-12-9 18:28 | 显示全部楼层
大叔这是在玩技术,似乎乐在其中:lol
秋天落叶 发表于 2010-12-9 21:31 | 显示全部楼层
很不错的笔记
a305566 发表于 2010-12-11 10:21 | 显示全部楼层
黑发尤物 发表于 2010-12-11 15:55 | 显示全部楼层
太牛X的函数,看不懂啊 !
 楼主| hotpower 发表于 2010-12-15 04:40 | 显示全部楼层
在菜农的群内只有工程源码提供下载
 楼主| hotpower 发表于 2011-12-1 23:56 | 显示全部楼层
本帖最后由 hotpower 于 2011-12-2 00:06 编辑

顶起来,有人想明白

https://bbs.21ic.com/icview-291301-1-1.html
 楼主| hotpower 发表于 2011-12-2 09:07 | 显示全部楼层
回调函数说穿了就是在中断服务程序例程isr里放置一个用户函数指针。isr里测试这个函数指针,非空就运行,空就不运行。
为何要如此?拿村里的一句俗话就是:“脱裤子放屁,多此一举”,是吗?
非也,是也。
在mcu编程中,我们一般都是在中断向量表中填写isr地址,在isr内添加用户中断服务程序。
故一般都要动启动代码文件,而这些大都是汇编文件。
如此这般每个用户程序的启动代码都不会相同。当然你可以用系统默认的isr名称,这样就不会动启动代码。
为了省略这些,引入了回调函数,系统事先编写好通用的isr,用于只要设置即安装回调函数即可,而且可以动态卸载,即将回调函数指针清空。
这样就增加了灵活性和通用性,用户就不需要明白中断向量号等有关涉及硬件的知识了。
用户做的只是安装或卸载回调即可。
把精力放在如何写好回调函数即自己的普通函数即可。
回到从前 发表于 2012-6-28 17:21 | 显示全部楼层
还不太懂,要好好学习!
江枫渔火 发表于 2012-6-29 13:04 | 显示全部楼层
好!好好理解,获益匪浅!
dong_abc 发表于 2012-6-29 19:49 | 显示全部楼层
复习一下,c + com , c++ ...
dong_abc 发表于 2012-7-13 00:11 | 显示全部楼层
开始copy , 开始运用,开始改造自己的程序。 由衷地感谢菜农~~~
SkyCode 发表于 2012-8-18 22:06 | 显示全部楼层
顶了,慢慢看
SkyCode 发表于 2012-8-18 22:06 | 显示全部楼层
顶了,慢慢看,这个好啊
呆板书生 发表于 2012-8-19 09:19 | 显示全部楼层
编程风格决定菜鸟的级别,风格怪异注定了菜农的孤独
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1460

主题

21619

帖子

508

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