前言此前我们打通了网页到ARM的下行通道本文将控制链路继续下沉通过ARM中转将指令透传至STM32以实现对终端设备的精准控制。指令获取方式不变仍通过消息队列接收网页命令本例继续以LED灯为演示对象区别在于该LED已移至STM32最小系统版上。ARM板接收指令并转发ARM板与STM32之间选用LoRa模块进行指令转发通信方式沿用定点模式。当LED线程接收到类型匹配的数据后即执行转发操作。由于此前已获取对应的串口设备名直接调用写操作即可完成LoRa数据的发送。ARM端转发指令如下#includedata_global.hintled_pending0;unsignedcharled_command0;externintserial_fd;// 外部声明串口文件描述符voidled_sendcmd(unsignedcharcommand);// 声明函数void*led_pthread(void*arg){while(1){pthread_mutex_lock(mutex_led);// 等待有命令到来while(led_pending0){pthread_cond_wait(cond_led,mutex_led);}led_sendcmd(led_command);// 发送LED命令led_pending0;// 重置LED命令待处理标志pthread_mutex_unlock(mutex_led);}}// LED控制函数voidled_sendcmd(unsignedcharcommand){unsignedcharbuffer[4];// 目标地址(2字节) 目标信道(1字节) 命令(1字节)buffer[0]LORA_TARGET_ADDR_H;// 目标地址高字节buffer[1]LORA_TARGET_ADDR_L;// 目标地址低字节buffer[2]LORA_TARGET_CHANNEL;// 目标信道buffer[3]command;// LED命令printf(Sending: ADDR%02X%02X, CH%02X, CMD%02X\n,buffer[0],buffer[1],buffer[2],buffer[3]);intretwrite(serial_fd,buffer,4);if(ret0){perror(Failed to send LED command);}}转发时需注意定点模式下数据帧格式为“高位地址 低位地址 信道 控制指令”组装时必须严格按照该顺序组帧。相关的地址信道已在头文件中包含#defineLORA_TARGET_ADDR_H0x00// 目标地址高字节#defineLORA_TARGET_ADDR_L0x01// 目标地址低字节#defineLORA_TARGET_CHANNEL24// 目标信道#defineLORA_LOCAL_ADDR_H0x00// 本地地址高字节#defineLORA_LOCAL_ADDR_L0x00// 本地地址低字节#defineLORA_LOCAL_CHANNEL23// 本地信道STM32端接收数据并控制LED设备STM32端配置串口接收中断当LoRa模块收到数据并传递给STM32时即触发串口中断。在中断服务函数中设置标志位主循环中检测到标志后对指令进行解析并执行。/** * 函 数USART2中断函数 * 参 数无 * 返 回 值无 * 注意事项此函数为中断函数无需调用中断触发后自动执行 * 函数名为预留的指定名称可以从启动文件复制 * 请确保函数名正确不能有任何差异否则中断函数将不能进入 */voidUSART2_IRQHandler(void){if(USART_GetITStatus(USART2,USART_IT_RXNE)SET){Serial_RxDataUSART_ReceiveData(USART2);Serial_RxFlag1;//串口接收标志位随后在主while中进行判断执行USART_ClearITPendingBit(USART2,USART_IT_RXNE);}}指令的解析与执行均在main函数的while循环中完成。voidProcess_Command(uint8_tcmd){OLED_ShowString(4,1,CMD:);OLED_ShowNum(4,5,cmd,3);switch(cmd){case0x80:LED_OFF();break;case0x81:LED_ON();break;default:break;}}intmain(void){System_Init();while(1){if(Serial_RxFlag){Serial_RxFlag0;// 清除标志Process_Command(Serial_RxData);// 处理指令}if(DHT11_Read_Data(temperature,humidity)0){Display_Data();// // 使用定点传输发送温湿度数据// 目标地址0x0000目标信道23// uint8_ttxBuffer[32];uint16_tlen;sprintf((char*)txBuffer,T:%d.%d,H:%d.%d,temperature/10,temperature%10,humidity/10,humidity%10);lenstrlen((char*)txBuffer);// 定点发送给地址 0x0000信道 23 的设备LORA_SendFixed(0x0000,23,txBuffer,len);// 同时OLED显示发送状态OLED_ShowString(3,1,Sent Fixed );}else{OLED_ShowString(3,1,Read Error!);}delay_ms(2000);}}如果要加入其他控制设备只需要修改Process_Command即可。实物连接如下图