免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1275 | 回复: 0
打印 上一主题 下一主题

cc2430学习9 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-01-24 11:49 |只看该作者 |倒序浏览
接到昨天的继续忽悠,话说:
2、SimpleApp
“这个例子我基本跑通了,可是鉴于时间的关系,没有来得及打字了,所以就留到下一次了,时间真是如流水啊-------------------快!….”
这个例子里面有两个演示:一个是灯与开关的控制实验,一个温度传感器实验。咱一个个来,不忙。
灯与开关实验
在这个例子中灯对应的工程名字为:SimpleControllerDB;开关对应:SimpleSwitchDB。严重需要注意的地方,这里选用的是DB。因为从从零开始学习Z-Stack之1上可以看到DB与EB的区别,而这里用DB的硬件就足以应付。
编译下载我就不继续罗嗦了。
咱关心的几个问题不外乎就是表演过程和表演结果,以及初步看看为什么会有这样的结果产生,当然就得从程序上简单了解下。
首先打开Controller(也就是灯设备)的电源,那么LED2就会不停的闪烁,这个时候是设备正在初始化,让您选择设备以哪种类型启动,从程序可以看出:
    if ( keys & HAL_KEY_SW_1 )
    {
      if ( myAppState == APP_INIT  )
      {
        // In the init state, keys are used to indicate the logical mode.
        // Key 1 starts device as a coordinator
        zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );
        if ( logicalType != ZG_DEVICETYPE_ENDDEVICE )
        {
          logicalType = ZG_DEVICETYPE_COORDINATOR
;
          zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);
        }
        // Do more configuration if necessary and then restart device with auto-start bit set
        // write endpoint to simple desc...dont pass it in start req..then reset
        zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        startOptions = ZCD_STARTOPT_AUTO_START;
        zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        zb_SystemReset();
      }
如果按下S1(UP),那么作为协调器启动。
   if ( keys & HAL_KEY_SW_2 )
    {
      if ( myAppState == APP_INIT )
      {
        // In the init state, keys are used to indicate the logical mode.
        // Key 2 starts device as a router
        zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType );
        if ( logicalType != ZG_DEVICETYPE_ENDDEVICE )
        {
          logicalType = ZG_DEVICETYPE_ROUTER
;
          zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);
        }
        zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        startOptions = ZCD_STARTOPT_AUTO_START;
        zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        zb_SystemReset();
      }
如果按下S2(RIGHT),设备作为路由器启动。
这里由于是第一个启动的设备,所以作为协调器启动,就按下UP,此时灯会有状态变化,最终结果是:LED2常亮,标示建立网络成功。如果您还有另外的灯设备就可以按下RIGHT让他们都作为路由器启动,由于本人这里只有两个节点,所以就只能有个协调器。
现在就来启动开关设备的电源,同样LED2会闪烁让您选择设备,但是在ZIGBEE中除了协调器和路由器就剩下终端设备了,所以开关就只能作为终端被启动,但是也需要通过按键来控制,从程序中可以看出:
if ( keys & HAL_KEY_SW_1 )
    {
      if ( myAppState == APP_INIT )
      {
        // In the init state, keys are used to indicate the logical mode.
        // The Switch device is always an end-device
        logicalType = ZG_DEVICETYPE_ENDDEVICE
;
        zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);
        // Do more configuration if necessary and then restart device with auto-start bit set
        zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        startOptions = ZCD_STARTOPT_AUTO_START;
        zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        zb_SystemReset();
      }
      else
      {
        // Initiate a binding with null destination
        zb_BindDevice(TRUE, TOGGLE_LIGHT_CMD_ID, NULL);
      }
    }
    if ( keys & HAL_KEY_SW_2 )
    {
      if ( myAppState == APP_INIT )
      {
        // In the init state, keys are used to indicate the logical mode.
        // The Switch device is always an end-device
        logicalType = ZG_DEVICETYPE_ENDDEVICE;
        zb_WriteConfiguration(ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType);
        zb_ReadConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        startOptions = ZCD_STARTOPT_AUTO_START;
        zb_WriteConfiguration( ZCD_NV_STARTUP_OPTION, sizeof(uint8), &startOptions );
        zb_SystemReset();
      }
      else
      {
        // Send the command to toggle light
        zb_SendDataRequest( 0xFFFE, TOGGLE_LIGHT_CMD_ID, 0,
                        (uint8 *)NULL, myAppSeqNumber, 0, 0 );
      }
    }
无论是按下S1还是S2(UP或者RIGHT),开关设备均作为终端设备启动。
启动之后呢,灯的状态同样会发生一些变化,最终结果是:LED2快速闪烁,表明此时开关已经成功加入刚才灯设备建立的那个网络了。
那么接下来就要看这个例子的核心部分----------绑定!
首先按下灯设备(这里为协调器,如果有路由器也可以)的UP,那么程序中调用了:
        zb_AllowBind( myAllowBindTimeout );
函数,允许绑定,这个允许的时间据说只有10S,当然这个时间是可以调整的,因为这里的参数为:static uint8 myAllowBindTimeout = 10;至于这个时间怎么计算的就需要到某个函数zb_AllowBind里去分析了。zb_AllowBind规定这个参数为1~64,如果为0,表示为假,就是不允许绑定的意思。如果大于64的话,就一直为真,就是一直都允许绑定。好像似乎是这个意思。至于这个10S是怎么制定的呢,在这个函数内部调用了:
osal_start_timerEx(sapi_TaskID, ZB_ALLOW_BIND_TIMER, timeout*1000);
因为osal_start_timerEx定时函数最小单位为mS,所以*1000就表示S了。
而在SAPI_ProcessEvent事件处理函数中ZB_ALLOW_BIND_TIMER事件处理如下:
  if ( events & ZB_ALLOW_BIND_TIMER )
  {
    afSetMatch(sapi_epDesc.simpleDesc->EndPoint, FALSE);
    return (events ^ ZB_ALLOW_BIND_TIMER);
  }

也就是定时取消绑定状态!!!
如果有人看着这些看不明白,那就把这个例子多看几遍,多跑几遍。一般如果您每天花费4个小时看这个例子,那么只需要一周事件,我想到时比我还精通明白的!
所以在10S之内,开关必须发起绑定,此时同样按下开关设备的UP,那么开关设备就调用了函数:zb_BindDevice(TRUE, TOGGLE_LIGHT_CMD_ID, NULL);发送一个绑定请求去寻求绑定设备。
一个设备允许绑定,一个设备发起绑定请求,两个是您情我愿的,所以就一拍即合,相当的登对!当然没有这么简单的哈,就如同两个人谈恋爱,至少也需要是一男一女啊,两个都是男或女那就太不正常了,ZIGBEE是个国际化的标准,当然不能有这种变态行为,所以也需要两个命令的属性是相反的,就例如这里的控制灯开关的命令,对于灯来说这个命令为输入,而对于开关来说这个命令是输出。所以一入一出刚好就登对。呵呵!!
绑定成功的表象是:开关设备的LED1快速闪烁。
void zb_AllowBindConfirm( uint16 source )
{
  // Flash LED
  HalLedSet( HAL_LED_1, HAL_LED_MODE_BLINK );
}
绑定成功了就可以发送灯控制命令了。按下RIGHT,调用了函数:
zb_SendDataRequest( 0xFFFE, TOGGLE_LIGHT_CMD_ID, 0,
                        (uint8 *)NULL, myAppSeqNumber, 0, 0 );
可以看出发送了一个数据请求,显然是广播发送的,而命令为切换灯状态的TOGGLE_LIGHT_CMD_ID。当灯收到这命令,就有处理函数了:
void zb_ReceiveDataIndication( uint16 source, uint16 command, uint16 len, uint8 *pData  )
{
  if (command == TOGGLE_LIGHT_CMD_ID)
  {
    // Received application command to toggle the LED
    HalLedSet(HAL_LED_1, HAL_LED_MODE_TOGGLE);
  }
}
所以LED1显示状态发生改变。
此时这个例子已经接近尾声了,因为绑定成功开关能够控制灯了,但是既然可以绑定那么也可以接触绑定的,如果按下开关的DOWN,那么同样调用了发送绑定请求函数:
zb_BindDevice(FALSE, TOGGLE_LIGHT_CMD_ID, NULL);
只是这里第一个参数为FALSE,所以就能解除绑定。如果某个开关被解除了绑定,那么此时就不能控制灯了。
在这个例子最后做个小结------绑定的好处。
绑定了之后,发送数据或者命令,就不需要设备的地址,因为这个命令只能在建立绑定间的设备中传输。------------绝对是我的理解!
还有,一个开关可以绑定多个灯,同样,一个灯可以同时与多个开关发生绑定。这个不代表本人观点,本人强力反对脚踏N只船!!!!!!
现在来简单分析下传感器的例子,由于前面灯的例子说的比较多,这里我就说少点。
中心节点对应SimpleCollectorEB ,传感器节点对应SimpleSensorEB。这里用到了EB,主要是因为DB没有串口硬件,而EB有,这个例子需要用到串口。
传感器的例子效果是:协调器可以收集传感器节点的温度信息并通过串口传输到PC机,如下图所示:


可以看到能够看到节点的温度和电源电压。
具体实现与灯的例子稍区别,但是本质的原理是一样的,先选择设备类型,然后建立绑定,最后收集信息。这里建立绑定的区别在于,只要中心节点允许绑定(与前面操作一样),然后传感器节点是自动发送绑定请求的:
  osal_start_timerEx( sapi_TaskID, MY_FIND_COLLECTOR_EVT, myBindRetryDelay );
定时去产生发MY_FIND_COLLECTOR_EVT事件:
if ( event & MY_FIND_COLLECTOR_EVT )
  {
    // Find and bind to a collector device
    zb_BindDevice( TRUE, SENSOR_REPORT_CMD_ID, (uint8 *)NULL );
  }
这个事件就是发送绑定请求的。
至于绑定后的现象与前面一样了。
最后通过串口调试工具就能看到前面那个图的效果了!!!!!!!!!!!!!
这里的温度为42,这个肯定不可能的,不然我就被蒸发掉了哈!因为采用的是芯片内部集成的温度传感器,这个传感器做实验还可以,因为可以看见温度的变化,但是其准确性是在不敢恭维。TI也是的,做了温度传感器,还超级不准确,还不如不做,只有还可以降低硬件成本,几乎没有任何使用价值!!!
不知道各位看官看到这里有何感想,我想都会觉得我写的乱七八糟,因为我也是兴之所至,毫无章法的。有任何疑问欢迎来函交流:
peterpanjy@163.com
。建议有以书面的形式集中提出交流意见、问题等。本人晚上回家与大家一起学习进步!!!
今天完成的比较早,这个要归功于昨天晚上的功劳。不过还是到此结束,我也需要一点私人空间,看会电影!!!!!!!!!!!!!!


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/73801/showart_1807659.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP