Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: pwm_input/pwmin.cpp
- Revision:
- 0:528f6a3352b9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pwm_input/pwmin.cpp Thu May 10 04:44:46 2018 +0000 @@ -0,0 +1,253 @@ +/*************************************************************** +功能 : 航模接收机PWM脉宽测量程序 +作者 : 王若溪 +邮箱 : thuwrx10[at]gmail[dot]com +声明 : +本程序仅供学习与交流使用,如需他用,须联系作者 +本程序可以随意更改,但须保留本信息页 +All rights reserved +2018.5.2 +***************************************************************/ + +#include "pwmin.h" + +extern Serial pc; +const uint16_t timerPeriod = 40000 - 1; // 单位为微秒,实际数字减1 +const int16_t widthUpperBound = 2200; +const int16_t widthLowerBound = 800; + +int16_t tim3IC1Width=0; //定时器3通道1脉宽,单位为微秒 +int16_t tim3IC2Width=0; //定时器3通道2脉宽 +int16_t tim3IC3Width=0; //定时器3通道3脉宽 +int16_t tim3IC4Width=0; //定时器3通道4脉宽 +int16_t tim1IC2Width=0; +int16_t tim1IC3Width=0; + +TIM_HandleTypeDef htim1, htim3; +// + +void TIM1_3_Config(void) +{ + + TIM_IC_InitTypeDef TIM_ICInitStructure; + + htim3.Instance = TIM3; + htim3.Init.Period = timerPeriod; + htim3.Init.Prescaler = (uint16_t) (SystemCoreClock / 1000000) - 1; //1微秒 + htim3.Init.ClockDivision = 0; + htim3.Init.CounterMode = TIM_COUNTERMODE_UP; + HAL_TIM_IC_Init(&htim3); + + TIM_ICInitStructure.ICPolarity = TIM_ICPOLARITY_FALLING; + TIM_ICInitStructure.ICSelection = TIM_ICSELECTION_DIRECTTI; + TIM_ICInitStructure.ICPrescaler = TIM_ICPSC_DIV1; + TIM_ICInitStructure.ICFilter = 0x0; + HAL_TIM_IC_ConfigChannel(&htim3, &TIM_ICInitStructure, TIM_CHANNEL_1); //配置各个通道的极性等 + HAL_TIM_IC_ConfigChannel(&htim3, &TIM_ICInitStructure, TIM_CHANNEL_2); + HAL_TIM_IC_ConfigChannel(&htim3, &TIM_ICInitStructure, TIM_CHANNEL_3); + HAL_TIM_IC_ConfigChannel(&htim3, &TIM_ICInitStructure, TIM_CHANNEL_4); + + HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1); //使能各通道的输入捕获中断 + HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2); + HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_3); + HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_4); + + htim1.Instance = TIM1; //换成TIM1再来一遍 + htim1.Init.Period = timerPeriod; + htim1.Init.Prescaler = (uint16_t) (SystemCoreClock / 1000000) - 1; //1微秒 + htim1.Init.ClockDivision = 0; + htim1.Init.CounterMode = TIM_COUNTERMODE_UP; + HAL_TIM_IC_Init(&htim1); + HAL_TIM_IC_ConfigChannel(&htim1, &TIM_ICInitStructure, TIM_CHANNEL_2); + HAL_TIM_IC_ConfigChannel(&htim1, &TIM_ICInitStructure, TIM_CHANNEL_3); + HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2); + HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_3); +} + +void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim) //自己定义此函数,这个函数已在别处声明,会被HAL_TIM_IC_Init调用。 +{ + GPIO_InitTypeDef GPIO_InitStructure; + if (htim->Instance == TIM3) + { + __HAL_RCC_TIM3_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + + GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7; + GPIO_InitStructure.Mode = GPIO_MODE_INPUT; + GPIO_InitStructure.Pull = GPIO_PULLDOWN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); + + GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); + + HAL_NVIC_SetPriority(TIM3_IRQn, 1, 0); + HAL_NVIC_EnableIRQ(TIM3_IRQn); + } + + if (htim->Instance == TIM1) + { + __HAL_RCC_TIM1_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + + GPIO_InitStructure.Pin = GPIO_PIN_9 | GPIO_PIN_10; + GPIO_InitStructure.Mode = GPIO_MODE_INPUT; + GPIO_InitStructure.Pull = GPIO_PULLDOWN; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); + + HAL_NVIC_SetPriority(TIM1_CC_IRQn, 2, 0); + HAL_NVIC_EnableIRQ(TIM1_CC_IRQn); + } +} + +//自己实现一个名为HAL_TIM_IC_CaptureCallback的函数。它要被HAL_TIM_IRQHandler调用。 +//另外需要将HAL_TIM_IRQHandler加入相关的中断处理函数中,见stm32f1xx_it.c +void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) +{ + static int16_t temp; + static uint16_t tim1PrevIC2Value, tim1PrevIC3Value, tim3PrevIC1Value, tim3PrevIC2Value, tim3PrevIC3Value, tim3PrevIC4Value; //上升沿时计数器的值 + static uint16_t tim1CurIC2Value, tim1CurIC3Value, tim3CurIC1Value, tim3CurIC2Value, tim3CurIC3Value, tim3CurIC4Value; // 下降沿时计数器的值 + + if (htim->Instance == TIM1) + { + if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + if(!(TIM1->CCER & 0x0020)) // 发生了上升沿 + { + tim1PrevIC2Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); + TIM1->CCER |= 0x0020; // 改为下降沿触发以迎接下降沿 + } + else + { + tim1CurIC2Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); + temp = tim1CurIC2Value - tim1PrevIC2Value; + if (temp < 0) // 上升沿和下降沿之间计数器走完了一个循环 + temp += timerPeriod; + if (temp > widthLowerBound && temp < widthUpperBound) // 检查是否超限 + tim1IC2Width=temp; + +// Tim3_ser1.printf("tim1IC2Width:%f\ttim1IC3Width:%f\n",tim1IC2Width,tim1IC3Width); + + TIM1->CCER &= ~0x0020; // 改回上升沿触发 + } + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + } + + if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + if(!(TIM1->CCER & 0x0200)) // Rising Edge + { + tim1PrevIC3Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3); + TIM1->CCER |= 0x0200; + } + else + { + tim1CurIC3Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3); + temp = tim1CurIC3Value - tim1PrevIC3Value; + if (temp < 0) // 上升沿和下降沿之间计数器走完了一个循环 + temp += timerPeriod; + if (temp > widthLowerBound && temp < widthUpperBound) + tim1IC3Width=temp; +// Tim3_ser1.printf("tim1IC2Width:%f\ttim1IC3Width:%f\n",tim1IC2Width,tim1IC3Width); + TIM1->CCER &= ~0x0200; + } + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + } + + } + + if (htim->Instance == TIM3) + { + if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + if(!(TIM3->CCER & 0x0002)) // Rising Edge + { + tim3PrevIC1Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); + TIM3->CCER |= 0x0002; + } + else + { + tim3CurIC1Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); + temp = tim3CurIC1Value - tim3PrevIC1Value; + if (temp < 0) // 上升沿和下降沿之间计数器走完了一个循环 + temp += timerPeriod; + if (temp > widthLowerBound && temp < widthUpperBound) + tim3IC1Width=temp; +// Tim3_ser1.printf("tim3IC1Width:%f\ttim3IC2Width:%f\n",tim3IC1Width,tim3IC2Width); + TIM3->CCER &= ~0x0002; + } + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + } + + if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + if(!(TIM3->CCER & 0x0020)) // Rising Edge + { + tim3PrevIC2Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); + TIM3->CCER |= 0x0020; + } + else + { + tim3CurIC2Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); + temp = tim3CurIC2Value - tim3PrevIC2Value; + if (temp < 0) // 上升沿和下降沿之间计数器走完了一个循环 + temp += timerPeriod; + if (temp > widthLowerBound && temp < widthUpperBound) + tim3IC2Width=temp; +// Tim3_ser1.printf("tim3IC1Width:%f\ttim3IC2Width:%f\n",tim3IC1Width,tim3IC2Width); + TIM3->CCER &= ~0x0020; + } + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + } + + if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + if(!(TIM3->CCER & 0x0200)) // Rising Edge + { + tim3PrevIC3Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3); + TIM3->CCER |= 0x0200; + } + else + { + tim3CurIC3Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3); + temp = tim3CurIC3Value - tim3PrevIC3Value; + if (temp < 0) // 上升沿和下降沿之间计数器走完了一个循环 + temp += timerPeriod; + if (temp > widthLowerBound && temp < widthUpperBound) + tim3IC3Width=temp; +// Tim3_ser1.printf("tim3IC3Width:%f\ttim3IC4Width:%f\n",tim3IC3Width,tim3IC4Width); + TIM3->CCER &= ~0x0200; + } + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + } + + if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + if(!(TIM3->CCER & 0x2000)) // Rising Edge + { + tim3PrevIC4Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_4); + TIM3->CCER |= 0x2000; + } + else + { + tim3CurIC4Value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_4); + temp = tim3CurIC4Value - tim3PrevIC4Value; + if (temp < 0) // Overflow occurred during rising edge and falling edge + temp += timerPeriod; + if (temp > widthLowerBound && temp < widthUpperBound) + tim3IC4Width=temp; +// Tim3_ser1.printf("tim3IC3Width:%f\ttim3IC4Width:%f\n",tim3IC3Width,tim3IC4Width); + TIM3->CCER &= ~0x2000; + } + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + } + } +} \ No newline at end of file