遥控RC SBUS和STM32通信
第一部分:操作
先来看一下我的硬件
强调一下SBUS的基本原理
- 波特率 100K,8位数据位,2位停止位,25字节
- 2位停止位,偶EVEN校验,无流控
- 空闲电平是低电平,和串口相反
数据格式
0 | 1 - 22 | 23 | 24 |
---|---|---|---|
头=0x0F | 16个通道数据 | 故障码,0正常,0x10故障 | 尾 = 0x00 |
MCU型号STM32F407VET,硬件如下图
STM32CUBE设置
初始化代码
/* 初始化 */
uint8_t RcUartBuff[32];
.
.
.
HAL_UARTEx_ReceiveToIdle_DMA(&huart2,RcUartBuff,32);//用IDLE和中断接收
.
/*回调函数*/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
//如果是DMA中断直接退出
if(huart->RxState != HAL_UART_STATE_READY){
return;
}
if(Size == 25){
//在这里直接使用 RcUartBuff 也可以
osMessageQueuePut(myQueueRcRXHandle,RcUartBuff,NULL,0);
}
HAL_UARTEx_ReceiveToIdle_DMA(&huart2,RcUartBuff,32);
}
还应该加上串口故障处理函数,防止贞错误等导致串口关闭
/* 数据解析 */
typedef struct{
uint8_t status;
uint16_t max;
uint16_t mid;
uint16_t min;
uint16_t CH[6];
}RC_Data_t;
RC_Data_t RC_Data ={
.max =1801,
.mid =1000,
.min =200
};
void Sbus_Data_Count(RC_Data_t* rc,uint8_t *buf)
{
uint16_t* chptr =rc->CH;
chptr[ 0] = ((int16_t)buf[ 1] >> 0 | ((int16_t)buf[ 2] << 8 )) & 0x07FF;
chptr[ 1] = ((int16_t)buf[ 2] >> 3 | ((int16_t)buf[ 3] << 5 )) & 0x07FF;
chptr[ 2] = ((int16_t)buf[ 3] >> 6 | ((int16_t)buf[ 4] << 2 ) | (int16_t)buf[ 5] << 10 ) & 0x07FF;
chptr[ 3] = ((int16_t)buf[ 5] >> 1 | ((int16_t)buf[ 6] << 7 )) & 0x07FF;
chptr[ 4] = ((int16_t)buf[ 6] >> 4 | ((int16_t)buf[ 7] << 4 )) & 0x07FF;
chptr[ 5] = ((int16_t)buf[ 7] >> 7 | ((int16_t)buf[ 8] << 1 ) | (int16_t)buf[9] << 9 ) & 0x07FF;
rc->status =buf[23];
}
Sbus_Data_Count(&RC_Data,RcBuff);
第二部分:原理
留下坑吧