日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

飞控信号SBUS信号解析为PWM信号输出

發(fā)布時間:2023/12/20 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 飞控信号SBUS信号解析为PWM信号输出 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

飛控信號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;

/*!< Flash 2 wait state */ FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; /*!< HCLK = SYSCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/*!< PCLK2 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/*!< PCLK1 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;/*!< PLLCLK = 8MHz * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL3); **//RCC_CFGR_PLLMULL3設(shè)置倍頻倍數(shù):輸出時鐘頻率=倍頻數(shù)*晶振時鐘**/*!< Enable PLL */ RCC->CR |= RCC_CR_PLLON;/*!< Wait till PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) { }/*!< Select PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; /*!< Wait till PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) { }

}?
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 */

/*!< Go to infinite loop */ while (1) { }

}?
}?
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); //注意各串口所對應(yīng)的時鐘源不一樣;?
Uart1 用的是APB2?
Uart2 用的是APB1?
Uart3 用的是APB1?
//奇偶檢驗(yàn)?
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;

偶校驗(yàn)因?yàn)樵诿總€字節(jié)后增加一位用于奇偶校驗(yàn),因此每字節(jié)長度不是8位,而是9字節(jié)。

3.串口中斷設(shè)置?
#if 1?
//初始化參數(shù)設(shè)置?
USART_InitStructure.USART_BaudRate = 100000;//100000; //波特率100000?
USART_InitStructure.USART_WordLength = USART_WordLength_9b; //字長8位?
USART_InitStructure.USART_StopBits = USART_StopBits_2; //2位停止字節(jié),USART_StopBits_2?
USART_InitStructure.USART_Parity = USART_Parity_Even;//偶校驗(yàn) //USART_Parity_No; //無奇偶校驗(yàn)?
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無流控制?
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//打開Rx接收和Tx發(fā)送功能?
USART_Init(USART3, &USART_InitStructure); //初始化?
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //使能串口中斷,這個必須加上?
USART_Cmd(USART3, ENABLE); //啟動串口?
#endif?
4.sbus協(xié)議:?
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.接收程序?qū)崿F(xiàn):?
在STM32中的具體實(shí)現(xiàn),除了如上述內(nèi)容配置串口參數(shù),還需要寫好中斷函數(shù),寫好解析函數(shù)。思路很簡單,利用間隔時間來區(qū)分兩幀,收到一幀數(shù)據(jù)后,做如下檢查:

  • 字節(jié)數(shù)夠不夠?

  • 第一個字節(jié)是不是0x0f?

  • 最后一個字節(jié)是不是0x00?

  • 檢查flag中的標(biāo)志位

  • 舉個中斷接收函數(shù)例子:

    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毫秒,則認(rèn)為是新的一幀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樓?
    樓主| 發(fā)表于 2012-7-25 15:43 | 只看該作者?
    收到25包據(jù)后,通過下面的算法,可以對SBUS數(shù)據(jù)包進(jìn)行解析?
    解析后數(shù)據(jù)如下

    搖桿行程?
    中點(diǎn) 1024?
    +100 1696?
    +135 1931?
    -100 352?
    -135 117

    回復(fù)

    舉報(bào)

    huperzhu

    9樓?
    樓主| 發(fā)表于 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信號,是遙控控制和接收以及電調(diào)油門控制舵機(jī)控制的最最重要的信號,當(dāng)然玩模擬器在電腦軟件里練飛行時也離不開PPM信號。如果只是單純玩也沒有必要了解那么仔細(xì),但作為的專業(yè)的知識帖知識點(diǎn)是有必要弄清楚的,甚至在開發(fā)航模遙控時,給微控制器編程都是要深入了解的。


    縱覽許多論壇,都沒有誰能說得清楚的完整的,這里我也就拋磚引玉了。不管看帖的懂不懂,我也直入主題了:


    PPM信號格式:


    1、老標(biāo)準(zhǔn):1~2毫秒是單個通道的總脈寬,其中低電平是固定的占0.3毫秒,高電平從0.7~1.7毫秒可變,脈寬越大油門越高。


    2、新的標(biāo)準(zhǔn):每個通道1~2毫秒脈寬,周期20毫秒,即高電平5V寬度為1毫秒代表低速(油門通道,舵機(jī)通道舵桿是打到一頭的頂),那剩下的19毫秒是低電平0V;1.5毫秒低表舵機(jī)通道舵桿是打到中心位置,那剩下的18.5毫秒是低電平0V;2毫秒代表高速(油門通道,舵機(jī)通道舵桿是打到另一頭的頂),那剩下的18毫秒是低電平0V,如圖。這樣,發(fā)射端每20毫秒發(fā)射一次,總共可以容納10個比例通道。在接收端,把每個通道分離出來,脈寬信號也是20毫秒更新一次。


    3、對于雙向電調(diào),是以1.5毫秒脈沖寬度為停止點(diǎn),1毫秒脈寬時反轉(zhuǎn)最高速,2毫秒脈寬時正轉(zhuǎn)最高速。


    在接收端分離出各個通道的信號輸出給被控對象:如電調(diào),舵機(jī)等,是不是可以理解為,是PWM(脈寬調(diào)制)信號呢?可以這么說,不能簡單地把接收輸出的控制信號,理解為PWM信號,接收輸出的單通信號可周期可以是18~22毫秒,或者16~25毫秒都可以認(rèn)為是正常的,要求嚴(yán)格的是那個高電平的1~2毫秒的脈沖信號。


    無線遙控就是利用高頻無線電波實(shí)現(xiàn)對模型的控制。Futuba具有自動跳頻抗干擾能力,從理論上講可以讓上百人在同一場地同時遙控自己的模型而不會相互干擾。而且在遙控距離方面也頗具優(yōu)勢,2.4 GHz遙控系統(tǒng)的功率僅僅在100 mW以下,而它的遙控距離可以達(dá)到1km以上。

    每個通道信號脈寬0~2ms,變化范圍為1~2ms之間。1幀PPM信號長度為20ms,理論上最多可以有10個通道,但是同步脈沖也需要時間,模型遙控器最多9個通道。 PPM格式

    總結(jié)

    以上是生活随笔為你收集整理的飞控信号SBUS信号解析为PWM信号输出的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。