精读OSAL --中断方式串行通信(_hal_uart_isr.c)

当在HAL里读完 _hal_uart_isr.c 就明白了TI的工程师写的发送接收算法.

 

static void HalUARTInitISR(void) 
static void HalUARTOpenISR(halUARTCfg_t *config)


初始化和打开没什么好讲的,读文档就有了.

 

先在这里讲缓冲区算法

             |-------------------|

head-->|-------------------|

             |-------------------|

             |-------------------|

             |-------------------|

    tail-->|-------------------|

             |-------------------|

             |-------------------|

             |-------------------|

             |-------------------|

             |-------------------|

head和tail都是一个方向移动,当移到末位就回到开头位置.这个很重要..

读写函数不是真正的发送接改函数,他们只是负责将数填入上述的缓冲区,

或者从缓冲区中读出.

怎么操作呢? 读写函数只是将数填入或读出缓冲区,然后移动其中一个指针..

那么什么时候结束呢? 就是head==tail..

这里还有,另一个指针是在发送接收中断函数中移动.

这是这种你追我跑的方式发送接收.

 

这里开始读写函数

/*****************************************************************************
 * @fn      HalUARTReadISR
 *
 * @brief   Read a buffer from the UART
 *
 * @param   buf  - valid data buffer at least 'len' bytes in size
 *          len  - max length number of bytes to copy to 'buf'
 *
 * @return  length of buffer that was read
 *****************************************************************************/
static uint16 HalUARTReadISR(uint8 *buf, uint16 len)
{
  uint16 cnt = 0;

  while ((isrCfg.rxHead != isrCfg.rxTail) && (cnt < len))   //这是读结束条件
  {
    *buf++ = isrCfg.rxBuf[isrCfg.rxHead++];
    if (isrCfg.rxHead >= HAL_UART_ISR_RX_MAX)
    {
      isrCfg.rxHead = 0;
    }
    cnt++;
  }

  return cnt;
}

/******************************************************************************
 * @fn      HalUARTWriteISR
 *
 * @brief   Write a buffer to the UART.
 *
 * @param   buf - pointer to the buffer that will be written, not freed
 *          len - length of
 *
 * @return  length of the buffer that was sent
 *****************************************************************************/
static uint16 HalUARTWriteISR(uint8 *buf, uint16 len)
{
  uint16 cnt;

  // Enforce all or none.
  if (HAL_UART_ISR_TX_AVAIL() < len)   //判断长度是否大于当前有效长度
  {
    return 0;
  }

  for (cnt = 0; cnt < len; cnt++)
  {
    isrCfg.txBuf[isrCfg.txTail] = *buf++;
    isrCfg.txMT = 0;

    if (isrCfg.txTail >= HAL_UART_ISR_TX_MAX-1)  //缓冲区循环
    {
      isrCfg.txTail = 0;
    }
    else
    {
      isrCfg.txTail++;
    }

    // Keep re-enabling ISR as it might be keeping up with this loop due to other ints.
    IEN2 |= UTXxIE;
  }

  return cnt;
}


 

 

这里是中断服务程序:

/***************************************************************************************************
 * @fn      halUartRxIsr
 *
 * @brief   UART Receive Interrupt
 *
 * @param   None
 *
 * @return  None
 ***************************************************************************************************/
#if (HAL_UART_ISR == 1)
HAL_ISR_FUNCTION( halUart0RxIsr, URX0_VECTOR )
#else
HAL_ISR_FUNCTION( halUart1RxIsr, URX1_VECTOR )
#endif
{
  HAL_ENTER_ISR();

  uint8 tmp = UxDBUF;
  isrCfg.rxBuf[isrCfg.rxTail] = tmp;

  // Re-sync the shadow on any 1st byte received.
  if (isrCfg.rxHead == isrCfg.rxTail)
  {
    isrCfg.rxShdw = ST0;
  }

  if (++isrCfg.rxTail >= HAL_UART_ISR_RX_MAX)
  {
    isrCfg.rxTail = 0;
  }

  isrCfg.rxTick = HAL_UART_ISR_IDLE;

  HAL_EXIT_ISR();
}

/***************************************************************************************************
 * @fn      halUartTxIsr
 *
 * @brief   UART Transmit Interrupt
 *
 * @param   None
 *
 * @return  None
 ***************************************************************************************************/
#if (HAL_UART_ISR == 1)
HAL_ISR_FUNCTION( halUart0TxIsr, UTX0_VECTOR )
#else
HAL_ISR_FUNCTION( halUart1TxIsr, UTX1_VECTOR )
#endif
{
  HAL_ENTER_ISR();

  if (isrCfg.txHead == isrCfg.txTail)
  {
    IEN2 &= ~UTXxIE;
    isrCfg.txMT = 1;
  }
  else
  {
    UTXxIF = 0;
    UxDBUF = isrCfg.txBuf[isrCfg.txHead++];

    if (isrCfg.txHead >= HAL_UART_ISR_TX_MAX)
    {
      isrCfg.txHead = 0;
    }
  }

  HAL_EXIT_ISR();
}


 都明白了吧?? 还有一个重要的东西:static void HalUARTPollISR(void)

这个函数是在OSAL每次循环中都调出一次,主要是设置事件,调用相应的回调函数.

 

static void HalUARTPollISR(void)
{
  uint16 cnt = HAL_UART_ISR_RX_AVAIL();
  uint8 evt = 0;

  if (isrCfg.rxTick)
  {
    // Use the LSB of the sleep timer (ST0 must be read first anyway).
    uint8 decr = ST0 - isrCfg.rxShdw;

    if (isrCfg.rxTick > decr)
    {
      isrCfg.rxTick -= decr;
    }
    else
    {
      isrCfg.rxTick = 0;
    }
  }
  isrCfg.rxShdw = ST0;

  if (cnt >= HAL_UART_ISR_RX_MAX-1)
  {
    evt = HAL_UART_RX_FULL;
  }
  else if (cnt >= HAL_UART_ISR_HIGH)
  {
    evt = HAL_UART_RX_ABOUT_FULL;
  }
  else if (cnt && !isrCfg.rxTick)
  {
    evt = HAL_UART_RX_TIMEOUT;
  }

  if (isrCfg.txMT)
  {
    isrCfg.txMT = 0;
    evt |= HAL_UART_TX_EMPTY;
  }

  if (evt && (isrCfg.uartCB != NULL))
  {
    isrCfg.uartCB(HAL_UART_ISR-1, evt);
  }
}


其它函数就不太重要了.

知道这些就很好理解了.

 

/****************************************************************************** * @fn zb_ReceiveDataIndication * * @brief The zb_ReceiveDataIndication callback function is called * asynchronously by the ZigBee stack to notify the application * when data is received from a peer device. * * @param source - The short address of the peer device that sent the data * command - The commandId associated with the data * len - The number of bytes in the pData parameter * pData - The data sent by the peer device * * @return none */ /* void zb_ReceiveDataIndication( uint16 source, uint16 command, uint16 len, uint8 *pData ) { //处理数据格式 gtwData.parent = BUILD_UINT16(pData[SENSOR_PARENT_OFFSET+ 1], pData[SENSOR_PARENT_OFFSET]); gtwData.source=source; gtwData.temp=*pData; gtwData.voltage=*(pData+1); // Flash LED 1 once to indicate data reception //接收到数据之后LED灯闪烁1次 HalLedSet( HAL_LED_1, HAL_LED_MODE_OFF ); HalLedSet( HAL_LED_1, HAL_LED_MODE_BLINK ); // Send gateway report //发送网关数据 sendGtwReport(&gtwData); } */ void zb_ReceiveDataIndication(uint16 source, uint16 command, uint16 len, uint8 *pData) { gtwData.parent = BUILD_UINT16(pData[SENSOR_PARENT_OFFSET+1], pData[SENSOR_PARENT_OFFSET]); gtwData.source = source; gtwData.temp = *pData; gtwData.humidity = *(pData+1); gtwData.humandetected = *(pData+2); // Flash LED 1 once to indicate data reception HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF); HalLedSet(HAL_LED_1, HAL_LED_MODE_BLINK); // 格式化显示数据 char displayBuf[50]; //sprintf(displayBuf, "22145131 22145137:%d,%d\r\n", gtwData.temp, gtwData.humidity); sprintf(displayBuf, "A0=%d A1=%d H0=%d\r\n", gtwData.temp, gtwData.humidity,gtwData.humandetected); HalUARTWrite(HAL_UART_PORT_0,(uint8 *)displayBuf, strlen(displayBuf)); sendGtwReport(&gtwData); } /****************************************************************************** * @fn uartRxCB * * @brief Callback function for UART * * @param port - UART port * event - UART event that caused callback * * @return none */ /*void uartRxCB(uint8 port, uint8 event) { uint8 pBuf[RX_BUF_LEN]; uint16 len; uint16 cmd; if (event != HAL_UART_TX_EMPTY) { len = HalUARTRead(HAL_UART_PORT_0, pBuf, RX_BUF_LEN); if (len > 0) { // 检查是否是PING请求 cmd = BUILD_UINT16(pBuf[SYS_PING_CMD_OFFSET+1], pBuf[SYS_PING_CMD_OFFSET]); if ((pBuf[FRAME_SOF_OFFSET] == CPT_SOP) && (cmd == SYS_PING_REQUEST)) { sysPingReqRcvd(); return; } // 处理字符串命令 if (strncmp((char *)pBuf, "0x131 ON", 8) == 0) { // LED ON命令 HalLedSet(HAL_LED_2, HAL_LED_MODE_BLINK); uint8 cmd[] = "305 ON"; zb_SendDataRequest(0xFFFF, SENSOR_REPORT_CMD_ID, sizeof(cmd)-1, cmd, 0, AF_ACK_REQUEST, 0); HalUARTWrite(HAL_UART_PORT_0, "22145131 22145137:LED ON ok\r\n", sizeof("22145131 22145137:LED ON ok\r\n")); } else if (strncmp((char *)pBuf, "0x131 OFF", 9) == 0) { // LED OFF命令 HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); uint8 cmd[] = "305 OFF"; zb_SendDataRequest(0xFFFF, SENSOR_REPORT_CMD_ID, sizeof(cmd)-1, cmd, 0, AF_ACK_REQUEST, 0); HalUARTWrite(HAL_UART_PORT_0, "22145131 22145137:LED OFF命令已发送\r\n", sizeof("22145131 22145137:LED OFF命令已发送\r\n")); } else if (strncmp((char *)pBuf, "0x132", 5) == 0) { // 单次采集命令 uint8 cmd[] = "SINGLE_REPORT"; zb_SendDataRequest(0xFFFE, SENSOR_REPORT_CMD_ID, sizeof(cmd)-1, cmd, 0, AF_ACK_REQUEST, 0); HalUARTWrite(HAL_UART_PORT_0, "22145131 22145137:one collect ok\r\n", sizeof("22145131 22145137:one collect ok\r\n")); } else if (strncmp((char *)pBuf, "0x133", 5) == 0) { // 连续采集命令 continuousReporting = 1; reportCount = 0; uint8 cmd[] = "CONTINUOUS_REPORT"; zb_SendDataRequest(0xFFFE, SENSOR_REPORT_CMD_ID, sizeof(cmd)-1, cmd, 0, AF_ACK_REQUEST, 0); HalUARTWrite(HAL_UART_PORT_0, "22145131 22145137:many collect ok\r\n", sizeof("22145131 22145137:many collect ok\r\n")); } else if (strncmp((char *)pBuf, "0x134", 5) == 0) { // 停止采集命令 continuousReporting = 0; uint8 cmd[] = "STOP_REPORT"; zb_SendDataRequest(0xFFFE, SENSOR_REPORT_CMD_ID, sizeof(cmd)-1, cmd, 0, AF_ACK_REQUEST, 0); HalUARTWrite(HAL_UART_PORT_0, "22145131 22145137:stop collect ok\r\n", sizeof("22145131 22145137:stop collect ok\r\n")); } } } }*/ /*风扇传感器------------------------------------------------------------------ ------------------------------------------------------------------------*/ //转速显示函数 int count = 0; void Speed(void) { char Str[10]; sprintf(Str,"%d\r\n",count/3); Uart_Send_String(Str); //串口发送数据 count = 0; halWait(250); //延时 halWait(250); halWait(250); halWait(250); } /*T1初始化函数,配置为pwm模式 -------------------------------------------------------*/ void t1_init(void) { PERCFG = 0x03; //位置1 定时器1设置为位置1, P0SEL |= 0x20; //P0_5用作外设接口 P0DIR |= 0x20; P2DIR |= 0xC0; T1CNTL = 0x00; T1CNTH = 0x00; T1CCTL3 = 0x2C; //比较模式6 T1CC0L = 0xFF; //周期 T1CC0H = 0xEF; T1CC3L = 0xFF; //占空比 T1CC3H = 0x6F; T1CTL = 0x0E; //模模式 } /*中断服务子程序 -------------------------------------------------------*/ #pragma vector = P0INT_VECTOR __interrupt void P0_ISR(void) { EA = 0; //关中断 if((P0IFG & 0x02 ) >0 ) //按键中断 ,p0_1 { halWait(200); //去抖动 P0IFG &= ~0x02; //P0.1中断标志清0 T1CC3H = T1CC3H + 0x20; //减小占空比 T1CC3L = 0xFF; } if((P0IFG & 0x10 ) >0 ) //按键中断 ,p0_4 { halWait(200); //去抖动 P0IFG &= ~0x10; //P0.4中断标志清0 T1CC3H = T1CC3H - 0x20; //增大占空比 T1CC3L = 0xFF; } if((P0IFG & 0x40 ) >0 ) // p0_6 { P0IFG &= ~0x40; //P0.5中断标志清0 count++; } P0IF = 0; //P0中断标志清0 EA = 1; //开中断 } /*延时函数 -------------------------------------------------------*/ void halWait(unsigned char wait) { unsigned long largeWait; if(wait == 0) {return;} largeWait = ((unsigned short) (wait << 7)); largeWait += 114*wait; largeWait = (largeWait >> CLKSPD); while(largeWait--); return; } //节能模式 void SetLowPowerMode(void) { // 1. 降低传感器采样频率 osal_stop_timerEx(sapi_TaskID, SENSOR_SAMPLE_EVT); osal_start_timerEx(sapi_TaskID, SENSOR_SAMPLE_EVT, 5000); // 5秒采样 // 2. 关闭非必要外设 HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); // 关闭D6 // 3. 发送节能通知 Uart_Send_String("SYSTEM: Entering Low Power Mode"); }
最新发布
07-03
/************************************************************************************************** Filename: SampleApp.c Revised: $Date: 2009-03-18 15:56:27 -0700 (Wed, 18 Mar 2009) $ Revision: $Revision: 19453 $ Description: Combined Application with Interrupt Handling and Environmental Sensing Copyright 2007 Texas Instruments Incorporated. All rights reserved. IMPORTANT: Your use of this Software is limited to those specific rights granted under the terms of a software license agreement between the user who downloaded the software, his/her employer (which must be your employer) and Texas Instruments Incorporated (the "License"). You may use this Software unless you agree to abide by the terms of the License. The License limits your use, and you acknowledge, that the Software may not be modified, copied or distributed unless embedded on a Texas Instruments microcontroller or used solely and exclusively in conjunction with a Texas Instruments radio frequency transceiver, which is integrated into your product. Other than for the foregoing purpose, you may not use, reproduce, copy, prepare derivative works of, modify, distribute, perform, display or sell this Software and/or its documentation for any purpose. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED极地 ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. Should you have any questions regarding your right to use this Software, contact Texas Instruments Incorporated at www.TI.com. **************************************************************************************************/ /********************************************************************* * INCLUDES */ #include <stdio.h> #include <string.h> #include "OSAL.h" #include "ZGlobals.h" #include "AF.h" #include "aps_groups.h" #include "ZDApp.h" #include "MT_UART.h" #include "SampleApp.h" // 包含头文件 #include "SampleAppHw.h" #include "OnBoard.h" #include "sht11.h" // 温湿度传感器头文件 /* HAL */ #include "hal_lcd.h" #include "hal_led.h" #include "hal_key.h" // 确保所有簇ID被定义 #ifndef SAMPLEAPP_SENDINT_CLUSTERID #define SAMPLEAPP_SENDINT_CLUSTERID 0x0003 #endif #ifndef SAMPLEAPP_ALARM_CLUSTERID #define SAMPLEAPP_ALARM_CLUSTERID 0x0004 // 报警簇ID #endif /********************************************************************* * CONSTANTS */ // 定义中断事件 #define SAMPLEAPP_SEND_SENSOR_INT_EVT 0x0004 // 学生信息 #define STUDENT_ID_NAME "42213361ljl" #define SENSOR2_NAME "HW01" // 传感器2名称 // 温湿度阈值 #define TEMP_THRESHOLD 25.0 #define HUMI_THRESHOLD 60.0 // 中断计数阈值 #define INT_COUNT_THRESHOLD 5 /********************************************************************* * GLOBAL VARIABLES */ const cId_t SampleApp_ClusterList[SAMPLEAPP_MAX_CLUSTERS] = { SAMPLEAPP_PERIODIC_CLUSTERID, // 温湿度数据 SAMPLEAPP_FLASH_CLUSTERID, // Flash命令 SAMPLEAPP_SENDINT_CLUSTERID, // 中断消息 SAMPLEAPP_ALARM_CLUSTERID // 报警信息 }; const SimpleDescriptionFormat_t SampleApp_SimpleDesc = { SAMPLEAPP_ENDPOINT, // int Endpoint; SAMPLEAPP_PROFID, // uint16 AppProfId; SAMPLEAPP_DEVICEID, // uint16 AppDeviceId; SAMPLEAPP_DEVICE_VERSION, // int AppDevVer:4; SAMPLEAPP_FLAGS, // int AppFlags:4; SAMPLEAPP_MAX_CLUSTERS, // uint8 AppNumInClusters; (cId_t *)SampleApp_ClusterList, // uint8 *pAppInClusterList; SAMPLEAPP_MAX_CLUSTERS, // uint8 AppNumOutClusters; (cId_t *)SampleApp_ClusterList // uint8 *pAppOutClusterList; }; endPointDesc_t SampleApp_epDesc; /********************************************************************* * LOCAL VARIABLES */ uint8 SampleApp_TaskID; devStates_t SampleApp_NwkState; uint8 SampleApp_TransID; uint8 gIntFlag = 0; // 中断标志 // 新增状态变量 uint8 gTempHumiAlarm = 0; // 温湿度异常标志 uint8 gIntAlarm = 0; // 中断异常标志 uint8 gIntCount = 0; // 中断计数 uint8 gLED1State = 0; // LED1状态(温湿度模块) uint8 gLED2State = 0; // LED2状态(中断模块) afAddrType_t SampleApp_Periodic_DstAddr; afAddrType_t SampleApp_Flash_DstAddr; afAddrType_t SampleApp_Alarm_DstAddr; // 报警目标地址 aps_Group_t SampleApp_Group; uint8 SampleAppPeriodicCounter = 0; uint8 SampleAppFlashCounter = 0; /********************************************************************* * FUNCTION PROTOTYPES */ void SampleApp_HandleKeys(uint8 shift, uint8 keys); void SampleApp_MessageMSGCB(afIncomingMSGPacket_t *pckt); void SampleApp_SendPeriodicMessage(void); void SampleApp_SendFlashMessage(uint16 flashTime); void SensorIO_Init(void); void SampleApp_Process_SensorInt(void); void SampleApp_ProcessIntMessage(afIncomingMSGPacket_t *pkt); void SampleApp_SendAlarmMessage(const char *alarmMsg); void SampleApp_CheckTempHumiThreshold(float temp, float humi); void SampleApp_CheckIntCount(void); void SampleApp_ProcessControlCommand(char *cmd); HAL_ISR_FUNCTION(halP12isr, P1INT_VECTOR); void Delay(int n); void BuildSensorDataString(char *buf, uint8 bufSize, float temp, float humi); void BuildInterruptString(char *buf, uint8 bufSize); void BuildAlarmString(char *buf, uint8 bufSize, const char *alarmType, uint8 isReset); void BuildForcedAlarmString(char *buf, uint8 bufSize, const char *alarmType); void RemoveSpaces(char *str); // 移除字符串中的空格 /********************************************************************* * @fn SampleApp_Init */ void SampleApp_Init(uint8 task_id) { SampleApp_TaskID = task_id; SampleApp_NwkState = DEV_INIT; SampleApp_TransID = 0; #if defined(BUILD_ALL_DEVICES) if (readCoordinatorJumper()) zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR; else zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER; #endif #if defined(HOLD_AUTO_START) ZDOInitDevice(0); #endif // 广播地址用于发送温湿度数据 SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast; SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF; // 组播地址用于Flash命令 SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup; SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP; // 报警目标地址(协调器) SampleApp_Alarm_DstAddr.addrMode = (afAddrMode_t)Addr16Bit; SampleApp_Alarm_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Alarm_DstAddr.addr.shortAddr = 0x0000; // 协调器地址 // 端点描述符 SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_epDesc.task_id = &SampleApp_TaskID; SampleApp_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc; SampleApp_epDesc.latencyReq = noLatencyReqs; afRegister(&SampleApp_epDesc); RegisterForKeys(SampleApp_TaskID); MT_UartRegisterTaskID(SampleApp_TaskID); // 默认组设置 SampleApp_Group.ID = SAMPLEAPP_FLASH_GROUP; osal_memcpy(SampleApp_Group.name, "Group 1", 7); aps_AddGroup(SAMPLEAPP_ENDPOINT, &SampleApp_Group); // 初始化中断IO SensorIO_Init(); // 初始化LED状态 HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF); HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); gLED1State = 0; gLED2State = 0; #if defined(LCD_SUPPORTED) HalLcdWriteString("Int&Env Sensor", HAL_LCD_LINE_1); HalLcdWriteString(STUDENT_ID_NAME, HAL_LCD_LINE_2); #endif } /********************************************************************* * @fn SampleApp_ProcessEvent */ uint16 SampleApp_ProcessEvent(uint8 task_id, uint16 events) { afIncomingMSGPacket_t *MSGpkt; (void)task_id; // Unused parameter if (events & SYS_EVENT_MSG) { MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(SampleApp_TaskID); while (MSGpkt) { switch (MSGpkt->hdr.event) { case KEY_CHANGE: SampleApp_HandleKeys(((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys); break; case AF_INCOMING_MSG_CMD: SampleApp_MessageMSGCB(MSGpkt); break; case ZDO_STATE_CHANGE: SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status); if ((SampleApp_NwkState == DEV_ZB_COORD) || (SampleApp_NwkState == DEV_ROUTER) || (SampleApp_NwkState == DEV_END_DEVICE)) { HalLedSet(HAL_LED_1, HAL_LED_MODE_ON); osal_start_timerEx(SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT); } break; default: break; } osal_msg_deallocate((uint8 *)MSGpkt); MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(SampleApp_TaskID); } return (events ^ SYS_EVENT_MSG); } if (events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT) { // 发送温湿度数据 char buffer[64]; float humi, temp; if (GetHumiAndTemp(&humi, &temp) == 0) { // 构建数据字符串:"42213361ljl huim:26 temp:45" BuildSensorDataString(buffer, sizeof(buffer), temp, humi); // 广播发送 AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, strlen(buffer), (uint8 *)buffer, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); // 检查温湿度阈值 SampleApp_CheckTempHumiThreshold(temp, humi); } // 重新设置定时器 osal_start_timerEx(SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT); return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT); } if (events & SAMPLEAPP_SEND_SENSOR_INT_EVT) { SampleApp_Process_SensorInt(); // 检查中断计数 SampleApp_CheckIntCount(); return (events ^ SAMPLEAPP_SEND_SENSOR_INT_EVT); } return 0; } /********************************************************************* * @fn SampleApp_HandleKeys */ void SampleApp_HandleKeys(uint8 shift, uint8 keys) { (void)shift; // Unused parameter if (keys & HAL_KEY_SW_6) { SampleApp_SendFlashMessage(SAMPLEAPP_FLASH_DURATION); } if (keys & HAL_KEY_SW_2) { aps_Group_t *grp = aps_FindGroup(SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP); if (grp) { aps_RemoveGroup(SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP); } else { aps_AddGroup(SAMPLEAPP_ENDPOINT, &SampleApp_Group); } } } /********************************************************************* * @fn SensorIO_Init */ void SensorIO_Init(void) { // 配置P1.2为中断输入 P1DIR &= ~0x04; // P1.2输入模式 P1INP &= ~0x04; // 上拉电阻 P1IEN |= 0x04; // 使能中断 PICTL &= ~0x02; // 上升沿触发 // 使能中断 IEN2 |= 0x10; // P1中断使能 IEN0 |= 0x80; // 全局中断使能 P1IFG &= ~0x04; // 清除中断标志 } /********************************************************************* * @fn halP12isr */ HAL_ISR_FUNCTION(halP12isr, P1INT_VECTOR) { if (P1IFG & 0x04) { // 检查P1.2中断 gIntFlag = 0x01; // 设置中断标志 gIntCount++; // 增加中断计数 osal_set_event(SampleApp_TaskID, SAMPLEAPP_SEND_SENSOR_INT_EVT); P1IFG &= ~0x04; // 清除中断标志 } P1IF = 0; // 清除端口中断标志 } /********************************************************************* * @fn SampleApp_Process_SensorInt */ void SampleApp_Process_SensorInt(void) { char intBuffer[64]; // 构建中断消息字符串 BuildInterruptString(intBuffer, sizeof(intBuffer)); // 发送中断通知到协调器(短地址0x0000) afAddrType_t intDstAddr = { .addrMode = (afAddrMode_t)Addr16Bit, .endPoint = SAMPLEAPP_ENDPOINT, .addr.shortAddr = 0x0000 }; AF_DataRequest(&intDstAddr, &SampleApp_epDesc, SAMPLEAPP_SENDINT_CLUSTERID, strlen(intBuffer), (uint8 *)intBuffer, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); // 本地指示 HalLedBlink(HAL_LED_1, 4, 50, 250); HalUARTWrite(0, "\r\nINT Triggered!", 15); gIntFlag = 0x00; // 重置中断标志 } /********************************************************************* * @fn SampleApp_MessageMSGCB */ void SampleApp_MessageMSGCB(afIncomingMSGPacket_t *pkt) { switch (pkt->clusterId) { case SAMPLEAPP_PERIODIC_CLUSTERID: // 温湿度数据 // 在协调器上显示温湿度数据 HalUARTWrite(0, (uint8 *)"\r\n", 2); HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength); break; case SAMPLEAPP_SENDINT_CLUSTERID: // 中断消息 SampleApp_ProcessIntMessage(pkt); break; case SAMPLEAPP_FLASH_CLUSTERID: { // Flash命令/控制命令 // 将接收到的数据视为字符串命令 char cmd[32]; uint8 len = pkt->cmd.DataLength; if (len > sizeof(cmd) - 1) len = sizeof(cmd) - 1; memcpy(cmd, pkt->cmd.Data, len); cmd[len] = '\0'; // 确保字符串结束 // 处理控制命令 SampleApp_ProcessControlCommand(cmd); break; } case SAMPLEAPP_ALARM_CLUSTERID: // 报警信息 // 在协调器上显示报警信息 HalUARTWrite(0, (uint8 *)"\r\n", 2); HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength); break; } } /********************************************************************* * @fn SampleApp_ProcessIntMessage */ void SampleApp_ProcessIntMessage(afIncomingMSGPacket_t *pkt) { HalLedBlink(HAL_LED_1, 8, 100, 500); // 长闪烁指示 HalUARTWrite(0, "\r\nInterrupt Received: ", 23); HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength); } /********************************************************************* * @fn SampleApp_SendFlashMessage */ void SampleApp_SendFlashMessage(uint16 flashTime) { uint8 buffer[3]; buffer[0] = (uint8)(SampleAppFlashCounter++); buffer[1] = LO_UINT16(flashTime); buffer[2] = HI_UINT16(flashTime); if (AF_DataRequest(&SampleApp_Flash_DstAddr, &SampleApp_epDesc, SAMPLEAPP_FLASH_CLUSTERID, 3, buffer, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS) != afStatus_SUCCESS) { // 错误处理 } } /********************************************************************* * @fn SampleApp_SendAlarmMessage */ void SampleApp_SendAlarmMessage(const char *alarmMsg) { uint8 len = strlen(alarmMsg); AF_DataRequest(&SampleApp_Alarm_DstAddr, &SampleApp_epDesc, SAMPLEAPP_ALARM_CLUSTERID, len, (uint8 *)alarmMsg, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } /********************************************************************* * @fn SampleApp_CheckTempHumiThreshold */ void SampleApp_CheckTempHumiThreshold(float temp, float humi) { char buffer[64]; // 检查是否超过阈值:任一条件超过就触发报警 if (temp > TEMP_THRESHOLD || humi > HUMI_THRESHOLD) { if (!gTempHumiAlarm) { gTempHumiAlarm = 1; // LED1持续闪烁(温湿度模块) HalLedBlink(HAL_LED_1, 0, 50, 500); BuildAlarmString(buffer, sizeof(buffer), "温湿度异常", 0); SampleApp_SendAlarmMessage(buffer); } } else { // 当两个都恢复到正常范围,才解除报警 if (gTempHumiAlarm && temp <= TEMP_THRESHOLD && humi <= HUMI_THRESHOLD) { gTempHumiAlarm = 0; // 恢复LED1到控制命令设置的状态 if (gLED1State) { HalLedSet(HAL_LED_1, HAL_LED_MODE_ON); } else { HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF); } BuildAlarmString(buffer, sizeof(buffer), "温湿度异常", 1); SampleApp_SendAlarmMessage(buffer); } } } /********************************************************************* * @fn SampleApp_CheckIntCount */ void SampleApp_CheckIntCount(void) { char buffer[64]; // 检查中断计数是否超过阈值 if (gIntCount >= INT_COUNT_THRESHOLD) { if (!gIntAlarm) { gIntAlarm = 1; HalLedBlink(HAL_LED_2, 0, 50, 500); // LED2持续闪烁(中断模块) BuildAlarmString(buffer, sizeof(buffer), "传感状态异常", 0); SampleApp_SendAlarmMessage(buffer); } } else { if (gIntAlarm) { gIntAlarm = 0; // 恢复LED2到控制命令设置的状态 if (gLED2State) { HalLedSet(HAL_LED_2, HAL_LED_MODE_ON); } else { HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); } BuildAlarmString(buffer, sizeof(buffer), "传感状态异常", 1); SampleApp_SendAlarmMessage(buffer); } } } /********************************************************************* * @fn RemoveSpaces * @brief 移除字符串中的所有空格 */ void RemoveSpaces(char *str) { char *p1 = str, *p2 = str; while (*p1) { if (*p1 != ' ') { *p2++ = *p1; } p1++; } *p2 = '\0'; } /********************************************************************* * @fn SampleApp_ProcessControlCommand */ void SampleApp_ProcessControlCommand(char *cmd) { char buffer[64]; // 调试:输出接收到的命令 HalUARTWrite(0, "\r\nRecv Cmd: ", 11); HalUARTWrite(0, (uint8*)cmd, strlen(cmd)); // 复制命令并移除所有空格 char cmdCopy[64]; strncpy(cmdCopy, cmd, sizeof(cmdCopy)-1); cmdCopy[sizeof(cmdCopy)-1] = '\0'; RemoveSpaces(cmdCopy); // 调试:输出处理后的命令 HalUARTWrite(0, "\r\nProcessed: ", 12); HalUARTWrite(0, (uint8*)cmdCopy, strlen(cmdCopy)); // 检查命令前缀 if (strncmp(cmdCopy, STUDENT_ID_NAME, strlen(STUDENT_ID_NAME)) != 0) { HalUARTWrite(0, "\r\nInvalid Prefix", 15); return; // 命令前缀不匹配 } char *command = cmdCopy + strlen(STUDENT_ID_NAME); // 处理LED控制命令 - Num1控制温湿度模块LED1 if (strstr(command, "Num1Led")) { if (strstr(command, "on")) { HalLedSet(HAL_LED_1, HAL_LED_MODE_ON); gLED1State = 1; HalUARTWrite(0, "\r\nTEMP LED1 ON", 13); } else if (strstr(command, "off")) { HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF); gLED1State = 0; HalUARTWrite(0, "\r\nTEMP LED1 OFF", 14); } else if (strstr(command, "relie")) { // 强制解除温湿度异常 if (gTempHumiAlarm) { gTempHumiAlarm = 0; HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF); gLED1State = 0; BuildForcedAlarmString(buffer, sizeof(buffer), "温湿度"); SampleApp_SendAlarmMessage(buffer); HalUARTWrite(0, "\r\n强制解除温湿度异常", 20); } else { HalUARTWrite(0, "\r\n无温湿度异常", 12); } } } // 处理LED控制命令 - Num2控制中断模块LED2 else if (strstr(command, "Num2Led")) { if (strstr(command, "on")) { HalLedSet(HAL_LED_2, HAL_LED_MODE_ON); gLED2State = 1; HalUARTWrite(0, "\r\nINT LED2 ON", 12); } else if (strstr(command, "off")) { HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); gLED2State = 0; HalUARTWrite(0, "\r\nINT LED2 OFF", 13); } else if (strstr(command, "relie")) { // 强制解除中断异常 if (gIntAlarm) { gIntAlarm = 0; gIntCount = 0; HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); gLED2State = 0; BuildForcedAlarmString(buffer, sizeof(buffer), "传感"); SampleApp_SendAlarmMessage(buffer); HalUARTWrite(0, "\r\n强制解除传感异常", 18); } else { HalUARTWrite(0, "\r\n无传感异常", 10); } } } // 处理全局解除命令 else if (strstr(command, "LedRile")) { // 解除所有报警并熄灭所有LED uint8 cleared = 0; if (gTempHumiAlarm) { gTempHumiAlarm = 0; HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF); gLED1State = 0; BuildForcedAlarmString(buffer, sizeof(buffer), "温湿度"); SampleApp_SendAlarmMessage(buffer); cleared = 1; } if (gIntAlarm) { gIntAlarm = 0; gIntCount = 0; HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); gLED2State = 0; BuildForcedAlarmString(buffer, sizeof(buffer), "传感"); SampleApp_SendAlarmMessage(buffer); cleared = 1; } if (cleared) { HalUARTWrite(0, "\r\n强制解除所有异常", 18); } else { HalUARTWrite(0, "\r\n无任何异常", 10); } } } /********************************************************************* * @fn BuildSensorDataString * @brief 构建传感器数据字符串:"42213361ljl huim:26 temp:45" */ void BuildSensorDataString(char *buf, uint8 bufSize, float temp, float humi) { if (bufSize < 50) { buf[0] = '\0'; return; } // 新格式:"42213361ljl huim:26 temp:45" sprintf(buf, "%s huim:%.0f temp:%.0f", STUDENT_ID_NAME, humi, temp); } /********************************************************************* * @fn BuildInterruptString * @brief 构建中断消息字符串 */ void BuildInterruptString(char *buf, uint8 bufSize) { if (bufSize < 50) { buf[0] = '\0'; return; } // 明确的中断消息 sprintf(buf, "%s %s interrupt triggered!", STUDENT_ID_NAME, SENSOR2_NAME); } /********************************************************************* * @fn BuildAlarmString * @brief 构建报警信息字符串 */ void BuildAlarmString(char *buf, uint8 bufSize, const char *alarmType, uint8 isReset) { if (bufSize < 50) { buf[0] = '\0'; return; } if (isReset) { sprintf(buf, "%s %s alarm cleared", STUDENT_ID_NAME, alarmType); } else { sprintf(buf, "%s %s alarm triggered!", STUDENT_ID_NAME, alarmType); } } /********************************************************************* * @fn BuildForcedAlarmString * @brief 构建强制解除报警信息字符串 */ void BuildForcedAlarmString(char *buf, uint8 bufSize, const char *alarmType) { if (bufSize < 50) { buf[0] = '\0'; return; } sprintf(buf, "%s %s alarm force-cleared!", STUDENT_ID_NAME, alarmType); } /********************************************************************* * @fn Delay */ void Delay(int n) { volatile int i, t; for(i = 0; i < 5; i++) for(t = 0; t < n; t++); } /********************************************************************* *********************************************************************/ 检查代码,为什么灯光控制和报警功能,均没有实现,给出解决方法,给出修改后的完整代码
07-02
一、系统分层功能 感知层:用实验箱的两个传感器模块 传感器 1:温湿度传感器,采集温度、湿度数据。 传感器 2:红外对射 ,采集触发状态。 网络层: Zigbee 通信:传感器 1、2 的数据,经 Zigbee 节点传给协调器,协调器通过串口发 PC 端。 数据处理:解析串口数据,分主题发 MQTT 网络,或存数据库 。 应用层:用 Python 做终端,实现界面、串口、数据库交互(可加 MQTT),完成这些功能: 二、具体功能 数据上传: 远程设备实时收传感器 1 数据,格式:学号姓名缩写+温度+湿度 。 远程设备实时收传感器 2 数据,格式:学号姓名缩写+传感器名+interrupt 。 Mysql 数据库:建不同数据表存两个传感器数据,表含 学号姓名缩写、传感器名、数据值、传感器状态 等字段 。 命令下发: 发 学号姓名缩写+Num1Led+on ,传感器 1 连的 Zigbee 模块 LED2 亮;发 ...+off 则灭 。 发 学号姓名缩写+Num2Led+on ,传感器 2 连的 Zigbee 模块 LED2 亮;发 ...+off 则灭 。 数据联动: 传感器 1:温度>25 且湿度>60,其连的 Zigbee 模块 LED2 闪烁,远程设备、数据库表显示 “温湿度异常”;恢复后显示 “异常解除” 。 传感器 2:触发超 5 次,其连的 Zigbee 模块 LED2 闪烁,远程设备、数据库表显示 “传感状态异常”;恢复后显示 “传感异常解除” 。 强制解除:发 学号姓名缩写+Num1Led+relie ,传感器 1 连的 LED2 停闪,设备和表显示 “强制异常解除温湿度” ;发 ...+Num2Led+relie 同理。 数据展示:Python 界面里,串口控制,实时显示传感器 1 的 学号姓名缩写、温度、湿度 数据,呈现底层传感器联动状态 。 #include <stdio.h> #include <string.h> #include "OSAL.h" #include "ZGlobals.h" #include "AF.h" #include "aps_groups.h" #include "ZDApp.h" #include "MT_UART.h" //???? #include "SampleApp.h" #include "SampleAppHw.h" #include "OnBoard.h" /* HAL */ #include "hal_lcd.h" #include "hal_led.h" #include "hal_key.h" #include "hal_uart.h" #include "hal_mcu.h" #include "sht11.h" // P1 interrupt vector value is already defined in ioCC2530.h // #define P1INT_VECTOR 0x7B // Commented out to avoid redefinition warning // Sensor type configuration: // Combined sensor: supports both temp/humidity and IR sensor functions // sht11 command activates temp/humidity sensor, interrupt command activates IR sensor //#define COMBINED_SENSOR // Single sensor configuration (optional): //#define TEMP_HUMIDITY_SENSOR // Temperature/humidity sensor only // Default: IR sensor only (no macro defined) /********************************************************************* * CONSTANTS */ /********************************************************************* * TYPEDEFS */ /********************************************************************* * GLOBAL VARIABLES */ // This list should be filled with Application specific Cluster IDs. const cId_t SampleApp_ClusterList[SAMPLEAPP_MAX_CLUSTERS] = { SAMPLEAPP_PERIODIC_CLUSTERID, SAMPLEAPP_FLASH_CLUSTERID, SAMPLEAPP_BUZZER_CLUSTERID, SAMPLEAPP_SENSOR_IDENTIFY_CLUSTERID, }; // Add function declarations at the top of the file, after other declarations void SetBuzzerStatus(uint8 status); void SampleApp_ProcessMTMessage(afIncomingMSGPacket_t *msg); void InitIRSensorInterrupt(void); void ProcessIRSensorInterrupt(void); void ProcessLED2Flash(void); // LED2闪烁处理函数 void PrintDeviceInfo(void); // 打印设备信息 void PrintHexBytes(const char* title, const char* data, uint8 len); // 十六进制打印辅助函数 const SimpleDescriptionFormat_t SampleApp_SimpleDesc = { SAMPLEAPP_ENDPOINT, // int Endpoint; SAMPLEAPP_PROFID, // uint16 AppProfId[2]; SAMPLEAPP_DEVICEID, // uint16 AppDeviceId[2]; SAMPLEAPP_DEVICE_VERSION, // int AppDevVer:4; SAMPLEAPP_FLAGS, // int AppFlags:4; SAMPLEAPP_MAX_CLUSTERS, // uint8 AppNumInClusters; (cId_t *)SampleApp_ClusterList, // uint8 *pAppInClusterList; SAMPLEAPP_MAX_CLUSTERS, // uint8 AppNumOutClusters; (cId_t *)SampleApp_ClusterList // uint8 *pAppOutClusterList; }; // This is the Endpoint/Interface description. It is defined here, but // filled-in in SampleApp_Init(). Another way to go would be to fill // in the structure here and make it a "const" (in code space). The // way it's defined in this sample app it is define in RAM. endPointDesc_t SampleApp_epDesc; // Add global variable to control temperature and humidity reading static uint8 g_bReadTempHumi = 0; // Add IR sensor status variable static uint8 g_IRSensorStatus = 0; // Add sensor type variable - configure this based on device type // For combined sensor nodes, set to SENSOR_TYPE_COMBINED // For temperature/humidity sensor nodes, set to SENSOR_TYPE_TEMP_HUMIDITY // For IR sensor nodes, set to SENSOR_TYPE_IR #ifdef COMBINED_SENSOR static uint8 g_SensorType = SENSOR_TYPE_COMBINED; #elif defined(TEMP_HUMIDITY_SENSOR) static uint8 g_SensorType = SENSOR_TYPE_TEMP_HUMIDITY; #else static uint8 g_SensorType = SENSOR_TYPE_IR; #endif // 添加全局变量,用于防止中断处理函数重入 static uint8 g_IRProcessingInProgress = 0; // 添加控制LED2闪烁的全局变量 static uint8 g_LED2FlashStatus = 0; // 0: 停止闪烁, 1: 闪烁中 // 定义命令字符串常量,避免硬编码字符串和在函数调用中重复创建 const char* CMD_NUM1LED_ON = "42213238YFC+Num1Led+on"; const char* CMD_NUM1LED_OFF = "42213238YFC+Num1Led+off"; const char* CMD_NUM2LED_ON = "42213238YFC+Num2Led+on"; const char* CMD_NUM2LED_OFF = "42213238YFC+Num2Led+off"; const char* CMD_ON = "on"; const char* CMD_OFF = "off"; const char* CMD_HT = "ht"; const char* CMD_HF = "hf"; const char* CMD_FLASH = "flash"; // 闪烁命令 const char* CMD_RELIE = "42213238YFC+Num1Led+relie"; // 停止闪烁命令 const char* CMD_SHUO = "shuo"; // 红外对射传感器闪烁命令 const char* CMD_IR_RELIE = "42213238YFC+Num2Led+relie"; // 红外对射传感器停止闪烁命令 /********************************************************************* * EXTERNAL VARIABLES */ /********************************************************************* * EXTERNAL FUNCTIONS */ /********************************************************************* * LOCAL VARIABLES */ uint8 SampleApp_TaskID; // Task ID for internal task/event processing // This variable will be received when // SampleApp_Init() is called. devStates_t SampleApp_NwkState; uint8 SampleApp_TransID; // This is the unique message ID (counter) afAddrType_t SampleApp_Periodic_DstAddr; afAddrType_t SampleApp_Flash_DstAddr; aps_Group_t SampleApp_Group; uint8 SampleAppPeriodicCounter = 0; uint8 SampleAppFlashCounter = 0; /********************************************************************* * LOCAL FUNCTIONS */ void SampleApp_HandleKeys( uint8 shift, uint8 keys ); void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pckt ); void SampleApp_SendPeriodicMessage( void ); void SampleApp_SendFlashMessage( uint16 flashTime ); /********************************************************************* * NETWORK LAYER CALLBACKS */ /********************************************************************* * PUBLIC FUNCTIONS */ /********************************************************************* * @fn SampleApp_Init * * @brief Initialization function for the Generic App Task. * This is called during initialization and should contain * any application specific initialization (ie. hardware * initialization/setup, table initialization, power up * notificaiton ... ). * * @param task_id - the ID assigned by OSAL. This ID should be * used to send messages and set timers. * * @return none */ void SampleApp_Init( uint8 task_id ) { SampleApp_TaskID = task_id; SampleApp_NwkState = DEV_INIT; SampleApp_TransID = 0; // Device hardware initialization can be added here or in main() (Zmain.c). // If the hardware is application specific - add it here. // If the hardware is other parts of the device add it in main(). // Initialize IR sensor interrupt InitIRSensorInterrupt(); #if defined ( BUILD_ALL_DEVICES ) // The "Demo" target is setup to have BUILD_ALL_DEVICES and HOLD_AUTO_START // We are looking at a jumper (defined in SampleAppHw.c) to be jumpered // together - if they are - we will start up a coordinator. Otherwise, // the device will start as a router. if ( readCoordinatorJumper() ) zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR; else zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER; #endif // BUILD_ALL_DEVICES #if defined ( HOLD_AUTO_START ) // HOLD_AUTO_START is a compile option that will surpress ZDApp // from starting the device and wait for the application to // start the device. ZDOInitDevice(0); #endif // Setup for the periodic message's destination address // Broadcast to everyone SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast; SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF; // Setup for the flash command's destination address - Group 1 SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup; SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP; // Fill out the endpoint description. SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_epDesc.task_id = &SampleApp_TaskID; SampleApp_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc; SampleApp_epDesc.latencyReq = noLatencyReqs; // Register the endpoint description with the AF afRegister( &SampleApp_epDesc ); // Register for all key events - This app will handle all key events RegisterForKeys( SampleApp_TaskID ); MT_UartRegisterTaskID( SampleApp_TaskID ); //add by 1305106 // By default, all devices start out in Group 1 SampleApp_Group.ID = 0x0001; osal_memcpy( SampleApp_Group.name, "Group 1", 7 ); aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); #if defined ( LCD_SUPPORTED ) HalLcdWriteString( "SampleApp", HAL_LCD_LINE_1 ); #endif // 打印设备类型和传感器类型信息 PrintDeviceInfo(); } /********************************************************************* * @fn SampleApp_ProcessEvent * * @brief Generic Application Task event processor. This function * is called to process all events for the task. Events * include timers, messages and any other user defined events. * * @param task_id - The OSAL assigned task ID. * @param events - events to process. This is a bit map and can * contain more than one event. * * @return none */ uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) { afIncomingMSGPacket_t *MSGpkt; (void)task_id; // Intentionally unreferenced parameter if ( events & SYS_EVENT_MSG ) { MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); while ( MSGpkt ) { switch ( MSGpkt->hdr.event ) { // Received when a key is pressed case KEY_CHANGE: SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys ); break; // Received when a messages is received (OTA) for this endpoint case AF_INCOMING_MSG_CMD: SampleApp_MessageMSGCB( MSGpkt ); break;; case SPI_INCOMING_ZAPP_DATA: SampleApp_ProcessMTMessage(MSGpkt); MT_UartAppFlowControl (MT_UART_ZAPP_RX_READY); break; // Received whenever the device changes state in the network case ZDO_STATE_CHANGE: SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status); Sht11Init(); if ( (SampleApp_NwkState == DEV_ZB_COORD) || (SampleApp_NwkState == DEV_ROUTER) || (SampleApp_NwkState == DEV_END_DEVICE) ) { // Start sending the periodic message in a regular interval. HalLedSet(HAL_LED_1, HAL_LED_MODE_ON); osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT ); } else { // Device is no longer in the network } break; default: break; } osal_msg_deallocate( (uint8 *)MSGpkt ); MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); } return (events ^ SYS_EVENT_MSG); // return unprocessed events } // Send a message out - This event is generated by a timer // (setup in SampleApp_Init()). if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) { SampleApp_SendPeriodicMessage(); // Send the periodic message // Setup to send message again in normal period (+ a little jitter) osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) ); return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT); // return unprocessed events } // Process IR sensor interrupt event if ( events & SAMPLEAPP_SEND_SENSOR_INT_EVT ) { ProcessIRSensorInterrupt(); return (events ^ SAMPLEAPP_SEND_SENSOR_INT_EVT); } // 处理LED2闪烁事件 if ( events & SAMPLEAPP_LED2_FLASH_EVT ) { // 添加调试输出 char buf[100]; sprintf(buf, "处理LED2闪烁事件, g_LED2FlashStatus=%d, g_SensorType=%d\r\n", g_LED2FlashStatus, g_SensorType); HalUARTWrite(0, (uint8*)buf, strlen(buf)); // 检查是否是温湿度传感器或红外对射传感器,且闪烁标志为1 if (g_LED2FlashStatus == 1 && (g_SensorType == SENSOR_TYPE_TEMP_HUMIDITY || g_SensorType == SENSOR_TYPE_IR)) { // 执行闪烁处理函数 ProcessLED2Flash(); // 不需要在这里设置下一次闪烁计时器,已在ProcessLED2Flash函数中处理 } else { // g_LED2FlashStatus不为1时,确保LED2关闭 if (g_LED2FlashStatus == 0) { HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); HalUARTWrite(0, (uint8*)"闪烁标志为0,停止闪烁并关闭LED2\r\n", 32); } } return (events ^ SAMPLEAPP_LED2_FLASH_EVT); } return 0; // Discard unknown events } /********************************************************************* * Event Generation Functions */ /********************************************************************* * @fn SampleApp_HandleKeys * * @brief Handles all key events for this device. * * @param shift - true if in shift/alt. * @param keys - bit field for key events. Valid entries: * HAL_KEY_SW_2 * HAL_KEY_SW_1 * * @return none */ void SampleApp_HandleKeys( uint8 shift, uint8 keys ) { (void)shift; // Intentionally unreferenced parameter if ( keys & HAL_KEY_SW_6 ) { /* This key sends the Flash Command is sent to Group 1. * This device will not receive the Flash Command from this * device (even if it belongs to group 1). */ SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION ); } if ( keys & HAL_KEY_SW_2 ) { /* The Flashr Command is sent to Group 1. * This key toggles this device in and out of group 1. * If this device doesn't belong to group 1, this application * will not receive the Flash command sent to group 1. */ aps_Group_t *grp; grp = aps_FindGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP ); if ( grp ) { // Remove from the group aps_RemoveGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP ); } else { // Add to the flash group aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); } } } /********************************************************************* * LOCAL FUNCTIONS */ /********************************************************************* * @fn SampleApp_MessageMSGCB * * @brief Data message processor callback. This function processes * any incoming data - probably from other devices. So, based * on cluster ID, perform the intended action. * * @param none * * @return none */ void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) { uint16 flashTime; uint8 *buf; switch(pkt->clusterId) { case SAMPLEAPP_PERIODIC_CLUSTERID: buf = pkt->cmd.Data; if(zgDeviceLogicalType == ZG_DEVICETYPE_COORDINATOR) { // Coordinator received data from end device if(pkt->cmd.DataLength == 4 && buf[0] <= 100) { // Format and print temperature data char tempStr[50]; sprintf(tempStr, "42213238YFC+温湿度传感器+温度:%d.%d C+湿度:%d.%d%%\r\n", buf[0], buf[1], buf[2], buf[3]); HalUARTWrite(0, (uint8*)tempStr, strlen(tempStr)); } else if(pkt->cmd.DataLength == 2 && buf[0] == 0x02) { // Process IR sensor data char irStr[50]; if(buf[1] == 0x01) { sprintf(irStr, "IR Sensor Node: Obstacle Detected!\r\n"); } else { sprintf(irStr, "IR Sensor Node: No Obstacle\r\n"); } HalUARTWrite(0, (uint8*)irStr, strlen(irStr)); } else if(pkt->cmd.DataLength == 3 && buf[0] == 0x03) { // Process interrupt message from end device if(buf[1] == 0x01) { // Coordinator prints the message and also blinks LED2 HalUARTWrite(0, (uint8*)"42213238YFC+红外对射传感器+interrupt\r\n", 36); // Flash LED2 10 times on coordinator as well HalLedBlink(HAL_LED_2, 10, 50, 200); } } else if(pkt->cmd.DataLength == 2 && buf[0] == 0x04) { // Process sensor identification response uint8 sensorType = buf[1]; char coordMsg[80]; uint16 srcAddr = pkt->srcAddr.addr.shortAddr; if(sensorType == SENSOR_TYPE_TEMP_HUMIDITY) { sprintf(coordMsg, "Device 0x%04X: Temperature/Humidity sensor identified and LED2 activated\r\n", srcAddr); HalUARTWrite(0, (uint8*)coordMsg, strlen(coordMsg)); } else if(sensorType == SENSOR_TYPE_IR) { sprintf(coordMsg, "Device 0x%04X: IR sensor identified and LED2 activated\r\n", srcAddr); HalUARTWrite(0, (uint8*)coordMsg, strlen(coordMsg)); } } } else { // End device received command from coordinator if(pkt->cmd.DataLength == 1) { if(buf[0] == 0x01) { // Start temperature reading g_bReadTempHumi = 1; osal_start_timerEx(SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, 1000); } else { // Stop temperature reading g_bReadTempHumi = 0; osal_stop_timerEx(SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT); } } else if(pkt->cmd.DataLength == 2 && buf[0] == 0x10) { // 处理协调器转发的闪烁命令,仅终端设备响应 if(zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR && g_SensorType == SENSOR_TYPE_TEMP_HUMIDITY) { if(buf[1] == 0x01) { // 启动LED2闪烁 g_LED2FlashStatus = 1; osal_set_event(SampleApp_TaskID, SAMPLEAPP_LED2_FLASH_EVT); // 添加调试输出 HalUARTWrite(0, (uint8*)"接收到闪烁命令,启动LED2闪烁\r\n", 30); } else { // 停止LED2闪烁 g_LED2FlashStatus = 0; HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); // 明确停止闪烁定时器 osal_stop_timerEx(SampleApp_TaskID, SAMPLEAPP_LED2_FLASH_EVT); // 添加调试输出 HalUARTWrite(0, (uint8*)"接收到停止命令,停止LED2闪烁\r\n", 30); } } } // 处理协调器转发的红外对射传感器闪烁命令 else if(pkt->cmd.DataLength == 2 && buf[0] == 0x11) { // 处理协调器转发的红外对射传感器闪烁命令,仅终端设备响应 if(zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR && g_SensorType == SENSOR_TYPE_IR) { if(buf[1] == 0x01) { // 启动红外对射传感器LED2闪烁 g_LED2FlashStatus = 1; osal_set_event(SampleApp_TaskID, SAMPLEAPP_LED2_FLASH_EVT); // 添加调试输出 HalUARTWrite(0, (uint8*)"接收到红外对射传感器闪烁命令,启动LED2闪烁\r\n", 42); } else { // 停止红外对射传感器LED2闪烁 g_LED2FlashStatus = 0; HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); // 明确停止闪烁定时器 osal_stop_timerEx(SampleApp_TaskID, SAMPLEAPP_LED2_FLASH_EVT); // 添加调试输出 HalUARTWrite(0, (uint8*)"接收到红外对射传感器停止命令,停止LED2闪烁\r\n", 42); } } } } break; case SAMPLEAPP_FLASH_CLUSTERID: flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2]); HalLedBlink(HAL_LED_4, 4, 50, (flashTime / 4)); break; case SAMPLEAPP_BUZZER_CLUSTERID: SetBuzzerStatus(pkt->cmd.Data[0]); break; case SAMPLEAPP_SENSOR_IDENTIFY_CLUSTERID: // Handle sensor identification requests if(zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR) { // This is an end device, check if we should respond uint8 cmd = pkt->cmd.Data[0]; if(cmd == SENSOR_IDENTIFY_CMD_SHT11 && (g_SensorType == SENSOR_TYPE_TEMP_HUMIDITY || g_SensorType == SENSOR_TYPE_COMBINED)) { // This is a temperature/humidity sensor or combined sensor responding to sht11 command // Turn on LED2 and send identification response HalLedSet(HAL_LED_2, HAL_LED_MODE_ON); // Send identification response to coordinator uint8 response[2]; response[0] = 0x04; // Sensor identification response // For combined sensor responding to sht11, report as temp/humidity sensor response[1] = SENSOR_TYPE_TEMP_HUMIDITY; AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 2, response, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } else if(cmd == SENSOR_IDENTIFY_CMD_INTERRUPT && (g_SensorType == SENSOR_TYPE_IR || g_SensorType == SENSOR_TYPE_COMBINED)) { // This is an IR sensor or combined sensor responding to interrupt command // Turn on LED2 and send identification response HalLedSet(HAL_LED_2, HAL_LED_MODE_ON); // Send identification response to coordinator uint8 response[2]; response[0] = 0x04; // Sensor identification response // For combined sensor responding to interrupt, report as IR sensor response[1] = SENSOR_TYPE_IR; AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 2, response, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } else if(cmd == 0x05 && (g_SensorType == SENSOR_TYPE_TEMP_HUMIDITY || g_SensorType == SENSOR_TYPE_COMBINED)) { // Turn off LED2 for temperature/humidity sensors HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); } else if(cmd == 0x06 && (g_SensorType == SENSOR_TYPE_IR || g_SensorType == SENSOR_TYPE_COMBINED)) { // Turn off LED2 for IR sensors HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); } } break; } } /********************************************************************* * @fn SampleApp_SendPeriodicMessage * * @brief Send the periodic message. * * @param none * * @return none */ void SampleApp_SendPeriodicMessage(void) { if(g_bReadTempHumi) { uint8 temp_int, temp_dec, humi_int, humi_dec; char buf[50]; float humi, temp; // Initialize SHT11 sensor Sht11Init(); if(GetHumiAndTemp(&humi, &temp) == 0) { // Convert float to integer parts temp_int = (uint8)temp; temp_dec = (uint8)((temp - temp_int) * 10); humi_int = (uint8)humi; humi_dec = (uint8)((humi - humi_int) * 10); // Format the message sprintf(buf, "42213238YFC+温湿度传感器+温度:%d.%d C+湿度:%d.%d%%\r\n", temp_int, temp_dec, humi_int, humi_dec); // Send to UART HalUARTWrite(0, (uint8*)buf, strlen(buf)); // Prepare network data packet buf[0] = temp_int; buf[1] = temp_dec; buf[2] = humi_int; buf[3] = humi_dec; // Send data to network and check result afStatus_t status = AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 4, // Only send 4 bytes of data (uint8*)buf, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); // 只记录错误但不中断流程,保持原有功能不变 if (status != afStatus_SUCCESS) { // 可以在这里添加错误处理代码,如重试或记录日志 // 但不要中断原有功能流程 } } // Restart timer for next reading osal_start_timerEx(SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, 2000); // Read every 2 seconds } } /********************************************************************* * @fn SampleApp_SendFlashMessage * * @brief Send the flash message to group 1. * * @param flashTime - in milliseconds * * @return none */ void SampleApp_SendFlashMessage( uint16 flashTime ){ uint8 buffer[3]; buffer[0] = (uint8)(SampleAppFlashCounter++); buffer[1] = LO_UINT16( flashTime ); buffer[2] = HI_UINT16( flashTime ); if ( AF_DataRequest( &SampleApp_Flash_DstAddr, &SampleApp_epDesc, SAMPLEAPP_FLASH_CLUSTERID, 3, buffer, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) { } else { // Error occurred in request to send. } } void SampleApp_ProcessMTMessage(afIncomingMSGPacket_t *msg) { // 增加安全检查,确保msg指针有效 if(msg == NULL) { return; } const char *msgPtr = ((const char *)msg+2); uint8 status; // 调试输出,打印收到的命令 HalUARTWrite(0, (uint8*)"收到命令: ", 10); HalUARTWrite(0, (uint8*)msgPtr, strlen(msgPtr)); HalUARTWrite(0, (uint8*)"\r\n", 2); // 打印命令的十六进制值,帮助调试 PrintHexBytes("命令十六进制", msgPtr, strlen(msgPtr)); // 打印预期命令常量进行比较 char buf[100]; sprintf(buf, "预期relie命令: %s, 长度: %d\r\n", CMD_RELIE, strlen(CMD_RELIE)); HalUARTWrite(0, (uint8*)buf, strlen(buf)); // 打印预期命令的十六进制值 PrintHexBytes("预期十六进制", CMD_RELIE, strlen(CMD_RELIE)); // 使用更安全的字符串比较方式 if(strncmp(msgPtr, CMD_NUM1LED_OFF, strlen(CMD_NUM1LED_OFF)) == 0) { // Send command to turn off LED2 for temperature/humidity sensors uint8 cmd[2]; cmd[0] = 0x05; // LED control command cmd[1] = 0x00; // Turn off LED2 for temp/humidity sensors AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_SENSOR_IDENTIFY_CLUSTERID, 2, cmd, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } else if(strncmp(msgPtr, CMD_NUM2LED_OFF, strlen(CMD_NUM2LED_OFF)) == 0) { // Send command to turn off LED2 for IR sensors uint8 cmd[2]; cmd[0] = 0x06; // LED control command cmd[1] = 0x00; // Turn off LED2 for IR sensors AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_SENSOR_IDENTIFY_CLUSTERID, 2, cmd, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } else if(strncmp(msgPtr, CMD_ON, strlen(CMD_ON)) == 0) { status = 0x01; AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_BUZZER_CLUSTERID, 1, &status, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } else if(strncmp(msgPtr, CMD_OFF, strlen(CMD_OFF)) == 0) { status = 0x00; AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_BUZZER_CLUSTERID, 1, &status, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } else if(strncmp(msgPtr, CMD_HT, strlen(CMD_HT)) == 0) { // Forward the command to end device uint8 cmd = 0x01; // Command for starting temperature reading AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 1, &cmd, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } else if(strncmp(msgPtr, CMD_HF, strlen(CMD_HF)) == 0) { // Forward the command to end device uint8 cmd = 0x00; // Command for stopping temperature reading AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 1, &cmd, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } else if(strncmp(msgPtr, CMD_NUM1LED_ON, strlen(CMD_NUM1LED_ON)) == 0) { // Send sensor identification request for temperature/humidity sensors uint8 cmd = SENSOR_IDENTIFY_CMD_SHT11; AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_SENSOR_IDENTIFY_CLUSTERID, 1, &cmd, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } else if(strncmp(msgPtr, CMD_NUM2LED_ON, strlen(CMD_NUM2LED_ON)) == 0) { // Send sensor identification request for IR sensors uint8 cmd = SENSOR_IDENTIFY_CMD_INTERRUPT; AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_SENSOR_IDENTIFY_CLUSTERID, 1, &cmd, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } else if(strncmp(msgPtr, CMD_FLASH, strlen(CMD_FLASH)) == 0) { // 添加调试输出 HalUARTWrite(0, (uint8*)"收到flash命令\r\n", 14); // 只有温湿度传感器模块响应flash命令 if (g_SensorType == SENSOR_TYPE_TEMP_HUMIDITY) { // 添加调试输出 HalUARTWrite(0, (uint8*)"当前是温湿度传感器模块\r\n", 25); if (zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR) { // 只有终端设备执行闪烁,协调器不闪烁 // 启动LED2闪烁 g_LED2FlashStatus = 1; // 触发闪烁事件,立即开始 osal_set_event(SampleApp_TaskID, SAMPLEAPP_LED2_FLASH_EVT); // 添加调试输出 HalUARTWrite(0, (uint8*)"终端设备开始LED2闪烁\r\n", 24); } else { // 协调器接收到flash命令时,转发给所有设备 uint8 cmd[2]; cmd[0] = 0x10; // 自定义的flash命令标识 cmd[1] = 0x01; // 开始闪烁 // 添加调试输出 HalUARTWrite(0, (uint8*)"协调器转发flash命令到网络\r\n", 27); AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 2, cmd, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } } else { // 添加调试输出 HalUARTWrite(0, (uint8*)"不是温湿度传感器模块,忽略命令\r\n", 32); } } else if(strncmp(msgPtr, CMD_RELIE, strlen(CMD_RELIE)) == 0) { // 添加调试输出 HalUARTWrite(0, (uint8*)"匹配到relie命令\r\n", 17); // 只有温湿度传感器模块响应relie命令 if (g_SensorType == SENSOR_TYPE_TEMP_HUMIDITY) { // 添加调试输出 HalUARTWrite(0, (uint8*)"当前是温湿度传感器模块\r\n", 25); if (zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR) { // 只有终端设备执行停止闪烁,协调器不处理 // 停止LED2闪烁 g_LED2FlashStatus = 0; // 关闭LED2 HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); // 明确停止闪烁定时器 osal_stop_timerEx(SampleApp_TaskID, SAMPLEAPP_LED2_FLASH_EVT); // 添加调试输出 HalUARTWrite(0, (uint8*)"终端设备停止LED2闪烁\r\n", 24); } else { // 协调器接收到relie命令时,转发给所有设备 uint8 cmd[2]; cmd[0] = 0x10; // 自定义的flash命令标识 cmd[1] = 0x00; // 停止闪烁 // 添加调试输出 HalUARTWrite(0, (uint8*)"协调器转发停止闪烁命令到网络\r\n", 31); AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 2, cmd, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } } else { // 添加调试输出 HalUARTWrite(0, (uint8*)"不是温湿度传感器模块,忽略命令\r\n", 32); } } // 添加对红外对射传感器停止闪烁命令的处理 else if(strncmp(msgPtr, CMD_IR_RELIE, strlen(CMD_IR_RELIE)) == 0) { // 添加调试输出 HalUARTWrite(0, (uint8*)"匹配到红外对射停止闪烁命令\r\n", 29); // 只有红外对射传感器模块响应停止闪烁命令 if (g_SensorType == SENSOR_TYPE_IR) { // 添加调试输出 HalUARTWrite(0, (uint8*)"当前是红外对射传感器模块\r\n", 27); if (zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR) { // 只有终端设备执行停止闪烁,协调器不处理 // 停止LED2闪烁 g_LED2FlashStatus = 0; // 关闭LED2 HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); // 明确停止闪烁定时器 osal_stop_timerEx(SampleApp_TaskID, SAMPLEAPP_LED2_FLASH_EVT); // 添加调试输出 HalUARTWrite(0, (uint8*)"红外对射终端设备停止LED2闪烁\r\n", 31); } else { // 协调器接收到停止闪烁命令时,转发给所有设备 uint8 cmd[2]; cmd[0] = 0x11; // 自定义的红外闪烁命令标识 cmd[1] = 0x00; // 停止闪烁 // 添加调试输出 HalUARTWrite(0, (uint8*)"协调器转发红外对射停止闪烁命令到网络\r\n", 38); AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 2, cmd, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } } else { // 添加调试输出 HalUARTWrite(0, (uint8*)"不是红外对射传感器模块,忽略命令\r\n", 34); } } // 尝试直接匹配红外对射传感器停止闪烁命令 else if(strcmp(msgPtr, "42213238YFC+Num2Led+relie") == 0) { // 添加调试输出 HalUARTWrite(0, (uint8*)"直接匹配到红外对射停止闪烁命令\r\n", 33); // 只有红外对射传感器模块响应停止闪烁命令 if (g_SensorType == SENSOR_TYPE_IR) { if (zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR) { // 只有终端设备执行停止闪烁,协调器不处理 // 停止LED2闪烁 g_LED2FlashStatus = 0; // 关闭LED2 HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); // 明确停止闪烁定时器 osal_stop_timerEx(SampleApp_TaskID, SAMPLEAPP_LED2_FLASH_EVT); // 添加调试输出 HalUARTWrite(0, (uint8*)"红外对射终端设备直接停止LED2闪烁\r\n", 35); } else { // 协调器接收到停止闪烁命令时,转发给所有设备 uint8 cmd[2]; cmd[0] = 0x11; // 自定义的红外闪烁命令标识 cmd[1] = 0x00; // 停止闪烁 // 添加调试输出 HalUARTWrite(0, (uint8*)"协调器直接转发红外对射停止闪烁命令到网络\r\n", 42); AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 2, cmd, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } } } // 尝试另一种方式匹配温湿度传感器的relie命令(恢复原有逻辑) else if(strcmp(msgPtr, "42213238YFC+Num1Led+relie") == 0) { // 添加调试输出 HalUARTWrite(0, (uint8*)"直接匹配到温湿度传感器relie命令\r\n", 33); // 只有温湿度传感器模块响应relie命令 if (g_SensorType == SENSOR_TYPE_TEMP_HUMIDITY) { if (zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR) { // 只有终端设备执行停止闪烁,协调器不处理 // 停止LED2闪烁 g_LED2FlashStatus = 0; // 关闭LED2 HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); // 明确停止闪烁定时器 osal_stop_timerEx(SampleApp_TaskID, SAMPLEAPP_LED2_FLASH_EVT); // 添加调试输出 HalUARTWrite(0, (uint8*)"温湿度传感器终端设备直接停止LED2闪烁\r\n", 39); } else { // 协调器接收到relie命令时,转发给所有设备 uint8 cmd[2]; cmd[0] = 0x10; // 自定义的flash命令标识 cmd[1] = 0x00; // 停止闪烁 // 添加调试输出 HalUARTWrite(0, (uint8*)"协调器直接转发温湿度传感器停止闪烁命令到网络\r\n", 46); AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 2, cmd, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } } } // 添加对shuo命令的处理 - 红外对射传感器LED闪烁命令 else if(strncmp(msgPtr, CMD_SHUO, strlen(CMD_SHUO)) == 0) { // 添加调试输出 HalUARTWrite(0, (uint8*)"收到shuo命令\r\n", 14); // 只有红外对射传感器模块响应shuo命令 if (g_SensorType == SENSOR_TYPE_IR) { // 添加调试输出 HalUARTWrite(0, (uint8*)"当前是红外对射传感器模块\r\n", 27); if (zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR) { // 只有终端设备执行闪烁,协调器不闪烁 // 启动LED2闪烁 g_LED2FlashStatus = 1; // 触发闪烁事件,立即开始 osal_set_event(SampleApp_TaskID, SAMPLEAPP_LED2_FLASH_EVT); // 添加调试输出 HalUARTWrite(0, (uint8*)"红外对射终端设备开始LED2闪烁\r\n", 30); } else { // 协调器接收到shuo命令时,转发给所有设备 uint8 cmd[2]; cmd[0] = 0x11; // 自定义的红外闪烁命令标识,与温湿度传感器区分 cmd[1] = 0x01; // 开始闪烁 // 添加调试输出 HalUARTWrite(0, (uint8*)"协调器转发shuo命令到网络\r\n", 27); AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 2, cmd, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } } else { // 添加调试输出 HalUARTWrite(0, (uint8*)"不是红外对射传感器模块,忽略命令\r\n", 34); } } } // Initialize IR sensor interrupt function void InitIRSensorInterrupt(void) { // Set P1_2 as input pin P1DIR &= ~BV(2); // Configure P1_2 as input P1SEL &= ~BV(2); // Set as general I/O, not peripheral function // Configure P1_2 as pull-up input P1INP &= ~BV(2); // Set as tri-state input P2INP &= ~BV(5); // Clear P1 port pull-down setting, configure as pull-up // Read current status g_IRSensorStatus = (P1 & BV(2)) ? 0 : 1; // Set P1_2 as falling edge triggered PICTL |= BV(1); // P1 port uses falling edge trigger (PICTL.P1ICON = 1) // Enable P1_2 interrupt P1IEN |= BV(2); // Enable P1_2 interrupt function // Clear possible interrupt flags P1IFG &= ~BV(2); // Enable P1 port interrupt IEN2 |= BV(4); // Enable P1 port interrupt (IEN2.P1IE = 1) } // Process IR sensor interrupt function void ProcessIRSensorInterrupt(void) { // 简单的重入保护:如果已经在处理中,则退出 if(g_IRProcessingInProgress) { return; } g_IRProcessingInProgress = 1; // 设置处理中标志 // Read current status uint8 currentStatus = (P1 & BV(2)) ? 0 : 1; // For end devices, flash LED2 10 times and send interrupt message to coordinator if (zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR) { // Flash LED2 10 times on end device only HalUARTWrite(0, (uint8*)"42213238YFC+红外对射传感器+interrupt\r\n", 36); HalLedBlink(HAL_LED_2, 10, 50, 200); uint8 buf[3]; buf[0] = 0x03; // Indicates this is an interrupt event message buf[1] = 0x01; // Interrupt occurred buf[2] = currentStatus; // Current sensor status AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 3, (uint8*)buf, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } // Status changed if (currentStatus != g_IRSensorStatus) { g_IRSensorStatus = currentStatus; // Send status to coordinator if (zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR) { uint8 buf[2]; buf[0] = 0x02; // Indicates this is IR sensor data buf[1] = g_IRSensorStatus; AF_DataRequest(&SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 2, (uint8*)buf, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); } } // Re-enable interrupt after processing // Clear interrupt flag P1IFG &= ~BV(2); // Re-enable interrupt P1IEN |= BV(2); g_IRProcessingInProgress = 0; // 清除处理中标志 } // LED2闪烁处理函数 void ProcessLED2Flash(void) { // 添加调试输出 HalUARTWrite(0, (uint8*)"执行LED2闪烁处理函数\r\n", 22); // 判断是温湿度传感器还是红外对射传感器 if (zgDeviceLogicalType != ZG_DEVICETYPE_COORDINATOR) { // 温湿度传感器模块执行闪烁 if (g_SensorType == SENSOR_TYPE_TEMP_HUMIDITY && g_LED2FlashStatus == 1) { // 添加调试输出 HalUARTWrite(0, (uint8*)"温湿度传感器符合条件,切换LED2状态\r\n", 35); // 切换LED2状态 (开/关) if ((HalLedGetState() & HAL_LED_2) == 0) { HalLedSet(HAL_LED_2, HAL_LED_MODE_ON); HalUARTWrite(0, (uint8*)"温湿度传感器LED2打开\r\n", 22); } else { HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); HalUARTWrite(0, (uint8*)"温湿度传感器LED2关闭\r\n", 22); } // 继续闪烁,500ms后再次触发 osal_start_timerEx(SampleApp_TaskID, SAMPLEAPP_LED2_FLASH_EVT, 500); } // 红外对射传感器模块执行闪烁 else if (g_SensorType == SENSOR_TYPE_IR && g_LED2FlashStatus == 1) { // 添加调试输出 HalUARTWrite(0, (uint8*)"红外对射传感器符合条件,切换LED2状态\r\n", 37); // 切换LED2状态 (开/关) if ((HalLedGetState() & HAL_LED_2) == 0) { HalLedSet(HAL_LED_2, HAL_LED_MODE_ON); HalUARTWrite(0, (uint8*)"红外对射传感器LED2打开\r\n", 24); } else { HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); HalUARTWrite(0, (uint8*)"红外对射传感器LED2关闭\r\n", 24); } // 继续闪烁,300ms后再次触发(红外传感器闪烁频率比温湿度传感器快一些) osal_start_timerEx(SampleApp_TaskID, SAMPLEAPP_LED2_FLASH_EVT, 300); } else { // LED2闪烁状态为0或传感器类型不匹配,不执行闪烁 if (g_LED2FlashStatus == 0) { HalUARTWrite(0, (uint8*)"闪烁状态为0,不执行LED2闪烁\r\n", 29); // 确保LED2处于关闭状态 HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF); } else { // 传感器类型不匹配 HalUARTWrite(0, (uint8*)"传感器类型不匹配,不执行LED2闪烁\r\n", 33); } } } else { // 协调器不执行闪烁 HalUARTWrite(0, (uint8*)"协调器不执行LED2闪烁\r\n", 22); } } // Modify P1 interrupt handler related code, add P1 interrupt service routine HAL_ISR_FUNCTION(halP1Isr, P1INT_VECTOR) { if (P1IFG & BV(2)) { // Clear interrupt flag P1IFG &= ~BV(2); // Notify application to process interrupt via OSAL event osal_set_event(SampleApp_TaskID, SAMPLEAPP_SEND_SENSOR_INT_EVT); } // Clear P1 port interrupt flag P1IF = 0; } // Modify SetBuzzerStatus function to use another pin (P1_0) as buzzer output void SetBuzzerStatus(uint8 status) { if(status == 0x01) { P1_0 = 1; // Use P1_0 as buzzer control pin (active high) } else { P1_0 = 0; // Turn off buzzer } } void PrintDeviceInfo(void) { char buf[80]; // 打印设备类型信息 if(zgDeviceLogicalType == ZG_DEVICETYPE_COORDINATOR) { sprintf(buf, "设备类型: 协调器 (ZG_DEVICETYPE_COORDINATOR)\r\n"); } else if(zgDeviceLogicalType == ZG_DEVICETYPE_ROUTER) { sprintf(buf, "设备类型: 路由器 (ZG_DEVICETYPE_ROUTER)\r\n"); } else if(zgDeviceLogicalType == ZG_DEVICETYPE_ENDDEVICE) { sprintf(buf, "设备类型: 终端设备 (ZG_DEVICETYPE_ENDDEVICE)\r\n"); } else { sprintf(buf, "设备类型: 未知 (%d)\r\n", zgDeviceLogicalType); } HalUARTWrite(0, (uint8*)buf, strlen(buf)); // 打印传感器类型信息 if(g_SensorType == SENSOR_TYPE_TEMP_HUMIDITY) { sprintf(buf, "传感器类型: 温湿度传感器 (SENSOR_TYPE_TEMP_HUMIDITY)\r\n"); } else if(g_SensorType == SENSOR_TYPE_IR) { sprintf(buf, "传感器类型: 红外传感器 (SENSOR_TYPE_IR)\r\n"); } else if(g_SensorType == SENSOR_TYPE_COMBINED) { sprintf(buf, "传感器类型: 组合传感器 (SENSOR_TYPE_COMBINED)\r\n"); } else { sprintf(buf, "传感器类型: 未知 (%d)\r\n", g_SensorType); } HalUARTWrite(0, (uint8*)buf, strlen(buf)); // 打印编译时定义的宏 #ifdef TEMP_HUMIDITY_SENSOR sprintf(buf, "宏定义: TEMP_HUMIDITY_SENSOR 已定义\r\n"); #else sprintf(buf, "宏定义: TEMP_HUMIDITY_SENSOR 未定义\r\n"); #endif HalUARTWrite(0, (uint8*)buf, strlen(buf)); #ifdef COMBINED_SENSOR sprintf(buf, "宏定义: COMBINED_SENSOR 已定义\r\n"); #else sprintf(buf, "宏定义: COMBINED_SENSOR 未定义\r\n"); #endif HalUARTWrite(0, (uint8*)buf, strlen(buf)); } // 辅助函数,将字符串以十六进制格式打印出来,帮助调试 void PrintHexBytes(const char* title, const char* data, uint8 len) { char buf[200]; uint8 offset = 0; uint8 i; // 打印标题 offset = sprintf(buf, "%s: ", title); // 打印十六进制值 for (i = 0; i < len && offset < 190; i++) { offset += sprintf(buf + offset, "%02X ", (uint8)data[i]); } sprintf(buf + offset, "\r\n"); HalUARTWrite(0, (uint8*)buf, strlen(buf)); } /********************************************************************* *********************************************************************/ 根据要求和代码,实现相关功能,给出修改后的完整代码
06-28
/************************************************************************************************** Filename: SampleApp.h Revised: $Date: 2007-10-27 17:22:23 -0700 (Sat, 27 Oct 2007) $ Revision: $Revision: 15795 $ Description: This file contains the Sample Application definitions. Copyright 2007 Texas Instruments Incorporated. All rights reserved. IMPORTANT: Your use of this Software is limited to those specific rights granted under the terms of a software license agreement between the user who downloaded the software, his/her employer (which must be your employer) and Texas Instruments Incorporated (the "License"). You may not use this Software unless you agree to abide by the terms of the License. The License limits your use, and you acknowledge, that the Software may not be modified, copied or distributed unless embedded on a Texas Instruments microcontroller or used solely and exclusively in conjunction with a Texas Instruments radio frequency transceiver, which is integrated into your product. Other than for the foregoing purpose, you may not use, reproduce, copy, prepare derivative works of, modify, distribute, perform, display or sell this Software and/or its documentation for any purpose. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED 揂S IS?WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. Should you have any questions regarding your right to use this Software, contact Texas Instruments Incorporated at www.TI.com. **************************************************************************************************/ #ifndef SAMPLEAPP_H #define SAMPLEAPP_H #ifdef __cplusplus extern "C" { #endif /********************************************************************* * INCLUDES */ #include "ZComDef.h" /********************************************************************* * CONSTANTS */ // These constants are only for example and should be changed to the // device's needs #define SAMPLEAPP_ENDPOINT 20 #define SAMPLEAPP_PROFID 0x0F08 #define SAMPLEAPP_DEVICEID 0x0001 #define SAMPLEAPP_DEVICE_VERSION 0 #define SAMPLEAPP_FLAGS 0 #define SAMPLEAPP_MAX_CLUSTERS 2 #define SAMPLEAPP_PERIODIC_CLUSTERID 1 #define SAMPLEAPP_FLASH_CLUSTERID 2 #define SAMPLEAPP_LEDCTL_CLUSTERID 3 // Send Message Timeout #define SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT 5000 // Every 5 seconds // Application Events (OSAL) - These are bit weighted definitions. #define SAMPLEAPP_SEND_PERIODIC_MSG_EVT 0x0001 // Group ID for Flash Command #define SAMPLEAPP_FLASH_GROUP 0x0001 // Flash Command Duration - in milliseconds #define SAMPLEAPP_FLASH_DURATION 1000 /********************************************************************* * MACROS */ /********************************************************************* * FUNCTIONS */ /* * Task Initialization for the Generic Application */ extern void SampleApp_Init( uint8 task_id ); /* * Task Event Processor for the Generic Application */ extern UINT16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ); /********************************************************************* *********************************************************************/ #ifdef __cplusplus } #endif #endif /* SAMPLEAPP_H */ /************************************************************************************************** Filename: SampleApp.c Revised: $Date: 2009-03-18 15:56:27 -0700 (Wed, 18 Mar 2009) $ Revision: $Revision: 19453 $ Description: Sample Application (no Profile). Copyright 2007 Texas Instruments Incorporated. All rights reserved. IMPORTANT: Your use of this Software is limited to those specific rights granted under the terms of a software license agreement between the user who downloaded the software, his/her employer (which must be your employer) and Texas Instruments Incorporated (the "License"). You may not use this Software unless you agree to abide by the terms of the License. The License limits your use, and you acknowledge, that the Software may not be modified, copied or distributed unless embedded on a Texas Instruments microcontroller or used solely and exclusively in conjunction with a Texas Instruments radio frequency transceiver, which is integrated into your product. Other than for the foregoing purpose, you may not use, reproduce, copy, prepare derivative works of, modify, distribute, perform, display or sell this Software and/or its documentation for any purpose. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE PROVIDED 揂S IS?WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS. Should you have any questions regarding your right to use this Software, contact Texas Instruments Incorporated at www.TI.com. **************************************************************************************************/ /********************************************************************* This application isn't intended to do anything useful, it is intended to be a simple example of an application's structure. This application sends it's messages either as broadcast or broadcast filtered group messages. The other (more normal) message addressing is unicast. Most of the other sample applications are written to support the unicast message model. Key control: SW1: Sends a flash command to all devices in Group 1. SW2: Adds/Removes (toggles) this device in and out of Group 1. This will enable and disable the reception of the flash command. *********************************************************************/ /********************************************************************* * INCLUDES */ #include <stdio.h> #include <string.h> #include "OSAL.h" #include "ZGlobals.h" #include "AF.h" #include "aps_groups.h" #include "ZDApp.h" #include "MT_UART.h" //add by 1305106 #include "SampleApp.h" #include "SampleAppHw.h" #include "OnBoard.h" /* HAL */ #include "hal_lcd.h" #include "hal_led.h" #include "hal_key.h" #include"sht11.h" /********************************************************************* * MACROS */ /********************************************************************* * CONSTANTS */ /********************************************************************* * TYPEDEFS */ /********************************************************************* * GLOBAL VARIABLES */ // This list should be filled with Application specific Cluster IDs. const cId_t SampleApp_ClusterList[SAMPLEAPP_MAX_CLUSTERS] = { SAMPLEAPP_PERIODIC_CLUSTERID, SAMPLEAPP_FLASH_CLUSTERID, }; const SimpleDescriptionFormat_t SampleApp_SimpleDesc = { SAMPLEAPP_ENDPOINT, // int Endpoint; SAMPLEAPP_PROFID, // uint16 AppProfId[2]; SAMPLEAPP_DEVICEID, // uint16 AppDeviceId[2]; SAMPLEAPP_DEVICE_VERSION, // int AppDevVer:4; SAMPLEAPP_FLAGS, // int AppFlags:4; SAMPLEAPP_MAX_CLUSTERS, // uint8 AppNumInClusters; (cId_t *)SampleApp_ClusterList, // uint8 *pAppInClusterList; SAMPLEAPP_MAX_CLUSTERS, // uint8 AppNumInClusters; (cId_t *)SampleApp_ClusterList // uint8 *pAppInClusterList; }; // This is the Endpoint/Interface description. It is defined here, but // filled-in in SampleApp_Init(). Another way to go would be to fill // in the structure here and make it a "const" (in code space). The // way it's defined in this sample app it is define in RAM. endPointDesc_t SampleApp_epDesc; /********************************************************************* * EXTERNAL VARIABLES */ /********************************************************************* * EXTERNAL FUNCTIONS */ /********************************************************************* * LOCAL VARIABLES */ uint8 SampleApp_TaskID; // Task ID for internal task/event processing // This variable will be received when // SampleApp_Init() is called. devStates_t SampleApp_NwkState; uint8 SampleApp_TransID; // This is the unique message ID (counter) afAddrType_t SampleApp_Periodic_DstAddr; afAddrType_t SampleApp_Flash_DstAddr; aps_Group_t SampleApp_Group; uint8 SampleAppPeriodicCounter = 0; uint8 SampleAppFlashCounter = 0; /********************************************************************* * LOCAL FUNCTIONS */ void SampleApp_HandleKeys( uint8 shift, uint8 keys ); void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pckt ); void SampleApp_SendPeriodicMessage( void ); void SampleApp_SendFlashMessage( uint16 flashTime ); /********************************************************************* * NETWORK LAYER CALLBACKS */ /********************************************************************* * PUBLIC FUNCTIONS */ /********************************************************************* * @fn SampleApp_Init * * @brief Initialization function for the Generic App Task. * This is called during initialization and should contain * any application specific initialization (ie. hardware * initialization/setup, table initialization, power up * notificaiton ... ). * * @param task_id - the ID assigned by OSAL. This ID should be * used to send messages and set timers. * * @return none */ void SampleApp_Init( uint8 task_id ) { SampleApp_TaskID = task_id; SampleApp_NwkState = DEV_INIT; SampleApp_TransID = 0; // Device hardware initialization can be added here or in main() (Zmain.c). // If the hardware is application specific - add it here. // If the hardware is other parts of the device add it in main(). #if defined ( BUILD_ALL_DEVICES ) // The "Demo" target is setup to have BUILD_ALL_DEVICES and HOLD_AUTO_START // We are looking at a jumper (defined in SampleAppHw.c) to be jumpered // together - if they are - we will start up a coordinator. Otherwise, // the device will start as a router. if ( readCoordinatorJumper() ) zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR; else zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER; #endif // BUILD_ALL_DEVICES #if defined ( HOLD_AUTO_START ) // HOLD_AUTO_START is a compile option that will surpress ZDApp // from starting the device and wait for the application to // start the device. ZDOInitDevice(0); #endif // Setup for the periodic message's destination address // Broadcast to everyone SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast; SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF; // Setup for the flash command's destination address - Group 1 SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup; SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP; // Fill out the endpoint description. SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_epDesc.task_id = &SampleApp_TaskID; SampleApp_epDesc.simpleDesc = (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc; SampleApp_epDesc.latencyReq = noLatencyReqs; // Register the endpoint description with the AF afRegister( &SampleApp_epDesc ); // Register for all key events - This app will handle all key events RegisterForKeys( SampleApp_TaskID ); MT_UartRegisterTaskID( SampleApp_TaskID ); //add by 1305106 // By default, all devices start out in Group 1 SampleApp_Group.ID = 0x0001; osal_memcpy( SampleApp_Group.name, "Group 1", 7 ); aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); #if defined ( LCD_SUPPORTED ) HalLcdWriteString( "SampleApp", HAL_LCD_LINE_1 ); #endif } /********************************************************************* * @fn SampleApp_ProcessEvent * * @brief Generic Application Task event processor. This function * is called to process all events for the task. Events * include timers, messages and any other user defined events. * * @param task_id - The OSAL assigned task ID. * @param events - events to process. This is a bit map and can * contain more than one event. * * @return none */ uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) { afIncomingMSGPacket_t *MSGpkt; (void)task_id; // Intentionally unreferenced parameter if ( events & SYS_EVENT_MSG ) { MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); while ( MSGpkt ) { switch ( MSGpkt->hdr.event ) { // Received when a key is pressed case KEY_CHANGE: SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys ); break; // Received when a messages is received (OTA) for this endpoint case AF_INCOMING_MSG_CMD: SampleApp_MessageMSGCB( MSGpkt ); break;; // Received whenever the device changes state in the network case ZDO_STATE_CHANGE: SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status); if ( (SampleApp_NwkState == DEV_ZB_COORD) || (SampleApp_NwkState == DEV_ROUTER) || (SampleApp_NwkState == DEV_END_DEVICE) ) { // Start sending the periodic message in a regular interval. HalLedSet(HAL_LED_1, HAL_LED_MODE_ON); osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT ); } else { // Device is no longer in the network } break; default: break; } osal_msg_deallocate( (uint8 *)MSGpkt ); // Release the memory MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); // Next - if one is available } return (events ^ SYS_EVENT_MSG); // return unprocessed events } // Send a message out - This event is generated by a timer // (setup in SampleApp_Init()). if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) { SampleApp_SendPeriodicMessage(); // Send the periodic message // Setup to send message again in normal period (+ a little jitter) osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) ); return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT); // return unprocessed events } return 0; // Discard unknown events } /********************************************************************* * Event Generation Functions */ /********************************************************************* * @fn SampleApp_HandleKeys * * @brief Handles all key events for this device. * * @param shift - true if in shift/alt. * @param keys - bit field for key events. Valid entries: * HAL_KEY_SW_2 * HAL_KEY_SW_1 * * @return none */ void SampleApp_HandleKeys( uint8 shift, uint8 keys ) { (void)shift; // Intentionally unreferenced parameter if ( keys & HAL_KEY_SW_6 ) { /* This key sends the Flash Command is sent to Group 1. * This device will not receive the Flash Command from this * device (even if it belongs to group 1). */ SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION ); } if ( keys & HAL_KEY_SW_2 ) { /* The Flashr Command is sent to Group 1. * This key toggles this device in and out of group 1. * If this device doesn't belong to group 1, this application * will not receive the Flash command sent to group 1. */ aps_Group_t *grp; grp = aps_FindGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP ); if ( grp ) { // Remove from the group aps_RemoveGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP ); } else { // Add to the flash group aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); } } } /********************************************************************* * LOCAL FUNCTIONS */ /********************************************************************* * @fn SampleApp_MessageMSGCB * * @brief Data message processor callback. This function processes * any incoming data - probably from other devices. So, based * on cluster ID, perform the intended action. * * @param none * * @return none */ void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) { uint16 flashTime; unsigned char *buf; switch ( pkt->clusterId ) { case SAMPLEAPP_PERIODIC_CLUSTERID: buf = pkt->cmd.Data; HalUARTWrite(0,"\r\nTemp:", 7); HalUARTWrite(0, buf, 7); HalUARTWrite(0," Humi:", 6); HalUARTWrite(0, buf+7, 7); break; case SAMPLEAPP_FLASH_CLUSTERID: flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] ); HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) ); break; } } /********************************************************************* * @fn SampleApp_SendPeriodicMessage * * @brief Send the periodic message. * * @param none * * @return none */ void SampleApp_SendPeriodicMessage( void ) { char temp_buf[7]; char humi_buf[7]; char i; char buf[14]; float humi,temp; if(GetHumiAndTemp(&humi,&temp) == 0) { sprintf(humi_buf, (char *)"%f", humi); sprintf(temp_buf, (char *)"%f", temp); for(i=0; i<7; i++) { buf[i] = temp_buf[i]; buf[i+7] = humi_buf[i]; } AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_PERIODIC_CLUSTERID, 14, (unsigned char*)buf, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ); } } /********************************************************************* * @fn SampleApp_SendFlashMessage * * @brief Send the flash message to group 1. * * @param flashTime - in milliseconds * * @return none */ void SampleApp_SendFlashMessage( uint16 flashTime ) { uint8 buffer[3]; buffer[0] = (uint8)(SampleAppFlashCounter++); buffer[1] = LO_UINT16( flashTime ); buffer[2] = HI_UINT16( flashTime ); if ( AF_DataRequest( &SampleApp_Flash_DstAddr, &SampleApp_epDesc, SAMPLEAPP_FLASH_CLUSTERID, 3, buffer, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) { } else { // Error occurred in request to send. } } /********************************************************************* *********************************************************************/ 一、系统分层功能 感知层:用实验箱的两个传感器模块 传感器 1:温湿度传感器,采集温度、湿度数据。 传感器 2:红外对射 ,采集触发状态。 网络层: Zigbee 通信:传感器 1、2 的数据,经 Zigbee 节点传给协调器,协调器通过串口发 PC 端。 数据处理:解析串口数据,分主题发 MQTT 网络,或存数据库 。 应用层:用 Python 做终端,实现界面、串口、数据库交互(可加 MQTT),完成这些功能: 二、具体功能 数据上传: 远程设备实时收传感器 1 数据,格式:学号姓名缩写+温度+湿度 。 远程设备实时收传感器 2 数据,格式:学号姓名缩写+传感器名+interrupt 。 Mysql 数据库:建不同数据表存两个传感器数据,表含 学号姓名缩写、传感器名、数据值、传感器状态 等字段 。 命令下发: 发 学号姓名缩写+Num1Led+on ,传感器 1 连的 Zigbee 模块 LED2 亮;发 …+off 则灭 。 发 学号姓名缩写+Num2Led+on ,传感器 2 连的 Zigbee 模块 LED2 亮;发 …+off 则灭 。 数据联动: 传感器 1:温度>25 且湿度>60,其连的 Zigbee 模块 LED2 闪烁,远程设备、数据库表显示 “温湿度异常”;恢复后显示 “异常解除” 。 传感器 2:触发超 5 次,其连的 Zigbee 模块 LED2 闪烁,远程设备、数据库表显示 “传感状态异常”;恢复后显示 “传感异常解除” 。 强制解除:发 学号姓名缩写+Num1Led+relie ,传感器 1 连的 LED2 停闪,设备和表显示 “强制异常解除温湿度” ;发 …+Num2Led+relie 同理。 数据展示:Python 界面里,串口控制,实时显示传感器 1 的 学号姓名缩写、温度、湿度 数据,呈现底层传感器联动状态 。 根据所给代码和要求,完成功能,给出完整的代码
06-28
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值