|
转自:tedeum
发现官方有个例子,固件库里面自带PWM输入功能,经调试稳定可用,代码如下:
C代码 [url=][/url]
- //计时器和gpio口的初始化
- GPIO_InitTypeDef GPIO_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
-
- /* TIM2 clock enable */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
-
- /* GPIOB clock enable */
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
-
- /* TIM2 chennel2 configuration : PA.01 */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
- 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(GPIOA, &GPIO_InitStructure);
-
- /* Connect TIM pin to AF1 */
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_1);
-
- /* Enable the TIM2 global Interrupt */
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
-
- TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
- TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
- TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
- TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
- TIM_ICInitStructure.TIM_ICFilter = 0x0;
-
- TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
-
- /* Select the TIM2 Input Trigger: TI2FP2 */
- TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
-
- /* Select the slave Mode: Reset Mode */
- TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
- TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);
-
- /* TIM enable counter */
- TIM_Cmd(TIM2, ENABLE);
-
- /* Enable the CC2 Interrupt Request */
- TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
相关中断函数如下:
C代码 [url=][/url]
- void TIM2_IRQHandler(void)
- {
- RCC_GetClocksFreq(&RCC_Clocks);
-
- /* Clear TIM2 Capture compare interrupt pending bit */
- TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
-
- /* Get the Input Capture value */
- IC2Value = TIM_GetCapture2(TIM2);
-
- if (IC2Value != 0)
- {
- /* Duty cycle computation */
- DutyCycle = (TIM_GetCapture1(TIM2) * 100) / IC2Value;
-
- /* Frequency computation
- TIM2 counter clock = (RCC_Clocks.HCLK_Frequency)/2 */
-
- Frequency = RCC_Clocks.HCLK_Frequency / IC2Value;
- }
- else
- {
- DutyCycle = 0;
- Frequency = 0;
- }
- }
这个方法经测试,是简单好用的,但根据资料表明这个是通道1和通道2配合实现,其他资料也没有说明如何捕获多个通道,是否能用3和4通道配合捕获,是否1个定时器能捕获2个通道。于是网上查到另一种方法可以1个定时器捕获4个通道,但是待测试,记录如下:
C代码 [url=][/url]
- // STM32 TIM2 4 Channel Input Capture STM32F0-Discovery - sourcer32@gmail.com
-
- #include "stm32f0xx.h"
- #include "stm32f0_discovery.h"
-
- //**************************************************************************************
-
- void TIM2_Config(void)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_ICInitTypeDef TIM_ICInitStructure;
-
- /* TIM2 Periph clock enable */
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
-
- /* TIM2 Configuration */
- TIM_DeInit(TIM2);
-
- /* Time base configuration */
- TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
- TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / 1000000) - 1; // 1 MHz, from 48 MHz
- TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF; // Maximal, TIM2 is 32-bit counter
- TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
-
- TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; // Rising/Falling/BothEdge
- TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
- TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
- TIM_ICInitStructure.TIM_ICFilter = 0x0;
-
- TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
- TIM_ICInit(TIM2, &TIM_ICInitStructure);
- TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
- 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);
-
- /* TIM1 enable counter */
- TIM_Cmd(TIM2, ENABLE);
-
- /* Enable the CCx Interrupt Request */
- TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);
- }
-
- //**************************************************************************************
-
- volatile uint32_t Freq[4];
-
- void TIM2_IRQHandler(void)
- {
- uint32_t Current, Delta;
- static uint32_t Last[4];
-
- if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
- {
- /* Clear TIM2_CH1 Capture compare interrupt pending bit */
- TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
-
- Current = TIM_GetCapture1(TIM2);
- Delta = Current - Last[0];
- Last[0] = Current;
- if (Delta)
- Freq[0] = 1000000 / Delta; // 1MHz clock
-
- // ..
- }
-
- if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)
- {
- /* Clear TIM2_CH2 Capture compare interrupt pending bit */
- TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
-
- Current = TIM_GetCapture2(TIM2);
- Delta = Current - Last[1];
- Last[1] = Current;
- if (Delta)
- Freq[1] = 1000000 / Delta; // 1MHz clock
-
- // ..
- }
-
- if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)
- {
- /* Clear TIM2_CH3 Capture compare interrupt pending bit */
- TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
-
- Current = TIM_GetCapture3(TIM2);
- Delta = Current - Last[2];
- Last[2] = Current;
- if (Delta)
- Freq[2] = 1000000 / Delta; // 1MHz clock
-
- // ..
- }
-
- if (TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET)
- {
- /* Clear TIM2_CH4 Capture compare interrupt pending bit */
- TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);
-
- Current = TIM_GetCapture4(TIM2);
- Delta = Current - Last[3];
- Last[3] = Current;
- if (Delta)
- Freq[3] = 1000000 / Delta; // 1MHz clock
-
- // ..
- }
- }
-
- //**************************************************************************************
-
- void NVIC_Config(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
-
- /* Enable and set TIM2 Interrupt */
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
-
- //**************************************************************************************
-
- void GPIO_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- /* GPIOA Periph clock enable */
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
-
- /* Configure TIM2 input */
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
- 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_NOPULL;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- /* Connect TIM pins to AF2 */
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_2); // TIM2_CH1 PA5
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_2); // TIM2_CH2 PA1
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_2); // TIM2_CH3 PA2
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_2); // TIM2_CH4 PA3
- }
-
- //**************************************************************************************
-
- int main(void)
- {
- NVIC_Config();
-
- GPIO_Config();
-
- TIM2_Config();
-
- while(1); /* Infinite loop */
- }
还有另外一种方法待测试: C代码 [url=][/url]
- // 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 );
- }
- }
|
|
|
|
|
加EE小助手好友, 入技术交流群 |
EE服务号 精彩活动e手掌握 |
EE订阅号 热门资讯e网打尽 |
聚焦汽车电子软硬件开发 认真关注技术本身 |
|