打印

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

[复制链接]
22485|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 hotpower 于 2010-12-27 03:54 编辑

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

#ifndef __NUC1xxcomIRQ_H__
#define __NUC1xxcomIRQ_H__

#ifdef __cplusplus
extern "C" {
#endif

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

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

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

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

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

#ifdef __cplusplus
}
#endif

#endif//__NUC1xxcomIRQ_H__
2.comIRQ.cpp
 
#include "comirq.h"
ICom_IRQ_Interface IComIRQ;//声明回调函数COM接口全局变量
bool InstallIRQCallbackFunction(unsigned int IRQn, CALLBACK pFunction)
{
bool result = false;
if (IRQn < 32 && pFunction != NULL && IComIRQ.Callback.FunctionArray[IRQn] == NULL)
{
  IComIRQ.Callback.FunctionArray[IRQn] = pFunction;
  IComIRQ.Count++;
  NVICs.ISER.Regs |= (1 << IRQn);//开中断
  result = true;
}
return result;
}
bool UnInstallIRQCallbackFunction(unsigned int IRQn)
{
bool result = false;
if (IRQn < 32 && IComIRQ.Callback.FunctionArray[IRQn] != NULL)
{
  IComIRQ.Callback.FunctionArray[IRQn] = (CALLBACK)NULL;
  IComIRQ.Count--;
  NVICs.ICER.Regs |= (1 << IRQn);//关中断
  result = true;
}
return result;
}
/*
extern "C" void __irq BOD_IRQHandler(void)
{
SYSs.BODCR.Bits.BOD_INTF = 1;
if (IComIRQ.Callback.FunctionArray[BOD_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[BOD_IRQn]();//已安装才运行回调函数
}
}
*/
extern "C" void __irq WDT_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[WDT_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[WDT_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq EINT0_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[EINT0_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[EINT0_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq EINT1_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[EINT1_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[EINT1_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq GPAB_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[BOD_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[BOD_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq GPCDE_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[GPCDE_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[GPCDE_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq PWMA_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[PWMA_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[PWMA_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq PWMB_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[PWMB_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[PWMB_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq TMR0_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[TMR0_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[TMR0_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq TMR1_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[TMR1_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[TMR1_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq TMR2_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[TMR2_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[TMR2_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq TMR3_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[TMR3_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[TMR3_IRQn]();//已安装才运行回调函数
}
}
/*
extern "C" void __irq UART02_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[UART02_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[UART02_IRQn]();//已安装才运行回调函数
}
}
*/
extern "C" void __irq UART1_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[UART1_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[UART1_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq SPI0_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[SPI0_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[SPI0_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq SPI1_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[SPI1_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[SPI1_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq SPI2_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[SPI2_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[SPI2_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq SPI3_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[SPI3_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[SPI3_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq I2C0_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[I2C0_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[I2C0_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq I2C1_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[I2C1_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[I2C1_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq CAN0_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[CAN0_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[CAN0_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq CAN1_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[CAN1_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[CAN1_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq SD_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[SD_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[SD_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq USBD_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[USBD_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[USBD_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq PS2_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[PS2_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[PS2_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq ACMP_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[ACMP_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[ACMP_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq PDMA_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[PDMA_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[PDMA_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq I2S_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[I2S_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[I2S_IRQn]();//已安装才运行回调函数
}
}
/*
extern "C" void __irq PWRWU_IRQHandler(void)
{
SYSCLKs.PWRCON.Bits.PD_WU_STS = 1;
if (IComIRQ.Callback.FunctionArray[PWRWU_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[PWRWU_IRQn]();//已安装才运行回调函数
}
}
*/
extern "C" void __irq ADC_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[ADC_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[ADC_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq DAC_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[DAC_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[DAC_IRQn]();//已安装才运行回调函数
}
}
extern "C" void __irq RTC_IRQHandler(void)
{
if (IComIRQ.Callback.FunctionArray[RTC_IRQn])//测试回调函数是否安装
{
  IComIRQ.Callback.FunctionArray[RTC_IRQn]();//已安装才运行回调函数
}
}
3.main.cpp
 
#include "main.h"
__noinit__ volatile unsigned int SystemRamTest;// = 0x19591119;//RAM不初始化
volatile unsigned int ErrorCount = 0;
/*-------------------------------------------
注意:
1.全局类对象实例的构造函数运行级别高于main()
2.类的构造函数的运行次序与申请次序一样
--------------------------------------------*/
SystemObj System;//自动调用构造函数
SysTickObj SystemTick;//自动调用构造函数
TimerObj  Timer;//自动调用构造函数
RtcObj Rtc;//自动调用构造函数
I2cObj I2c;//自动调用构造函数
WdtObj  Wdt;//自动调用构造函数
TargetObj Target;//自动调用构造函数
/*-------------------------------------------
main()将在以上构造函数的后面运行
--------------------------------------------*/
int main()
{
unsigned char Data;
unsigned char TxBuff[] = "0123456789ABCDEF";
unsigned char RxBuff[] = "FEDCBA9876543210";
/*
String s, s1 = "212";
s = s1 + "212";
if (s == "1212")
{
  __NOP();
}
*/
/*
String s, s1, s2;
s1 = "ded";
s2 = "sdfdf";
s = s1 + s2;
s += s1;
s += s2;
s += "abcdef";
s = s1 + s2;
s = s1 + "323";
s = s1 + "45";
*/
__enable_irq();//开中断
InstallIRQCallbackFunction(I2C0_IRQn, &I2cObj::Exec);//安装I2C回调函数,并打开I2C中断
// UnInstallIRQCallbackFunction(I2C0_IRQn);//卸载I2C回调函数并关闭I2C中断
if (I2c.WriteBuffer(0, TxBuff, 8) != I2C_BUS_OK)
{
  __NOP();//写入AT24C02失败
}
if (I2c.ReadBuffer(0, RxBuff, 8) != I2C_BUS_OK)
{
  __NOP();//读出AT24C02失败
}
if (I2c.WriteByte(0, 0x55) != I2C_BUS_OK)
{
  __NOP();//写入AT24C02失败
}
if (I2c.ReadByte(0, Data) != I2C_BUS_OK)
{
  __NOP();//读出AT24C02失败
}
while(1)
{
  if (SystemTick.Timer.Bits.T500mS)//0.5S到
  {
         PortLed.DOUT.Bits.PinLed ^= 1;//LED闪烁
   SystemTick.Timer.Bits.T500mS = 0;
  }
  SystemTick.Timer.Bits.IntFlag = 0;//清除中断标志(主程序看门狗)
  ::ErrorCount ++;//节拍中断看门狗
  if (::ErrorCount > 0x8888)
  {
   __NOP();//10mS节拍中断错误停在此处!!!
  }
}
}
/*
.\;
..\..\..\..\CMSIS\CM0\CoreSupport;
..\..\..\..\CMSIS\CM0\DeviceSupport\Nuvoton\NUC1xx;
..\..\..\Include;
..\..\..\Include\Driver;
..\..\..\Include\NUC1xx-LB_002
.\;.\CMSIS\CM0\CoreSupport;.\CMSIS\CM0\DeviceSupport\Nuvoton\NUC1xx;.\CMSIS\CM0\DeviceSupport\Nuvoton\NUC1xx\startup;.\System;
*/
/*
*/
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 | 只看该作者
大叔太牛了

使用特权

评论回复
5
yybj| | 2010-12-9 18:28 | 只看该作者
大叔这是在玩技术,似乎乐在其中:lol

使用特权

评论回复
6
秋天落叶| | 2010-12-9 21:31 | 只看该作者
很不错的笔记

使用特权

评论回复
7
a305566| | 2010-12-11 10:21 | 只看该作者
mark

使用特权

评论回复
8
黑发尤物| | 2010-12-11 15:55 | 只看该作者
太牛X的函数,看不懂啊 !

使用特权

评论回复
9
hotpower|  楼主 | 2010-12-15 04:40 | 只看该作者
在菜农的群内只有工程源码提供下载

使用特权

评论回复
10
hotpower|  楼主 | 2011-12-1 23:56 | 只看该作者
本帖最后由 hotpower 于 2011-12-2 00:06 编辑

顶起来,有人想明白

https://bbs.21ic.com/icview-291301-1-1.html

使用特权

评论回复
11
hotpower|  楼主 | 2011-12-2 09:07 | 只看该作者
回调函数说穿了就是在中断服务程序例程isr里放置一个用户函数指针。isr里测试这个函数指针,非空就运行,空就不运行。
为何要如此?拿村里的一句俗话就是:“脱裤子放屁,多此一举”,是吗?
非也,是也。
在mcu编程中,我们一般都是在中断向量表中填写isr地址,在isr内添加用户中断服务程序。
故一般都要动启动代码文件,而这些大都是汇编文件。
如此这般每个用户程序的启动代码都不会相同。当然你可以用系统默认的isr名称,这样就不会动启动代码。
为了省略这些,引入了回调函数,系统事先编写好通用的isr,用于只要设置即安装回调函数即可,而且可以动态卸载,即将回调函数指针清空。
这样就增加了灵活性和通用性,用户就不需要明白中断向量号等有关涉及硬件的知识了。
用户做的只是安装或卸载回调即可。
把精力放在如何写好回调函数即自己的普通函数即可。

使用特权

评论回复
12
回到从前| | 2012-6-28 17:21 | 只看该作者
还不太懂,要好好学习!

使用特权

评论回复
13
江枫渔火| | 2012-6-29 13:04 | 只看该作者
好!好好理解,获益匪浅!

使用特权

评论回复
14
dong_abc| | 2012-6-29 19:49 | 只看该作者
复习一下,c + com , c++ ...

使用特权

评论回复
15
dong_abc| | 2012-7-13 00:11 | 只看该作者
开始copy , 开始运用,开始改造自己的程序。 由衷地感谢菜农~~~

使用特权

评论回复
16
SkyCode| | 2012-8-18 22:06 | 只看该作者
顶了,慢慢看

使用特权

评论回复
17
SkyCode| | 2012-8-18 22:06 | 只看该作者
顶了,慢慢看,这个好啊

使用特权

评论回复
18
呆板书生| | 2012-8-19 09:19 | 只看该作者
编程风格决定菜鸟的级别,风格怪异注定了菜农的孤独

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1460

主题

21619

帖子

506

粉丝