当前位置:   article > 正文

一个使用CC2530实现的Zigbee红绿灯_cc2530模拟交通灯总体架构

cc2530模拟交通灯总体架构

  本文介绍了一个ZIGBEE小制作——使用CC2530来实现的红绿灯。这个例子使用协调器透传,可以接受别的控制单片机的串口命令,或者使用PC机的串口助手软件来给协调器发命令,控制节点中红绿灯的状态。节点上红黄绿三个交通灯都可以独立实现开,关或者闪烁。
  先说命令格式:

typedef struct
{
  uint8 Header_1;
  uint8 Header_2;
  uint8 NodeID;
  uint8 Command;
  uint8 Data;
  uint8 Tailer;
}UART_Format;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

  Header_1、Header_2与Tailer是固定的帧头和帧尾,这里用EE,CCC和FF来表示。
  NodeID是设备号,如1号红绿灯可以使用0x01,2号使用0x02;
  Command表示是命令,如0xAA表明是周期消息,0xDD表明是节点对协调器命令的响应。
  Data是数据。这个例子中使用一个8位数据来表示红绿黄三个交通灯的状态,每个交通灯都有两个数据位, 00不亮01亮10闪烁,最高的两位预留,然后从高位到低位依次是红黄绿灯。假如红灯亮,黄灯闪烁绿灯不亮,那么data就是0001 1000,也就是0x18。
  下面是节点的代码:
  首先是IO口与宏定义。具体可根据自己的硬件写。我是用了红绿灯来演示,实际应用可以使用三极管或者继电器控制更高电压的交通灯。

//LED控制接口 
#define LED_R                       P0_4
#define LED_Y                       P0_5
#define LED_G                       P0_6
 //1红2黄3绿   0亮起来 1不亮
#define ON          0
#define OFF         1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

  截取节点的消息处理函数:(flag_X = 1 表示这个灯要闪烁。)

void SerialApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt )  //处理接收到的RF消息
{
。。。。。。
  switch ( pkt->clusterId )
  {
   case SERIALAPP_CLUSTERID1:  //处理各个传感器节数据    
     receiveData = (UART_Format *)(pkt->cmd.Data);
     HalLedBlink(HAL_LED_1,1,50,200);
     if((receiveData->Header_1==0xcc)&&(receiveData->Header_2==0xee)&&(receiveData->Tailer==0xff)) //校验包头包尾
     {
       if(receiveData->NodeID == 0x01) //地址,如果是发给自己的命令
       {            
             flag_R = 0;//先将所有的标识都置零
             flag_Y = 0;//这些标识用来标记是否闪烁
             flag_G = 0;
           Rsp.Command  = 0xDD;//DD表明是响应
           Rsp.Data  = receiveData->Data;
               switch (receiveData->Data)
               {
                    。。。。。。。
                  case 0x06://RHG012   0不亮1亮2闪烁    0000 0110
                     LED_R = OFF;
                     LED_Y = ON;
                     flag_G = 1;
                  break;
。。。。。
                  case 0x2a://RHG222   0不亮1亮2闪烁   0010 1010
                    flag_ALL = 1;   //如果3个灯全部闪烁,特别定义这样一个变量
                     flag_R = 1;  //保证同时亮灭
                     flag_Y = 1;
                     flag_G = 1;
                  break;
               default :
                    Rsp.Command  = 0xEF;//出错
                  break;
               }
         //响应
          osal_set_event(SerialApp_TaskID, LED_BLINK_EVT);
         SerialApp_OTAData(&SerialApp_TxAddr, SERIALAPP_CLUSTERID1, &Rsp, sizeof(UART_Format));
       }
     }
    break;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

  最后使用osal_set_event(SerialApp_TaskID, LED_BLINK_EVT);来设置了一个闪烁事件。这个事件的宏定义

#define LED_BLINK_EVT                       0X0004
  • 1

 这个事件的处理函数:

UINT16 SerialApp_ProcessEvent( uint8 task_id, UINT16 events )
{
  (void)task_id;  // Intentionally unreferenced parameter
。。。。。。
     if ( events & LED_BLINK_EVT ) 
  {
    if (flag_ALL)
    {
      LED_R = 0;
      LED_Y = 0;
      LED_G = 0;
      flag_ALL = 0;
    }
    if (flag_R) LED_R = ! LED_R;
    if (flag_Y) LED_Y = ! LED_Y;  
    if (flag_G) LED_G = ! LED_G; 
      osal_start_timerEx(SerialApp_TaskID, LED_BLINK_EVT, 1000);
    return (events ^ LED_BLINK_EVT);
  }
。。。。。。
  return ( 0 );  // Discard unknown events.
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

 处理函数也很简单,哪个状态位被标记过,就让其对应的灯状态反转,然后使用定时器计时1000毫秒再次反转,就实现了灯的闪烁。

 协调器的功能主要是将串口数据转发为无线数据,也会将节点执行命令的结果通过串口发给控制系统,代码就不列了。
 以上

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/848407
推荐阅读
相关标签
  

闽ICP备14008679号