本节实验还是建立在前面讲解的点对点通信时所使用的工程,主要是对Coordinator.c文件进行改动,实现串口的收发。
修改Coordinator.c文件,修改后的内容如下(新增加的部分以加粗字体显示):
上述代码大部分都在之前进行了讲解,下面只是着重讲解新增加的部分代码。
ZigBee协议栈中对串口的配置是使用一个结构体来实现的,该结构体为halUARTCfg_t。在此不必关心该结构体的具体定义形式,只需要对其功能有个了解,该结构体将串口初始化有关的参数集合在了一起,如波特率、是否打开串口、是否使用流控等,用户只需要将各个参数初始化就可以了。
最后使用HalUARTOpen()函数对串口进行初始化。注意,该函数将halUARTCfg_t类型的结构体变量作为参数,因为halUARTCfg_t类型的结构体变量已经包含了串口初始化相关的参数,所以,将这些参数传递给HalUARTOpen()函数,HalUARTOpen()函数使用这些参数对串口进行初始化。
该函数是一个空函数, 因为本实验并没有进行事件处理, 所以没有实现任何代码。
第1~3行,清空缓冲中。
第4行,调用HalUARTRead( )函数,从串口读取数据并将其存放在uartbuf数组中。
第5行,使用osal_memcmp( )函数判断接收到的数据是否是字符串“www.wtc.edu.cn”,如果是该字符串,在osal_memcmp( )函数返回TURE,执行第6行。
第6行,调用HalUARTWrite( )函数将接收到的字符输出到串口。
注意,osal_memcmp( )函数经常使用。
上述函数是一个回调函数,什么是回调函数呢?
回调函数就是一个通过函数指针(函数地址)调用的函数。如果把函数的指针(也即函数的地址)作为参数传递给另一个函数,当通过这个指针调用它所指向的函数时,称为函数的回调。
在第6行代码处,将rxCB( )传递给了uartConfig的成员函数caIIBackFunc,其中aIIBack Func的定义为:
halUARTCBack_t callBackFunc;
而halUARTCBack_t的定义为:
typedef void(*halUARTCBack_t)(uint8 port,uint8 event);
这就是定义了一个函数指针。
小技巧:部分读者可能对函数指针的定义形式不熟悉,可以尝试以下面的方式理解,常用的定义形式如下:(www.xing528.com)
typedef uint unsigned int
则如下两种定义变量的方式等价:
unit num;
unsigned int num;
按照这种理解方式,或许函数指针的定义形式改为如下形式更好理解:
typedef halUARTCBack_t void (*) (uint8 port,uint8 event);
当然这只是帮助读者理解的一种方式而已。
因此,第6行代码处,将rxCB()传递给了tConfig变量的callBackFunc成员函数;实现了“把函数的指针(也即函数的地址)作为参数传递给另一个函数”,这样就可以通过callBackFunc成员函数来调用rxCB()函数了。
此外,回调函数不是由该函数的实现方直接调用的,而是在特定的事件或条件发生时,由另外的一方调用的,用于对该事件或条件进行响应。
回调函数机制提供了系统对异步事件的处理能力。首先将异步事件发生时需要执行的代码编写成一个函数,并将该函数注册成为回调函数,这样当该异步事件发生时,系统会自动调用事先注册好的回调函数,回调函数的注册实际上就是将回调函数的信息填写到一个用于注册回调函数的结构体变量中。
在程序中使用回调函数有以下几个步骤:
(1)定义一个回调函数。
(2)在初始化时,提供函数实现的一方将回调函数的函数指针传递给调用者。
(3)当特定的事件或条件发生时,调用者使用函数指针调用回调函数对事件进行处理。
回调函数,顾名思义需要调用者对函数进行回调,到底是什么时候回调的呢?
先把此问题放一放,看一看上述代码的执行情况,然后再对回调进行讲解。
顺便说一句,只要将函数的回调机制理解清楚,ZigBee协议栈的开发就会变得简单,因为串口操作有回调函数,定时器操作有回调函数,按键操作也有回调函数。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。