从零开始学习Zstack之2
--------Sample例子演示
本文原地址:http://www.yyytech.cn/Tech/Read.aspx?id=253
上节基本上初步认识了Zstack的一些情况,今天继续我的学习,打开Sample例子看看,究竟ZIGBEE是怎么回事。
毫无疑问:如果是第一次打开这个例子工程,肯定很迷糊,因为此时我迷糊了。对图2-1我简直是相当迷糊。
图2-1
这么多文件夹,打开之后又有那么多文件,从何看起?不要着急,特别是有些人拿到之后,啥都不知道的人第一个问题就是:我要实现XXX,在哪修改或者在哪添加我的函数呢?凡是我遇到这样的客户,我就可以肯定他技术部咋的。就连我这个外行都知道,不把这些弄明白,就是实现XXX只需要修改一个字母,那也不知道在哪改啊?所以我不急,但是我也理解很多客户,因为有时候项目催的比较急,毕竟老板都是外行嘛!
两条路:1就是先看主函数,2就是看看TI提供例子说明文档没有。
我这里先看看主函数再说哈!因为我就知道从主函数看起.
没办法大概每个文件夹找啊,主函数的特征还是比较明明显的,见图2-2所示:
图2-2
下面把主函数复制过来简单看下:
ZSEG int main( void )
{
// Turn off interrupts------------关闭中断
osal_int_disable( INTS_ALL );
// Initialize HAL-----------初始化HAL,关于HAL是什么我想后面会有介绍的。
HAL_BOARD_INIT();
// Make sure supply voltage is high enough to run----电压检测,最好是能保证芯片能正常工作的电压
zmain_vdd_check();
// Initialize stack memory-------------初始化stack存储区
zmain_ram_init();
// Initialize board I/O------------初始化板载IO
InitBoard( OB_COLD );
// Initialze HAL drivers-------------初始化HAL驱动
HalDriverInit();
// Initialize NV System--------------初始化NV系统,NV是什么后面我想也会有介绍的
osal_nv_init( NULL );
// Determine the extended address------------确定扩展地址(64位IEEE/物理地址)
zmain_ext_addr();
// Initialize basic NV items----------------初始化基本NV条目
zgInit();
// Initialize the MAC----------------初始化MAC
ZMacInit();
#ifndef NONWK
// Since the AF isn't a task, call it's initialization routine
afInit();
#endif
// Initialize the operating system----------初始化操作系统,看样子这里面还有OS,麻烦了……..!
osal_init_system();
// Allow interrupts-------------允许中断
osal_int_enable( INTS_ALL );
// Final board initialization------------------最后的版在初始化
InitBoard( OB_READY );
// Display information about this device---------------显示设备信息
zmain_dev_info();
/* Display the device info on the LCD */------------液晶支持显示
#ifdef LCD_SUPPORTED
zmain_lcd_init();
#endif
osal_start_system(); // No Return from here-------------------这里没有返回,大概是进入OS了。
} // main()
可以看到基本上都是初始化函数,因为函数名称都基本上带了init字样的,呵呵,个人觉得TI的变成习惯比我好,一看名称就知道大概功能了。所以这里也奉劝各位像我这样菜鸟级的初学者,一开始一定就要养成规范化编程的习惯,据说这样维护以及以后升级或者移植兼容性都比较好。我就先不管各个初始化函数是怎么实现的,我先看看各个功能是什么,现掌握整体功能在细化,我觉得这样的学习方法比较好,因为代码是在太多了,从一开始就逐句看,我敢保证没几个人有耐心看完看明白!
幸好每个初始化函数都有一句说明,虽然是英文的,但是理解起来一点都不难的。关于每个函数的功能我就直接写在上面的程序里面,节省纸张哈!
………………………………….
一句话:主函数的功能就是初始化!
主函数看完了又开始模糊了,又从何看起呢?在无从下手之际,只有去寻求TI说明文档的帮助了。上节不是漏掉了内容,是关于演示结果的,这里做上补充,怕因为缺调一点后面遇到什么不理解的就惨了!
Sample例子演示演示现象:
1、认识硬件------------按键和LED
上节提到了 EM和DB两个板子,其硬件是不一样的。按键EM就有5各SW1~SW5,而DB只有1各方向键,但是他们有个对应关系,如图2-3所示.
图2-3
LED数量和颜色也不一样,EM有四个LED,如图2-4;而DB只有两个,如图2-5。
如图2-4
如图2-5
关于上面几个图2-4/5中出现的LEDx实际上是程序中出现的关键字。
2、初始化64位IEEE地址
实际上在主函数中有这么个初始化函数的:zmain_ext_addr()。这里说如果地址复位为0xFFFFFFFFFFFFFFFF的话,那么就会不停的闪烁LED1,一直等到按键SW5按下后程序才能继续运行,意思就是说按下SW5后就把无效的地址初始化为有效地物理地址了,这个应该是程序上实现的,那么就来看看对应的程序zmain_ext_addr。
/*********************************************************************
* @fn zmain_ext_addr
* @brief Makes extended address if none exists.确定扩展地址是有效的
* @return none
*********************************************************************/
static ZSEG void zmain_ext_addr( void )
{
uint8 i;
uint8 led;
uint8 tmp;
uint8 *xad;
uint16 AtoD;
// Initialize extended address in NV初始化NV里的扩载地址
osal_nv_item_init( ZCD_NV_EXTADDR, Z_EXTADDR_LEN, NULL );
osal_nv_read( ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, &aExtendedAddress );
// Check for uninitialized value (erased EEPROM = 0xFF)检查是否为无效值(地址)
xad = (uint8*)&aExtendedAddress;
for ( i = 0; i < Z_EXTADDR_LEN; i++ )
if ( *xad++ != 0xFF ) return;-------------------如果有一个字节不为0xFF,那么该地址有效返回
#ifdef ZDO_COORDINATOR
tmp = 0x10;
#else
tmp = 0x20;
#endif
// Initialize with a simple pattern----------------简单初始化扩展地址
xad = (uint8*)&aExtendedAddress;
for ( i = 0; i < Z_EXTADDR_LEN; i++ )
*xad++ = tmp++;
// Flash LED1 until user hits SW5 ---------闪烁LED1直到SW5按下
led = HAL_LED_MODE_OFF;
while ( HAL_KEY_SW_5 != HalKeyRead() )---------------------SW5循环检测
{
MicroWait( 62500 );
HalLedSet( HAL_LED_1, led^=HAL_LED_MODE_ON ); // Toggle the LED
MicroWait( 62500 );
}
HalLedSet( HAL_LED_1, HAL_LED_MODE_OFF );
// Plug AtoD data into lower bytes
AtoD = HalAdcRead (HAL_ADC_CHANNEL_7, HAL_ADC_RESOLUTION_10);
xad = (uint8*)&aExtendedAddress;
*xad++ = LO_UINT16( AtoD );
*xad = HI_UINT16( AtoD );
#if !defined( ZTOOL_PORT ) || defined( ZPORT ) || defined( NV_RESTORE )
// If no support for Z-Tool serial I/O,
// Write temporary 64-bit address to NV些临时的64位物理地址进入NV
osal_nv_write( ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, &aExtendedAddress );
#endif
}
从程序中可以看出,一开始就检测FLASH中的物理地址,因为这个地址在FLASH中是固定的存储空间,一旦为有效地址就退出函数,一旦为无效地址(0xFFFFFFFFFFFFFFFF),那么就对其物理地址进行简单的初始化并检测SW5按键。还是比较好理解的!
3、运行例子
在这里提到了跳线,由于本人采用的非TI原装硬件,没有该跳线,所以必须对程序进行修改,否则检测不到跳线,连ZIGBEE的设备类型都不能确定,肯定不能正常运行了。所以这里就先暂时不说了,这里要说的是一切都正常的情况下,例子的验尸结果。小小跳跃一下。不然学习一直没有进展很麻烦的!
协调器:上电运行,地址检测如上面介绍的情况,通过之后呢-------就进行通道扫描,此时LED1闪烁,一旦协调器成功建立网络,此时LED1停止闪烁,而LED3被点亮。
路由器:上电运行,仍然是地址检测在前。之后就是通道扫描寻求是否又存在的网络,此时LED1闪烁,一旦检测到存在网络并成功加入该网络,LED1将停止闪烁,被替换的是LED3别点亮,也就表明路由器成功加入了网络。
那么此时能进行的操作控制是什么呢,也是最简单的表现手法---按键无线控制LED:
? 周期(5S)发送信息到网络中每个设备
? SW1按下,发送一个信息到组1的设备
? SW2按下,退出/加入组1
这个我是经过验证的。如:
? 按下协调器SW1,路由器的LED1狂闪几下;按下路由器的SW1,那么协调器的LED1也就狂闪几下;当然我是只有两个节点。
? 如果按1下协调器的SW2,在按下路由器的SW1,此时协调器就没有反应,表明协调器已经退出组1;但是再按下协调器SW2在按路由器的SW1就与上一步类似了。路由器与此类似可以通过SW2退出/加入组1.
终于把演示弄完了,接下来就来看看程序。在此之前还是来看看TI提供的Sample指导文档。这个文档个人觉得写的不错,要是没看之前就看程序的却很郁闷的!
但是本人英文很差,所以需要慢慢看,等点时间放上来!
YYYtech于成都
2008年6月25日22:26
文章评论(0条评论)
登录后参与讨论