飞控信号SBUS信号解析为PWM信号输出
飛控信號SBUS信號解析為PWM信號輸出?
1.修改STM32時鐘頻率:?
static void SetSysClockTo72(void)?
{?
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/!< SYSCLK, HCLK, PCLK2 and PCLK1 configuration —————————/?
/!< Enable HSE?/?
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/!< Wait till HSE is ready and if Time out is reached exit?/?
do?
{?
HSEStatus = RCC->CR & RCC_CR_HSERDY;?
StartUpCounter++;?
} while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)?
{?
HSEStatus = (uint32_t)0x01;?
}?
else?
{?
HSEStatus = (uint32_t)0x00;?
}
if (HSEStatus == (uint32_t)0x01)?
{?
/!< Enable Prefetch Buffer?/?
FLASH->ACR |= FLASH_ACR_PRFTBE;
}?
else?
{ /*!< If HSE fails to start-up, the application will have wrong clock?
configuration. User can add here some code to deal with this error */
}?
}?
2.串口時鐘配置?
打開串口時鐘?
void RCC_Configuration(void) // 啟動USART1,2,3的時鐘?
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);?
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);?
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //注意各串口所對應的時鐘源不一樣;?
Uart1 用的是APB2?
Uart2 用的是APB1?
Uart3 用的是APB1?
//奇偶檢驗?
USART_InitStructure.USART_BaudRate = 9600;?
USART_InitStructure.USART_WordLength = USART_WordLength_9b;?
USART_InitStructure.USART_StopBits = USART_StopBits_1;?
USART_InitStructure.USART_Parity = USART_Parity_Even;?
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;?
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
偶校驗因為在每個字節后增加一位用于奇偶校驗,因此每字節長度不是8位,而是9字節。
3.串口中斷設置?
#if 1?
//初始化參數設置?
USART_InitStructure.USART_BaudRate = 100000;//100000; //波特率100000?
USART_InitStructure.USART_WordLength = USART_WordLength_9b; //字長8位?
USART_InitStructure.USART_StopBits = USART_StopBits_2; //2位停止字節,USART_StopBits_2?
USART_InitStructure.USART_Parity = USART_Parity_Even;//偶校驗 //USART_Parity_No; //無奇偶校驗?
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無流控制?
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//打開Rx接收和Tx發送功能?
USART_Init(USART3, &USART_InitStructure); //初始化?
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //使能串口中斷,這個必須加上?
USART_Cmd(USART3, ENABLE); //啟動串口?
#endif?
4.sbus協議:?
S-BUS protocol
The protocol is 25 Byte long and is send every 14ms (analog mode) or 7ms (highspeed mode).?
One Byte = 1 startbit + 8 databit + 1 paritybit + 2 stopbit (8E2), baudrate = 100’000 bit/s?
The highest bit is send first. The logic is inverted (Level High = 1)
[startbyte] [data1] [data2] …. [data22] [flags][endbyte]
startbyte = 11110000b (0xF0)
data 1-22 = [ch1, 11bit][ch2, 11bit] …. [ch16, 11bit] (ch# = 0 bis 2047)?
channel 1 uses 8 bits from data1 and 3 bits from data2?
channel 2 uses last 5 bits from data2 and 6 bits from data3?
etc.
flags = bit7 = ch17 = digital channel (0x80)?
bit6 = ch18 = digital channel (0x40)?
bit5 = Frame lost, equivalent red LED on receiver (0x20)?
bit4 = failsafe activated (0x10)?
bit3 = n/a?
bit2 = n/a?
bit1 = n/a?
bit0 = n/a
endbyte = 00000000b?
3.接收程序實現:?
在STM32中的具體實現,除了如上述內容配置串口參數,還需要寫好中斷函數,寫好解析函數。思路很簡單,利用間隔時間來區分兩幀,收到一幀數據后,做如下檢查:
字節數夠不夠?
第一個字節是不是0x0f?
最后一個字節是不是0x00?
檢查flag中的標志位
舉個中斷接收函數例子:
void UART4_IRQHandler(void)
{
static uint8_t byteCNT = 0;static uint32_t lastTime = 0;uint32_t curTime;uint32_t interval = 0;HAL_NVIC_ClearPendingIRQ(UART4_IRQn);//如果時間間隔大于3毫秒,則認為是新的一幀if(lastTime == 0){curTime = HAL_GetTick();lastTime = curTime;}else{curTime = HAL_GetTick();interval = curTime - lastTime;lastTime = curTime;if(interval >= 3){if(byteCNT == 25 && uart4_cache1[0] == 0x0f && uart4_cache1[24] == 0x00){rc_captured = 0;memcpy(uart4_cache2, uart4_cache1, byteCNT);rc_captured = 1;}byteCNT = 0;}}if(RESET != __HAL_UART_GET_FLAG(&huart4, UART_FLAG_ORE)){__HAL_UART_CLEAR_FLAG(&huart4, UART_FLAG_ORE);uart4_cache1[byteCNT++] = huart4.Instance->DR;} if(RESET != __HAL_UART_GET_FLAG(&huart4, UART_FLAG_RXNE)){uart4_cache1[byteCNT++] = huart4.Instance->DR;}}
4.sbus解析程序:
8樓?
樓主| 發表于 2012-7-25 15:43 | 只看該作者?
收到25包據后,通過下面的算法,可以對SBUS數據包進行解析?
解析后數據如下
搖桿行程?
中點 1024?
+100 1696?
+135 1931?
-100 352?
-135 117
回復
舉報
huperzhu
9樓?
樓主| 發表于 2012-7-25 15:44 | 只看該作者?
算法
define
SBUS_SIGNAL_OK
0
define
SBUS_SIGNAL_LOST?
1
define
SBUS_SIGNAL_FAILSAFE
2
unsigned int channels[20];
unsigned char sbus_data[30];
unsigned char failsafe_status,byte_in_sbus,bit_in_sbus,ch,bit_in_channel;
if(SBUS_IN_OK == 1)
{
SBUS_IN_OK = 0;
sbus_flag = sbus_convert(sbus_data);
if((sbus_flag == 0) && (failsafe_status==0))
{
update_PWM(channels);
}
}
unsigned char sbus_convert(unsigned char *data_in)
{
int i;
if ((data_in[0]==0x0F) && (data_in[24] == 0))
{
// clear channels[]
for (i=0; i<16; i++) {channels = 0;}
// reset counters
byte_in_sbus = 1;
bit_in_sbus = 0;
ch = 0;
bit_in_channel = 0;
// process actual sbus data
for (i=0; i<176; i++) {
if (data_in[byte_in_sbus] & (1<
喝水不忘挖井人:http://blog.csdn.net/mish84/article/details/51512718
PPM信號,是遙控控制和接收以及電調油門控制舵機控制的最最重要的信號,當然玩模擬器在電腦軟件里練飛行時也離不開PPM信號。如果只是單純玩也沒有必要了解那么仔細,但作為的專業的知識帖知識點是有必要弄清楚的,甚至在開發航模遙控時,給微控制器編程都是要深入了解的。
縱覽許多論壇,都沒有誰能說得清楚的完整的,這里我也就拋磚引玉了。不管看帖的懂不懂,我也直入主題了:
PPM信號格式:
1、老標準:1~2毫秒是單個通道的總脈寬,其中低電平是固定的占0.3毫秒,高電平從0.7~1.7毫秒可變,脈寬越大油門越高。
2、新的標準:每個通道1~2毫秒脈寬,周期20毫秒,即高電平5V寬度為1毫秒代表低速(油門通道,舵機通道舵桿是打到一頭的頂),那剩下的19毫秒是低電平0V;1.5毫秒低表舵機通道舵桿是打到中心位置,那剩下的18.5毫秒是低電平0V;2毫秒代表高速(油門通道,舵機通道舵桿是打到另一頭的頂),那剩下的18毫秒是低電平0V,如圖。這樣,發射端每20毫秒發射一次,總共可以容納10個比例通道。在接收端,把每個通道分離出來,脈寬信號也是20毫秒更新一次。
3、對于雙向電調,是以1.5毫秒脈沖寬度為停止點,1毫秒脈寬時反轉最高速,2毫秒脈寬時正轉最高速。
在接收端分離出各個通道的信號輸出給被控對象:如電調,舵機等,是不是可以理解為,是PWM(脈寬調制)信號呢?可以這么說,不能簡單地把接收輸出的控制信號,理解為PWM信號,接收輸出的單通信號可周期可以是18~22毫秒,或者16~25毫秒都可以認為是正常的,要求嚴格的是那個高電平的1~2毫秒的脈沖信號。
無線遙控就是利用高頻無線電波實現對模型的控制。Futuba具有自動跳頻抗干擾能力,從理論上講可以讓上百人在同一場地同時遙控自己的模型而不會相互干擾。而且在遙控距離方面也頗具優勢,2.4 GHz遙控系統的功率僅僅在100 mW以下,而它的遙控距離可以達到1km以上。
每個通道信號脈寬0~2ms,變化范圍為1~2ms之間。1幀PPM信號長度為20ms,理論上最多可以有10個通道,但是同步脈沖也需要時間,模型遙控器最多9個通道。 PPM格式
總結
以上是生活随笔為你收集整理的飞控信号SBUS信号解析为PWM信号输出的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python3 —— 逗号分隔值CSV
- 下一篇: 查看linux IO地址范围