一个完整的网站设计,在家里怎样做网站,wordpress火车头采集教程,百度指数专业版app文章目录 一、IBUS协议二、SBUS协议三、PPM信号 一、IBUS协议
IBUS#xff08;Intelligent Bus#xff09;是一种用于电子设备之间通信的协议#xff0c;采用串行通信方式#xff0c;允许多设备通过单一数据线通信#xff0c;较低延迟#xff0c;支持多主机和从机结构Intelligent Bus是一种用于电子设备之间通信的协议采用串行通信方式允许多设备通过单一数据线通信较低延迟支持多主机和从机结构常用于遥控器与天空端之间富斯官网已公开协议协议格式如下可见 一共32字节2 字节帧头28字节数据位 2字节校验位组成
解码如下
#define IBUS_USER_CHANNELS 10
#define IBUS_LENGTH 0x20
#define IBUS_COMMAND40 0x40
#define IBUS_MAX_CHANNLES 14uint8_t rx_buffer[32] {0};
uint16_t channel[IBUS_USER_CHANNELS] {0};
uint16_t checksum_cal, checksum_ibus;void IBUS_READ_CHANNEL(uint8_t user_channels)
{uint16_t channel_buffer[IBUS_MAX_CHANNLES] {0};if(rx_buffer[0] IBUS_LENGTH rx_buffer[1] IBUS_COMMAND40){checksum_cal 0xffff - rx_buffer[0] - rx_buffer[1];for(int i 0; i IBUS_MAX_CHANNLES; i){channel_buffer[i] (uint16_t)(rx_buffer[i * 2 3] 8 | rx_buffer[i * 2 2]);checksum_cal checksum_cal - rx_buffer[i * 2 3] - rx_buffer[i * 2 2];}checksum_ibus rx_buffer[31] 8 | rx_buffer[30];if(checksum_cal checksum_ibus){for(int j 0; j user_channels; j){channel[j] channel_buffer[j];}}}HAL_UART_Receive_IT(IBUS_UART, rx_buffer, 32);
}
二、SBUS协议
SBUSSerial Bus也是一种用于遥控模型、无人机和其他应用程序中的串行通信协议特别是在飞控系统和遥控设备之间以实现高效的数据传输。
采用串行通信单线信号传输支持最多16个通道的控制实时性强可反向兼容PWM设计考虑冗余性。
协议格式共有25字节数据由首部1字节 数据22字节 标志位1字节 结束符1字节组成
帧头 0x0F数据 22 字节的数据分别代表16个通道的数据也即是每个通道的值用了 11 位来表示22x8/16 11每个通道的取值范围为 0~2047低位在前、高位在后标志位 1字节高四位从高到低依次表示 bit7CH17数字通道 bit6CH16数字通道 bit5帧丢失(Frame lost) bit4安全保护(Failsafe)失控保护激活位(0x10判断飞机是否失控 bit3~bit0低四位不用结束符 0x00
通道解析 解码如下
#define USART_BUF_SIZE 8
#define SBUS_DATA_SIZE 25
struct SBUS_t{uint8_t head; // 1字节帧头uint16_t ch[16]; // 16个通道数据uint8_t flag; // 1字节标志位uint8_t end; // 1字节结束
};uint8_t usart_buf[USART_BUF_SIZE];
uint8_t sbus_rx_head 0; // 发现起始字节 0x0F
uint8_t sbus_rx_sta 0; // sbus 接收状态0未完成1已完成一帧接收
uint8_t sbus_rx_index; // 接收字节计数
uint8_t sbus_rx_buf[SBUS_DATA_SIZE]; // 接收sbus数据缓冲区struct SBUS_t sbus; // SBUS 结构体实例化void USART2_IRQHandler(void) //中断函数
{uint8_t chr;if ((__HAL_UART_GET_FLAG(UART2_Handler, UART_FLAG_RXNE) ! RESET)) // 接收中断{HAL_UART_Receive(UART2_Handler, chr, 1, 1000); // 接收一个字符if (sbus_rx_sta 0) // 接收未完成{if ((chr 0x0F) || sbus_rx_head) // 找到首字节或已经找到首字节{sbus_rx_head 1; // 标明已经找到首字母if (sbus_rx_index SBUS_DATA_SIZE) // 未接收到25个字符{sbus_rx_buf[sbus_rx_index] chr; // 不断接收sbus_rx_index ;}else // 接收到25个字符了{sbus_rx_sta 1; // 接收完成sbus_rx_head 0; // 清零准备下一次接收sbus_rx_index 0;}}}}HAL_UART_IRQHandler(UART2_Handler);
}/* 对SBUS协议数据进行解析 */
/* 实现对S.BUS协议缓存头部为 0x0F,结尾为 0x00, 中间22Bytes16通道数据1Byte标志符 */
void SbusParseTask(void *arg)
{while (1){if(sbus_rx_sta1) // 接收完一帧{NVIC_DisableIRQ(USART2_IRQn); // 要关闭中断防止读写混乱sbus.head sbus_rx_buf[0]; // 首部sbus.flag sbus_rx_buf[23]; // 标志符sbus.end sbus_rx_buf[24]; // 结尾sbus.ch[0] ((sbus_rx_buf[2]8) (sbus_rx_buf[1])) 0x07ff; sbus.ch[1] ((sbus_rx_buf[3]5) (sbus_rx_buf[2]3)) 0x07ff;sbus.ch[2] ((sbus_rx_buf[5]10) (sbus_rx_buf[4]2) (sbus_rx_buf[3]6)) 0x07ff;sbus.ch[3] ((sbus_rx_buf[6]7) (sbus_rx_buf[5]1)) 0x07ff;sbus.ch[4] ((sbus_rx_buf[7]4) (sbus_rx_buf[6]4)) 0x07ff;sbus.ch[5] ((sbus_rx_buf[9]9) (sbus_rx_buf[8]1) (sbus_rx_buf[7]7)) 0x07ff; sbus.ch[6] ((sbus_rx_buf[10]6) (sbus_rx_buf[9]2)) 0x07ff;sbus.ch[7] ((sbus_rx_buf[11]3) (sbus_rx_buf[10]5)) 0x07ff;sbus.ch[8] ((sbus_rx_buf[13]8) sbus_rx_buf[12]) 0x07ff;sbus.ch[9] ((sbus_rx_buf[14]5) (sbus_rx_buf[13]3)) 0x07ff;sbus.ch[10]((sbus_rx_buf[16]10) (sbus_rx_buf[15]2) (sbus_rx_buf[14]6)) 0x07ff;sbus.ch[11]((sbus_rx_buf[17]7) (sbus_rx_buf[16]1)) 0x07ff;sbus.ch[12]((sbus_rx_buf[18]4) (sbus_rx_buf[17]4)) 0x07ff;sbus.ch[13]((sbus_rx_buf[20]9) (sbus_rx_buf[19]1) (sbus_rx_buf[18]7)) 0x07ff;sbus.ch[14]((sbus_rx_buf[21]6) (sbus_rx_buf[20]2)) 0x07ff;sbus.ch[15]((sbus_rx_buf[22]3) (sbus_rx_buf[21]5)) 0x07ff;delay_ms(500); // 先做完延时再开启中断与下一次捕获否则延时期间中断到来没有达到预期效果NVIC_EnableIRQ(USART2_IRQn); // 打开串口中断sbus_rx_sta 0; // 准备下一次接收 }else{delay_ms(500); // 免得异常时到此处使得低优先级任务无法执行}}
}
三、PPM信号
PPMPulse Position Modulation脉冲位置调制信号是一种用于传输控制信号的调制方式尤其在遥控系统中非常常见。PPM信号通过改变脉冲在时间上的位置来代表不同的信息在遥控模型、无人机和一些工业控制系统中被广泛应用。
采用串行通信信号频率只有50Hz略逊于ibus和sbus对于一些高精度仪器不可用。
这里提一下PWM表示脉冲宽度调制也就是高电平维持的时间而PPM实质上就是将多个通道的PWM放到“一根线”上进行传输一个完整的PPM信号帧包含了多个通道的PWM值。 PPM信号一帧数据分为低电平0.5ms高电平0.5ms-1.5ms高电平长度与PWM占空比成正比。因为一帧信号最多要2ms信号周期为20ms所以理论一次PPM信号可以发送10帧数据但是由于要确定帧头信号所以要加入同步帧真正的PPM信号里面最多有9帧数据帧。
解析方式①外部中断 ②定时器输入捕获
考虑安全条件下建议使用定时器输入捕获方式进行解码具体解码参考如下
uint16_t PPM_Sample_Cnt0;
uint32_t PPM_Time0;
uint16_t PPM_Okay0;
uint16_t PPM_Databuf[8]{0}; //PPM信号存储
uint8_t TIM2_CH2_CAPTURE_STA0;void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_CC2)!RESET)//捕获中断{if(TIM2_CH2_CAPTURE_STA0x01)//符合条件的话说明上次捕获了高电平那么这次捕获的一定是低电平{PPM_TimeTIM_GetCapture2(TIM2);if(PPM_Time0)PPM_Time; if(PPM_Okay1){PPM_Databuf[PPM_Sample_Cnt]PPM_Time;PPM_Sample_Cnt;if(PPM_Sample_Cnt8)PPM_Okay0;}if(PPM_Time7000)//识别到帧尾{PPM_Okay1;PPM_Sample_Cnt0;} TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Rising);TIM2_CH2_CAPTURE_STA0;//清掉标志位准备开始下一次上升沿和下降沿检测}else{TIM_SetCounter(TIM2,0);//以上为清零 TIM2_CH2_CAPTURE_STA|0x01;//高电平指示被赋值TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //当捕获上升沿后改为捕获下降沿} }TIM_ClearITPendingBit(TIM2, TIM_IT_CC2|TIM_IT_Update); //清除中断标志位一定不要忘要不然下次进不了中断
}