2020-04-28 04:56 PM
Hi all!
I'm trying to measure a PWM frequency signal using the input capture channel 1 of TIM3, but it won't work.
i'm using NUCLEO F446RE board, here is my code:
#include "stm32f4xx.h" // Device header
#include "lcd_H.h"
int main(void)
{
uint16_t capt1 = 0, capt2 = 0;
uint8_t lock = 1;
float Freq = 0.00;
//Clock Setup
RCC ->CR |= 1 << 18; //Enable bypass HSE
RCC ->CR |= 1 << 16; //Enable HSE
while(!(RCC ->CR & (1 << 17))); //wait HSE is ready
RCC ->CFGR &= ~(1 << 1); //HSE is used as system clock
RCC ->CFGR |= 1 << 0;
/**************************************************************************************/
//Configure PA6 as Input Capture channel 1
RCC ->AHB1ENR |= 1 << 0; //Enable clock for GPIOA
GPIOA ->MODER &= ~(1 << 12); //PA6 is used as Alternate function Mode: 10
GPIOA ->MODER |= (1 << 13);
GPIOA ->PUPDR &= ~(1 << 12); //Pull Down in PA6 : 10
GPIOA ->PUPDR |= (1 << 13);
GPIOA ->AFR[0] |= 1 << 24; //PA6 is Alternate function 1: 0001
/**************************************************************************************/
//Configure TIM3
LcdInit();
RCC ->APB1ENR |= 1 << 1; //Enable clock for TIM3
TIM3 ->ARR = 0xFFFF;
TIM3 ->PSC = 0;
TIM3 ->CR1 |= 1 << 0; //Enable counter
TIM3 ->CCMR1 = 0x01; //01: CC1 channel is configured as input, IC1 is mapped on TI1
//IC1F: 0000 No filter, sampling is done at fDTS
//IC1PSC: Input capture 1 prescaler: 00 no prescaler, capture is done each time an edge is detected on the capture input
TIM3 ->CCER |= (1 << 0); //1: Capture enabled
//positive edge
/**************************************************************************************/
while(1)
{
TIM3 ->SR &= ~(1 << 1); //CLEAR Flag
while(!(TIM3 ->SR & (1 << 1))); //Wait a capture occurs
if(lock){
capt1 = TIM3 ->CCR1;
lock = 0;
}
else{
capt2 = TIM3 ->CCR1;
if(capt2 > capt1)
{
Freq = capt2 - capt1;
}
else{
Freq = ((0xffff-capt1)+capt2) +1;
}
Freq = (float)8000000.00/Freq;
//Print value in the LCD
LcdSendData(0x01, COMMAND_MODE); //Clear LCD
LcdSetCursor(1, 1);
LcdSendString("F=");
LcdPrintfloat(Freq);
LcdSendString("Hz");
lock = 1;
}
}
}
In debugging the code stuck here while(!(TIM3 ->SR & (1 << 1))); please any help?
Thank you.
Solved! Go to Solution.
2020-04-28 10:30 PM
Read back the registers, all of them. Do they contain what you expect?
There should be a few cycles delay after enabling peripheral clocks in RCC (see Delay after an RCC peripheral clock enabling in the errata). I'd just change the order of initialization
RCC ->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; //Enable clock for GPIOA
RCC ->APB1ENR |= RCC_APB1ENR_TIM3EN; //Enable clock for TIM3, provides the required delay
//Configure GPIO
//Configure TIM3
Enable the counter i.e. TIM_CR1_CEN as the last thing after all other timer registers are set up.
Check PA6 - TIM3 mapping in the Alternate function table of the datasheet.
2020-04-28 05:37 PM
Enable CC1IE in DIER.
TIMx->DIER |= TIM_DIER_CC1IE
2020-04-28 08:49 PM
It doesn't work! And i don't want to use interrupt.
2020-04-28 10:30 PM
Read back the registers, all of them. Do they contain what you expect?
There should be a few cycles delay after enabling peripheral clocks in RCC (see Delay after an RCC peripheral clock enabling in the errata). I'd just change the order of initialization
RCC ->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; //Enable clock for GPIOA
RCC ->APB1ENR |= RCC_APB1ENR_TIM3EN; //Enable clock for TIM3, provides the required delay
//Configure GPIO
//Configure TIM3
Enable the counter i.e. TIM_CR1_CEN as the last thing after all other timer registers are set up.
Check PA6 - TIM3 mapping in the Alternate function table of the datasheet.
2020-04-28 11:56 PM
> GPIOA ->AFR[0] |= 1 << 24; //PA6 is Alternate function 1: 0001
Exactly as berendi said above:
JW
2020-04-29 05:05 AM
Thank you guys for the help, now it's working very well!