向系统发送英文汉字混合消息的函数void SendKeys(char * str)

本文介绍了一个使用C/C++实现的SendKeys函数,该函数能够将字符串转换为Unicode宽字符,并通过SendInput API发送到Windows系统中。具体实现包括字符串编码的转换、键盘输入事件的构造等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#define KEYEVENTF_UNICODE 0x4
void SendKeys(char *str)
{
 INPUT Input;
 WCHAR unicodeWord[512];
 memset(unicodeWord,0,sizeof(unicodeWord));
 MultiByteToWideChar(CP_THREAD_ACP,MB_COMPOSITE,str,strlen(str),unicodeWord,512);;
 
 for(  int i=0 ; unicodeWord[i]!=0 ; i++ )
 {
  Input.type =INPUT_KEYBOARD;
  Input.ki.wVk =0;
  Input.ki.wScan =unicodeWord[i];
  Input.ki.dwFlags = KEYEVENTF_UNICODE;
  Input.ki.time = 1000;
  Input.ki.dwExtraInfo = GetMessageExtraInfo();
  SendInput( 1, &Input , sizeof(INPUT) );
  Input.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
  SendInput( 1, &Input , sizeof(INPUT) );
 }
}
 
/************************************************************************************************** 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
/************************************************************************************************** Filename: SampleApp.c Revised: $Date: 2009-03-18 15:56:27 -0700 (Wed, 18 Mar 2009) $ Revision: $Revision: 19453 $ Description: Sample Application (no Profile). **************************************************************************************************/ /********************************************************************* * 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" /* HAL */ #include "hal_lcd.h" #include "hal_led.h" #include "hal_key.h" #include "sht11.h" /********************************************************************* * CONSTANTS */ /********************************************************************* * GLOBAL VARIABLES */ const cId_t SampleApp_ClusterList[SAMPLEAPP_MAX_CLUSTERS] = { SAMPLEAPP_PERIODIC_CLUSTERID, SAMPLEAPP_FLASH_CLUSTERID, SAMPLEAPP_LED_CLUSTERID, SAMPLEAPP_TEMP_CLUSTERID, }; const SimpleDescriptionFormat_t SampleApp_SimpleDesc = { SAMPLEAPP_ENDPOINT, SAMPLEAPP_PROFID, SAMPLEAPP_DEVICEID, SAMPLEAPP_DEVICE_VERSION, SAMPLEAPP_FLAGS, SAMPLEAPP_MAX_CLUSTERS, (cId_t *)SampleApp_ClusterList, SAMPLEAPP_MAX_CLUSTERS, (cId_t *)SampleApp_ClusterList }; endPointDesc_t SampleApp_epDesc; /********************************************************************* * LOCAL VARIABLES */ uint8 SampleApp_TaskID; devStates_t SampleApp_NwkState; uint8 SampleApp_TransID; 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 ); void SampleApp_Process_SensorInt(void); void SampleApp_ProcessIntMessage( afIncomingMSGPacket_t *pkt ); void Delay(uint16 n); void SensorIO_Init(void); /********************************************************************* * PUBLIC FUNCTIONS */ void SampleApp_Init( uint8 task_id ) { SampleApp_TaskID = task_id; SampleApp_NwkState = DEV_INIT; SampleApp_TransID = 0; SampleApp_Periodic_DstAddr.addrMode = AddrBroadcast; SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF; SampleApp_Flash_DstAddr.addrMode = afAddrGroup; SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP; 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 = 0x0001; osal_memcpy( SampleApp_Group.name, "Group 1", 7 ); aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); Sht11Init(); #if defined ( LCD_SUPPORTED ) HalLcdWriteString( "SampleApp", HAL_LCD_LINE_1 ); #endif } uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) { afIncomingMSGPacket_t *MSGpkt; 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 ) { SampleApp_SendPeriodicMessage(); 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 0; } void SetLedStatus(unsigned char *buf) { if(*buf==0x00){ P1_0=0; } else if(*buf==0x01){ P1_0=1; } else if(*buf==0x03){ P1_2=1; } else if(*buf==0x04){ P1_2=0; } } void SampleApp_HandleKeys( uint8 shift, uint8 keys ) { if ( keys & HAL_KEY_SW_6 ) { SampleApp_SendFlashMessage( SAMPLEAPP_FLASH_DURATION ); } if ( keys & HAL_KEY_SW_2 ) { aps_Group_t *grp; grp = aps_FindGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP ); if ( grp ) { aps_RemoveGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP ); } else { aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); } } } 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:", 10); HalUARTWrite(0, buf+7, 7); break; case SAMPLEAPP_LED_CLUSTERID: buf =pkt->cmd.Data; SetLedStatus(buf); 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; } } 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 { } } 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 ); } } void SampleApp_ProcessMTMessage(afIncomingMSGPacket_t *msg) { byte len = msg->hdr.status; uint8 *msgPtr = ((unsigned char *)msg+2); HalUARTWrite ( 0, msgPtr, len); uint8 status; if(strncmp(msgPtr, "on", 2) == 0){ status = 0x00; HalUARTWrite ( 0, "\r led on\r", 12); } else if(strncmp(msgPtr, "off", 3) == 0){ status = 0x01; HalUARTWrite ( 0, "\r led off\r", 13); } else if(strncmp(msgPtr, "beepon", 6) == 0){ status = 0x03; HalUARTWrite ( 0, "\rset beep on\r", 13); } else if(strncmp(msgPtr, "beepoff", 7) == 0){ status = 0x04; HalUARTWrite ( 0, "\rset beep off\r", 13); } if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc, SAMPLEAPP_LED_CLUSTERID, 1, &status, &SampleApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ) { } else { } } 代码是这样的 xcom上从硬件传来的数据是乱码
06-23
详细解读以下代码:/** * copyright Copyright (c) 2025 Chendu TP-Link Technologies Co.Ltd. * * file shared_memory.h * brief Implementing inter process communication through shared memory * * author Wang zhiheng <wangzhiheng@tp-link.com.hk> * version 1.0.0 * date 12Aug25 * */ #ifndef SHM_COMM_H #define SHM_COMM_H /**************************************************************************************************/ /* INCLUDE FILES */ /**************************************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/shm.h> #include <sys/sem.h> #include <sys/ipc.h> #include <time.h> #include <unistd.h> /**************************************************************************************************/ /* DEFINES */ /**************************************************************************************************/ /** Define shared memory keys */ #define SHM_A2B_KEY 0x1234 #define SHM_B2A_KEY 0x5678 /** Define semaphore keys */ #define SEM_A2B_EMPTY_KEY 0x1111 #define SEM_A2B_FULL_KEY 0x2222 #define SEM_B2A_EMPTY_KEY 0x3333 #define SEM_B2A_FULL_KEY 0x4444 /** Semaphore operation macros */ #define P(sem_id) semaphore_operation(sem_id, -1, 0) #define V(sem_id) semaphore_operation(sem_id, 1, 0) /**************************************************************************************************/ /* TYPES */ /**************************************************************************************************/ /** Define shared memory segment structure for data transmission */ typedef struct ShmDataSegment { char data[1024]; /** Buffer for data storage */ size_t size; /** Actual size of transmitted data */ unsigned long crc; /** CRC checksum for data validation */ } ShmDataSegment; /** Define shared memory segment structure for acknowledgment */ typedef struct ShmAckSegment { int ack_status; /** 1 = success, 2 = checksum failure */ size_t size; /** Size of the acknowledged data */ } ShmAckSegment; /**************************************************************************************************/ /* FUNCTIONS */ /**************************************************************************************************/ static inline unsigned short calculate_checksum(const char *data, int len) { unsigned short sum = 0; for (int i = 0; i < len; i++) { sum += (unsigned char)data[i]; } return sum; } /** Semaphore operation function */ void semaphore_operation(int sem_id, int op, int flg) { struct sembuf sops; sops.sem_num = 0; sops.sem_op = op; sops.sem_flg = flg; semop(sem_id, &sops, 1); } #endif /** * copyright Copyright (c) 2025 Chendu TP-Link Technologies Co.Ltd. * * file A.c * brief process A(Sending process) * * author Wang zhiheng <wangzhiheng@tp-link.com.hk> * version 1.0.0 * date 12Aug25 * */ /**************************************************************************************************/ /* INCLUDE FILES */ /**************************************************************************************************/ #include "shm_comm.h" /**************************************************************************************************/ /* GLOBAL_FUNCTIONS */ /**************************************************************************************************/ int main() { /** * Initialize shared memory segments for data transmission and acknowledgment * Create with read/write permissions for all users (0666) */ int shmid_a2b = shmget(SHM_A2B_KEY, sizeof(ShmDataSegment), IPC_CREAT | 0666); int shmid_b2a = shmget(SHM_B2A_KEY, sizeof(ShmAckSegment), IPC_CREAT | 0666); /** Attach shared memory segments to process address space */ ShmDataSegment *shm_data = (ShmDataSegment*)shmat(shmid_a2b, NULL, 0); ShmAckSegment *shm_ack = (ShmAckSegment*)shmat(shmid_b2a, NULL, 0); /** * Create and initialize semaphores for synchronization * A2B channel: * - sem_a2b_empty: Indicates if data buffer is empty (initial value 1) * - sem_a2b_full: Indicates if data buffer is full (initial value 0) * B2A channel: * - sem_b2a_empty: Indicates if ack buffer is empty (initial value 1) * - sem_b2a_full: Indicates if ack buffer is full (initial value 0) */ int sem_a2b_empty = semget(SEM_A2B_EMPTY_KEY, 1, IPC_CREAT | 0666); int sem_a2b_full = semget(SEM_A2B_FULL_KEY, 1, IPC_CREAT | 0666); int sem_b2a_empty = semget(SEM_B2A_EMPTY_KEY, 1, IPC_CREAT | 0666); int sem_b2a_full = semget(SEM_B2A_FULL_KEY, 1, IPC_CREAT | 0666); semctl(sem_a2b_empty, 0, SETVAL, 1); semctl(sem_a2b_full, 0, SETVAL, 0); semctl(sem_b2a_empty, 0, SETVAL, 1); semctl(sem_b2a_full, 0, SETVAL, 0); /** Test data blocks to be transmitted every second */ char *data[] = { "First data block (M bytes)", /** Transmission at second 1 */ "Second data block (N bytes)", /** Transmission at second 2 */ "Third data block (P bytes)", /** Transmission at second 3 */ "Fourth data block (Q bytes)" /** Transmission at second 4 */ }; /** Main transmission loop - sends data every second */ int i = 0; while(1) { /** Wait for one second before sending next data block */ sleep(1); /** Get current time and format it as YYYY-MM-DD HH:MM:SS */ time_t current_time = time(NULL); struct tm *tm_info = localtime(&current_time); char time_str[20]; strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm_info); /** Prepare data for transmission */ size_t len = strlen(data[i]) + 1; /** Include null terminator */ /** * Send data through A2B channel: * 1. Wait for buffer to be empty (P operation on empty semaphore) * 2. Copy data to shared memory * 3. Calculate and store checksum * 4. Signal buffer is full (V operation on full semaphore) */ P(sem_a2b_empty); memcpy(shm_data->data, data[i], len); shm_data->size = len; shm_data->crc = calculate_checksum(shm_data->data, len); V(sem_a2b_full); /** Log transmission activity */ printf("[A] %s: 我发送了%zu字节数据给B\n", time_str, len); /** * Wait for acknowledgment from B: * 1. Wait for ack buffer to be full (P operation on full semaphore) * 2. Read acknowledgment status and size * 3. Signal ack buffer is empty (V operation on empty semaphore) */ P(sem_b2a_full); int ack_status = shm_ack->ack_status; size_t ack_size = shm_ack->size; V(sem_b2a_empty); /** Log acknowledgment status based on received response */ if (ack_status == 1) { printf("[A] %s: B告诉我收到了%zu字节数据,校验正确\n", time_str, ack_size); } else { printf("[A] %s: B告诉我收到了%zu字节数据,但校验失败\n", time_str, ack_size); } i = ( i + 1) % 4; } /** * Cleanup resources: * 1. Detach shared memory segments * 2. Mark shared memory segments for deletion * 3. Remove semaphores */ shmdt(shm_data); shmdt(shm_ack); shmctl(shmid_a2b, IPC_RMID, NULL); shmctl(shmid_b2a, IPC_RMID, NULL); semctl(sem_a2b_empty, 0, IPC_RMID, 0); semctl(sem_a2b_full, 0, IPC_RMID, 0); semctl(sem_b2a_empty, 0, IPC_RMID, 0); semctl(sem_b2a_full, 0, IPC_RMID, 0); return 0; } /** * copyright Copyright (c) 2025 Chendu TP-Link Technologies Co.Ltd. * * file B.c * brief process B(Receiving process) * * author Wang zhiheng <wangzhiheng@tp-link.com.hk> * version 1.0.0 * date 13Aug25 * */ /**************************************************************************************************/ /* INCLUDE FILES */ /**************************************************************************************************/ #include "shm_comm.h" /**************************************************************************************************/ /* TYPES */ /**************************************************************************************************/ /** Statistics tracking structure */ typedef struct { int recv_count; /** Total receptions */ int success_count; /** Valid checksums */ int fail_count; /** Checksum mismatches */ size_t total_bytes; /** Cumulative bytes received */ } Stats; /**************************************************************************************************/ /* GLOBAL_FUNCTIONS */ /**************************************************************************************************/ int main() { /** * Attach to existing shared memory segments * Note: No IPC_CREAT flag since segments should already exist */ int shmid_a2b = shmget(SHM_A2B_KEY, sizeof(ShmDataSegment), 0666); int shmid_b2a = shmget(SHM_B2A_KEY, sizeof(ShmAckSegment), 0666); ShmDataSegment *shm_data = (ShmDataSegment*)shmat(shmid_a2b, NULL, 0); ShmAckSegment *shm_ack = (ShmAckSegment*)shmat(shmid_b2a, NULL, 0); /** Get existing semaphores */ int sem_a2b_empty = semget(SEM_A2B_EMPTY_KEY, 1, 0666); int sem_a2b_full = semget(SEM_A2B_FULL_KEY, 1, 0666); int sem_b2a_empty = semget(SEM_B2A_EMPTY_KEY, 1, 0666); int sem_b2a_full = semget(SEM_B2A_FULL_KEY, 1, 0666); /** Main reception loop - continuously checks for incoming data */ while (1) { /** * Wait for data to arrive in A2B channel: * P operation on full semaphore (blocks until data is available) */ P(sem_a2b_full); /** Get current time for logging */ time_t current_time = time(NULL); struct tm *tm_info = localtime(&current_time); char time_str[20]; strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm_info); /** Check for termination condition (size=0) */ size_t size = shm_data->size; if (size == 0) { V(sem_a2b_empty); /** Release buffer before breaking */ break; } /** * Validate received data: * 1. Calculate checksum of received data * 2. Compare with transmitted checksum */ unsigned short calc_crc = calculate_checksum(shm_data->data, size); int crc_ok = (calc_crc == shm_data->crc) ? 1 : 0; /** Log reception status based on checksum validation */ if (crc_ok) { printf("[B] %s: 我从A接收了%zu字节数据,校验正确,通知A接收了%zu字节数据,校验正确。\n", time_str, size, size); } else { printf("[B] %s: 我从A接收了%zu字节数据,校验错误,通知A接收了%zu字节数据,校验错误。\n", time_str, size, size); } /** * Send acknowledgment through B2A channel: * 1. Wait for ack buffer to be empty (P operation on empty semaphore) * 2. Write acknowledgment status and size * 3. Signal ack buffer is full (V operation on full semaphore) * 4. Release data buffer (V operation on empty semaphore) */ P(sem_b2a_empty); shm_ack->ack_status = crc_ok ? 1 : 2; /** 1=success, 2=checksum failure */ shm_ack->size = size; V(sem_b2a_full); V(sem_a2b_empty); /** Release data buffer for next transmission */ } /** Detach shared memory segments before exit */ shmdt(shm_data); shmdt(shm_ack); return 0; }
最新发布
08-14
/************************************************************************************************** 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
#define PPR 13 #define ENCODER_MULTIPLY 4 #define GEAR_RATIO 20 // 计算每圈对应的计数 #define COUNTS_PER_REV (PPR * ENCODER_MULTIPLY * GEAR_RATIO) /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* 速度环PID参数 */ float InnerTarget=0, InnerActual=0,Innerout=0;//目标值,实际值,输出值ֵ float InnerKp=0.5; float InnerKi=0.5; float InnerKd=0.1;//比例项积分项微分项的权重 float InnerError0=0,InnerError1=0,InnerErrorInt=0,InnerIntout=0;//本次误差,上次误差,误差积分 /* 位置环PID参数 */ float PositionTarget = 0, PositionActual = 0, Positionout = 0;//目标值,实际值,输出值ֵ float PositionKp = 0.3; float PositionKi = 0.15; float PositionKd = 0.05;//比例项积分项微分项的权重 float PositionError0 = 0, PositionError1 = 0, PositionErrorInt = 0, PositionIntOut = 0;//本次误差,上次误差,误差积分 extern unsigned char Hzk[][32]; uint32_t ccr_value=0; uint32_t arr_value; unsigned int x=0; int motor_direction; uint8_t rx_data; unsigned char* word0=(uint8_t *)"**<qianchen>**"; unsigned char* time=(uint8_t *)"*>2025-07-06<*"; unsigned char* word1=(uint8_t *)"Count:"; unsigned char* word2=(uint8_t *)"PWM:"; unsigned char* word3=(uint8_t *)"Speed:"; unsigned char* word4=(uint8_t *)"Target:"; unsigned char* word5=(uint8_t *)"Actual:"; unsigned char* word6=(uint8_t *)"Out:"; unsigned char* word7=(uint8_t *)"P_T:"; unsigned char* word8=(uint8_t *)"P_A:"; unsigned char* word9=(uint8_t *)"P_O:"; unsigned char* word10=(uint8_t *)"I_T:"; unsigned char* word11=(uint8_t *)"I_A:"; unsigned char* word12=(uint8_t *)"I_O:"; uint16_t count; float speed=0.0; uint8_t str_buff[64]; void delay(unsigned int x) { while(x--); } void Scan_Keys() { if(KEY0==GPIO_PIN_RESET) { delay(1000); if(KEY0==GPIO_PIN_RESET) { while(KEY0==GPIO_PIN_RESET); PositionTarget+=200; } } if(KEY1==GPIO_PIN_RESET) { delay(1000); if(KEY1==GPIO_PIN_RESET) { while(KEY1==GPIO_PIN_RESET); PositionTarget-=200; } } } void OLED_display_info() { OLED_Clear(); OLED_ShowString(8,0,word0,sizeof(word0)); OLED_ShowString(5,1,time,sizeof(time)); // OLED_ShowString(8,2,word1,sizeof(word1)); // OLED_ShowString(8,3,word2,sizeof(word2)); // OLED_ShowString(8,4,word3,sizeof(word3)); // OLED_ShowString(8,5,word4,sizeof(word4)); // OLED_ShowString(8,6,word5,sizeof(word5)); // OLED_ShowString(8,7,word6,sizeof(word6)); OLED_ShowString(8,2,word7,sizeof(word7)); OLED_ShowString(8,3,word8,sizeof(word8)); OLED_ShowString(8,4,word9,sizeof(word9)); OLED_ShowString(8,5,word10,sizeof(word10)); OLED_ShowString(8,6,word11,sizeof(word11)); OLED_ShowString(8,7,word12,sizeof(word12)); // OLED_ShowCHinese(0,3,0); // OLED_ShowCHinese(18,3,1); // OLED_ShowCHinese(36,3,2); // OLED_ShowCHinese(54,3,3); // OLED_ShowCHinese(0,6,4); // OLED_ShowCHinese(18,6,5); // OLED_ShowCHinese(36,6,6); // OLED_ShowCHinese(54,6,7); } void OLED_display_dat() { // sprintf((char*)str_buff,"%5d",count); // OLED_ShowString(64,2,str_buff,sizeof(str_buff)); // // arr_value = __HAL_TIM_GET_AUTORELOAD(&htim2); // 获取ARR值 // float duty_cycle = ((float)ccr_value / arr_value) * 100.0f; // 计算占空比 // // sprintf((char*)str_buff,"%+.0f",duty_cycle); // OLED_ShowString(64,3,str_buff,sizeof(str_buff)); // // sprintf((char*)str_buff,"%+.0f",speed); // OLED_ShowString(64,4,str_buff,sizeof(str_buff)); sprintf((char*)str_buff,"%+.0f",PositionTarget); OLED_ShowString(64,2,str_buff,sizeof(str_buff)); sprintf((char*)str_buff,"%+.0f",PositionActual); OLED_ShowString(64,3,str_buff,sizeof(str_buff)); sprintf((char*)str_buff,"%+.0f",Positionout); OLED_ShowString(64,4,str_buff,sizeof(str_buff)); sprintf((char*)str_buff,"%+.0f",InnerTarget); OLED_ShowString(64,5,str_buff,sizeof(str_buff)); sprintf((char*)str_buff,"%+.0f",InnerActual); OLED_ShowString(64,6,str_buff,sizeof(str_buff)); sprintf((char*)str_buff,"%+.0f",Innerout); OLED_ShowString(64,7,str_buff,sizeof(str_buff)); } uint16_t last_count = 0; uint16_t last_time_ms = 0; //void calculate_speed() //{ // count = __HAL_TIM_GET_COUNTER(&htim3); // uint16_t current_time_ms = HAL_GetTick(); // int16_t diff_count = count - last_count; // float delta_time_sec = (current_time_ms - last_time_ms) / 1000.0f; // // if (delta_time_sec > 0) // { // float rpm = ((float)diff_count / (float)COUNTS_PER_REV) * 60.0f / delta_time_sec; // // speed=rpm; // // InnerActual=speed/1220.0f*100; // // InnerError1 = InnerError0; // InnerError0 = InnerTarget - InnerActual; //// ErrorInt += Error0; // InnerIntOut += InnerKi * InnerError0; // // /*积分项输出限幅*/ // if(InnerIntOut>1000)InnerIntOut=1000; // if(InnerIntOut<0)InnerIntOut=0; // // Innerout = InnerKp * InnerError0 + InnerIntOut + InnerKd * (InnerError0 - InnerError1); // // if(Innerout > 1000)Innerout = 1000; // if(Innerout < 0)Innerout = 0; // // __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,Innerout); // } // last_count = count; // last_time_ms = current_time_ms; //} void set_motor_direction_and_pwm(float pwm_value) { // 限制PWM范围 pwm_value = fmaxf(fminf(pwm_value, 1000.0f), 0); // 设置方向引脚(假设DIR_PIN控制方向) if (motor_direction > 0) { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET); // 正转 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET); } else { HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET); // 反转 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); } // 设置PWM占空比 __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pwm_value); } void calculate_Position() { count = __HAL_TIM_GET_COUNTER(&htim3); uint16_t current_time_ms = HAL_GetTick(); int16_t diff_count = count - last_count; float delta_time_sec = (current_time_ms - last_time_ms) / 1000.0f; if (delta_time_sec > 0) { // float rpm = ((float)diff_count / (float)COUNTS_PER_REV) * 60.0f / delta_time_sec; // // speed=rpm; // 更新位置实际值(编码器脉冲累计) PositionActual += diff_count; // 位置环控制:计算误差和方向 PositionError0 = PositionTarget - PositionActual; motor_direction = (PositionError0 >= 0) ? 1 : -1; // 目标>实际时正转,否则反转 // 位置环PID输出(取绝对值作为速度目标) PositionErrorInt += PositionError0; PositionIntOut = PositionKp * PositionError0 + PositionKi * PositionErrorInt; // 限制积分输出 PositionIntOut = fmaxf(fminf(PositionIntOut, 1000.0f), -1000.0f); // 速度环目标值(绝对值) InnerTarget = fabs(PositionIntOut); // 速度环目标值(绝对值) InnerTarget = fabs(PositionIntOut); // 速度环控制(InnerActual为编码器脉冲差值) InnerError0 = InnerTarget - fabs(diff_count); InnerIntout += InnerKi * InnerError0; InnerIntout = fmaxf(fminf(InnerIntout, 1000.0f), 0); // 速度环输出非负 Innerout = InnerKp * InnerError0 + InnerIntout; Innerout = fmaxf(fminf(Innerout, 1000.0f), 0); // 设置电机方向和PWM set_motor_direction_and_pwm(Innerout); // //速度环实际值 = 本周期编码器脉冲差值(或累计值) // InnerActual = PositionActual; // // //位置环控制 // PositionError1 = PositionError0; // PositionError0 = PositionTarget - PositionActual; // PositionErrorInt += PositionError0; // // /*积分项输出限幅*/ // if(PositionIntOut>1000)PositionIntOut=1000; // if(PositionIntOut<0)PositionIntOut=0; // Positionout = PositionKp * PositionError0 + PositionKi * PositionErrorInt + PositionKd * (PositionError0 - PositionError1); // // 确定方向和速度目标 // motor_direction = (Positionout >= 0) ? 1 : -1; // if(motor_direction==1) // { // HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1, GPIO_PIN_SET); // HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2, GPIO_PIN_RESET); // } // else if(motor_direction==-1) // { // HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1, GPIO_PIN_RESET); // HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2, GPIO_PIN_SET); // } // InnerTarget = fabs(Positionout); // InnerTarget = Positionout; // InnerError1 = InnerError0; // InnerError0 = InnerTarget - InnerActual; //// ErrorInt += Error0; // InnerIntout += InnerKi * InnerError0; // // /*积分项输出限幅*/ // if(InnerIntout>1000)InnerIntout=1000; // if(InnerIntout<0)InnerIntout=0; // // Innerout = InnerKp * InnerError0 + InnerIntout + InnerKd * (InnerError0 - InnerError1); // // if(Innerout > 1000)Innerout = 1000; // if(Innerout < 0)Innerout = 0; // // __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,Innerout); } last_count = count; last_time_ms = current_time_ms; } //void dianjispeed() //{ // switch(x) // { // case 0: PositionTarget = 0; break; // case 1: PositionTarget = 300; break; // case 2: PositionTarget = 500; break; // case 3: PositionTarget = 800; break; // } //// __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,ccr_value); //} void Send_PID_Data(float target, float actual, float output) { char buffer[64]; sprintf(buffer, "T:%.2f,A:%.2f,O:%.2f\r\n", target, actual, output); HAL_UART_Transmit(&huart1, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY); } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM2_Init(); MX_TIM3_Init(); MX_I2C1_Init(); MX_TIM4_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ OLED_Init(); OLED_display_info(); // 启动编码器 HAL_TIM_Encoder_Start(&htim3,TIM_CHANNEL_ALL); // 启动串口接收中断 HAL_UART_Receive_IT(&huart1, &rx_data, 1); // 启动定时器并启用中断 HAL_TIM_Base_Start_IT(&htim4); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2, GPIO_PIN_RESET); HAL_TIM_PWM_Start_IT(&htim2,TIM_CHANNEL_1); PositionActual = 0; // 初始化位置实际值 while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ Scan_Keys(); Send_PID_Data(PositionTarget, PositionActual, Positionout); // dianjispeed(); // __HAL_TIM_SET_COUNTER(&htim3,0); // HAL_Delay(500); } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } /* USER CODE BEGIN 4 */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim == &htim4) { calculate_Position(); // 计算速度 OLED_display_dat(); // 更新 OLED 显示 } } // 回调函数中处理数据 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { // 示例:根据接收的字符调整目标值 switch (rx_data) { case '1': PositionTarget = 300; break; case '2': PositionTarget = 600; break; case '3': PositionTarget = 900; break; default: break; } // 重新启动接收中断 HAL_UART_Receive_IT(&huart1, &rx_data, 1); } } 如果想用野火PID调试助手对以上代码进行调试,该如何修改?
07-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值