在了解遥控数据交换协议之前,首先对常用的协议有所了解,推荐一篇科普文章:
http://www.docin.com/p-680140417.html
若该链接无效可以搜索关键字“APM PX4飞控开发笔记-第五章:PWM、PPM与S.bus”
之后选择自己需要的协议进行设计,我用的是PWM,所以需要通过定时器对脉冲宽度进行读取。具体代码如下,这并不是我写的,但经测试,可以使用。
- // Hold onto the Channel 1 init structure -- we will use it to reverse
- // polarity on every edge interrupt.
- static TIM_ICInitTypeDef TIM_CH1_ICInitStructure;
-
- #define GPIO_AF_TIM2 GPIO_AF_2
-
- void ConfigPwmIn() {
- GPIO_InitTypeDef GPIO_InitStructure;
- TIM_ICInitTypeDef TIM_ICInitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
-
- TIM_DeInit(TIM2 );
-
- /* TIM2 clock enable */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
-
- /* GPIOC clock enable */
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
-
- /* TIM2 GPIO pin configuration : CH1=PD3, C2=PD4, CH3=PD7, CH4=PD6 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_7 | GPIO_Pin_6;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
-
- /* Connect pins to TIM3 AF2 */
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource3, GPIO_AF_TIM2 );
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_TIM2 );
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_TIM2 );
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_TIM2 );
-
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
-
- /* Enable capture*/
- TIM_CH1_ICInitStructure.TIM_Channel = TIM_Channel_1;
- TIM_CH1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
- TIM_CH1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
- TIM_CH1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
- TIM_CH1_ICInitStructure.TIM_ICFilter = 0;
- TIM_ICInit(TIM2, &TIM_ICInitStructure);
- TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
- TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
- TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
- TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
- TIM_ICInitStructure.TIM_ICFilter = 0;
- TIM_ICInit(TIM2, &TIM_ICInitStructure);
- TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
- TIM_ICInit(TIM2, &TIM_ICInitStructure);
- TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
- TIM_ICInit(TIM2, &TIM_ICInitStructure);
-
- /* Enable TIM2 */
- TIM_Cmd(TIM2, ENABLE);
-
- /* Enable CC1-4 interrupt */
- TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);
-
- /* Clear CC1 Flag*/
- TIM_ClearFlag(TIM2, TIM_FLAG_CC1 | TIM_FLAG_CC2 | TIM_FLAG_CC3 | TIM_FLAG_CC4 );
- }
-
- static volatile uint32_t ccr[4];
- static volatile char pulseState = 0;
-
- void TIM2_IRQHandler() {
- if (TIM2 ->SR & TIM_IT_CC1 ) {
- TIM2 ->SR &= (~TIM_IT_CC1 );
-
- if (pulseState == 0) {
- TIM_CH1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
-
- // Any time we get a rising edge on CH1, we reset the counter. All channels are
- // phase aligned, so they all use this as a reference.
- TIM_SetCounter(TIM2, 0);
- } else {
- TIM_CH1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
-
- // Pull the value on the falling edge.
- ccr[0] = TIM_GetCapture1(TIM2 );
- }
- pulseState = !pulseState;
-
- // Reverse polarity.
- TIM_ICInit(TIM2, &TIM_CH1_ICInitStructure);
- }
-
- if (TIM2 ->SR & TIM_IT_CC2 ) {
- TIM2 ->SR &= (~TIM_IT_CC2 );
- ccr[1] = TIM_GetCapture2(TIM2 );
- }
- if (TIM2 ->SR & TIM_IT_CC3 ) {
- TIM2 ->SR &= (~TIM_IT_CC3 );
- ccr[2] = TIM_GetCapture3(TIM2 );
- }
- if (TIM2 ->SR & TIM_IT_CC4 ) {
- TIM2 ->SR &= (~TIM_IT_CC4 );
- ccr[3] = TIM_GetCapture4(TIM2 );
- }
- }
复制代码以上代码来自《
stm32 pwm捕获学习笔记》,该Blog中列出了几种测量方式,可以根据需要选择合适的加以运用。
获取了PWM脉冲宽度,就可以归一化处理后加入控制。