2019-12-16 08:04 AM
#include "stm32f4xx.h" // Device header
// Trying to use the General Purpose Timer (TIM2) to create a 1 second delay
// Board External Crystal 8.0 MHz
// Port A Pin 0 Output
// The program should output a high on GPIOA Pin 0 and delay 1 second then output low and delay 1 second.
int main(void){
RCC->AHB1ENR |= 0x00000001; //Enable Clock to PortA
GPIOA->MODER |= 0x00000001; //General Purpose IO for PortA Pin 0
//TIM2 Configuration
RCC->APB1ENR |= 0x00000001; Enable Clock to TIM2
TIM2->PSC = 8000-1;
TIM2->ARR = 10000 - 1;
TIM2->CNT = 0;
TIM2->CR1 = 0x00000001;
while(1){
while((!TIM2->SR & 1)){
GPIOA->ODR ^= 0x00000001; // Output high/low on Pin0 PortA
}
}
}
Would like to know how to calculate the values that should be inserted in TIM2->PSC, TIM2->ARR, and TIM2->CNT. Is there a formula to calculate the values. Also what values must be added to the registers in the above program to make it a 1 second delay. The program runs but the LED doesn't blink, its just ON.
Solved! Go to Solution.
2019-12-16 01:24 PM
> How did you know its 10 seconds?
Clive just assumed that that your system clock is either the default 16MHz HSI or as the comment in code says, 8MHz HSE; and that there are no dividers on the APB buses or they are equal to 2 which means the timers run at the same clock as the system clock.
Then, update (i.e. "oveflow") rate of the timer is
fUPDATE = fCLK_IN / (PSC + 1) / (ARR + 1)
so that's in your case 8'000'000Hz/8'000/10'000 = 0.1Hz (or twice that if the 16MHz is the system clock). That's 10s (or 5s) pulse followed by 10s (5s) space if you toggle the output as above.
> Which register is the Update flag is in?
Clive means TIMx_SR.UIF, the flag you are testing:
while((!TIM2->SR & 1)){
GPIOA->ODR ^= 0x00000001; // Output high/low on Pin0 PortA
}
If you don't clear it, it will remain set, so then the while cycle is exit immediately and the pin will toggle at an extremely high rate, hundreds of kHz - invisible by naked eye. Use an oscilloscope/logic analyzer (LA) to observe the output.
Clear the flag by writing 0 into it.
OTOH, if you'd just clear the flag, the output would again toggle rapidly while it's 0. You want this:
while(1) { // an infinite loop
while((TIM2->SR & TIM_SR_UIF) == 0); // wait until TIM2_SR.UIF gets set, when the timer overflows
TIM2->SR = ~TIM_SR_UIF; // clear the flag
GPIOA->ODR ^= 0x00000001; // Output high/low on Pin0 PortA
}
JW
2019-12-16 08:19 AM
Looks to be 10 seconds
You will need to explicitly clear the Update flag.
2019-12-16 09:10 AM
How did you know its 10 seconds? What formula did you use to know that its a 10 second delay. Which register is the Update flag is in?
2019-12-16 01:24 PM
> How did you know its 10 seconds?
Clive just assumed that that your system clock is either the default 16MHz HSI or as the comment in code says, 8MHz HSE; and that there are no dividers on the APB buses or they are equal to 2 which means the timers run at the same clock as the system clock.
Then, update (i.e. "oveflow") rate of the timer is
fUPDATE = fCLK_IN / (PSC + 1) / (ARR + 1)
so that's in your case 8'000'000Hz/8'000/10'000 = 0.1Hz (or twice that if the 16MHz is the system clock). That's 10s (or 5s) pulse followed by 10s (5s) space if you toggle the output as above.
> Which register is the Update flag is in?
Clive means TIMx_SR.UIF, the flag you are testing:
while((!TIM2->SR & 1)){
GPIOA->ODR ^= 0x00000001; // Output high/low on Pin0 PortA
}
If you don't clear it, it will remain set, so then the while cycle is exit immediately and the pin will toggle at an extremely high rate, hundreds of kHz - invisible by naked eye. Use an oscilloscope/logic analyzer (LA) to observe the output.
Clear the flag by writing 0 into it.
OTOH, if you'd just clear the flag, the output would again toggle rapidly while it's 0. You want this:
while(1) { // an infinite loop
while((TIM2->SR & TIM_SR_UIF) == 0); // wait until TIM2_SR.UIF gets set, when the timer overflows
TIM2->SR = ~TIM_SR_UIF; // clear the flag
GPIOA->ODR ^= 0x00000001; // Output high/low on Pin0 PortA
}
JW