本帖最后由 gdmgb520 于 2011-9-21 22:22 编辑
GPIO中断应用之理解回调函数
今天看神龙的GPIO中断讲课笔记。感觉神龙讲的很详细,很细致,非常实用。但对于我等只玩过单片机,没有接触过嵌入式的菜鸟,还有一个问题需要先弄明白,那就是神龙多次提及的回调。由于单片机编程中一般很少使用回调,所以,如果没有接触过嵌入式编程,C语言一般还是比较薄弱的。
下面我分享下我的学习过程,希望对C语言基础比较薄弱的童鞋有所帮助。不对的地方还请大家指点.
阅读前最好是先看神龙的GPIO中断的讲课笔记,然后带着问题来读。
1.函数指针
static void (*_pfGPABCallback)(uint32_tu32GPAStatus, uint32_t u32GPBStatus);
static void (*_pfGPCDECallback)(uint32_tu32GPCStatus, uint32_t u32GPDStatus, uint32_t u32GPEStatus);
static void (*_pfEINT0Callback)(void);
static void (*_pfEINT1Callback)(void);
这里是定义了四个指针变量,以第一个为例,_pfGPABCallback 是一个指针变量,他指向一个函数,该函数返回值为 void型,且该函数是模块内部函数,该函数有两个uint32_t型参数
2.函数指针的使用举例
#include
<stdio.h>
#include
<string.h>
char * fun(char *p1,char *p2)
{
inti = 0;
i = strcmp(p1,p2);
if(0 ==i)
{
returnp1;
}
else
{
returnp2;
}
}
void main(void)
{
char* (*pf)(char *p1,char*p2);
pf = &fun;
(*pf)("ab","bb");
pf("cc","dd");
}
上面main函数中第3行和第4行使用了两种不同 调用方式。通常情况下应该是使用第一种调用方式,但是很多编译器都支持第二种调用方式。
在VC2008中可以看到 pf 和 *pf 的值是一样的,但类型不同:
名称
值
类型
pf
0x004111c7 _fun
char* (char *, char *)*
*pf
0x004111c7_fun
char * (char *, char *)
而我们在M0的例程中见到的就是第二种调用方式,即:
if ( _pfGPABCallback )
_pfGPABCallback(u32GPAStatus, u32GPBStatus);
如果指针变量 _pfGPABCallback不为空,则调用该变量所指向的含水量。
3.指针变量在哪里被赋值了
在2中的例子中我们见到了这条语句:
pf= &fun;
那么在M0的中断例子中这条语句在哪里呢?
DrvGPIO_SetIntCallback(GPABCallback,GPCDECallback);
该函数的定义如下:
voidDrvGPIO_SetIntCallback(GPIO_GPAB_CALLBACK pfGPABCallback, GPIO_GPCDE_CALLBACKpfGPCDECallback)
{
_pfGPABCallback
= (void (*)(uint32_t,uint32_t))pfGPABCallback;
_pfGPCDECallback= (void (*)(uint32_t, uint32_t, uint32_t))pfGPCDECallback;
}
另外:
typedefvoid (*GPIO_GPAB_CALLBACK)(uint32_t u32GPAStatus, uint32_t u32GPBStatus);
所以可以看出:
DrvGPIO_SetIntCallback(GPABCallback,GPCDECallback);
这条调用语句是把两个函数指针(函数地址)传入了该函数,该函数再把这两个指针赋值给变量pfGPABCallback 和 pfGPCDECallback。
这个过程大体上明白了吧。呵呵。 |