2020-01-29 12:14 AM
I am new to this evaluation board, (Nucleo-64 STM32F411), I am working on timer , I need to Update event for every 1s and for every 1 s response from the Timer base I need to toggle the status of the LED.
In the following code I am not able to toggle the LED. I can't figure out what I am missing out with the code weather I need to update something on the code??
// ----------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include "diag/Trace.h"
#include "stm32f4xx.h"
#include "stm32f4xx_hal_tim.h"
// ----------------------------------------------------------------------------
//
// Standalone STM32F4 empty sample (trace via DEBUG).
//
// Trace support is enabled by adding the TRACE macro definition.
// By default the trace messages are forwarded to the DEBUG output,
// but can be rerouted to any device or completely suppressed, by
// changing the definitions required in system/src/diag/trace_impl.c
// (currently OS_USE_TRACE_ITM, OS_USE_TRACE_SEMIHOSTING_DEBUG/_STDOUT).
//
// ----- main() ---------------------------------------------------------------
// Sample pragmas to cope with warnings. Please note the related line at
// the end of this function, used to pop the compiler diagnostics status.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wmissing-declarations"
#pragma GCC diagnostic ignored "-Wreturn-type"
void init_periperalclock()
{
/* Enable GPIO clock */
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; //Port A clock enable
/* Enable USART clock */
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; //TIM2 Enable
}
void init_gpiopins()
{
/* GPIO Configurations for TIMER1 */
GPIOA ->MODER |= GPIO_MODER_MODER0_1;// PA0 Timer channel 1
GPIOA ->OTYPER|= 0;
GPIOA ->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR0_0;
GPIOA ->PUPDR |= GPIO_PUPDR_PUPDR0_0 ;
GPIOA ->AFR[0] |= 0x0001; // PA0 AFR value is AF01 so AFR[0] = 0x0001
uint32_t position = 5;
uint32_t temp = 0x00U;
/* Configure IO Direction mode (Input, Output, Alternate or Analog) */
temp = GPIOA->MODER; //0xa8000000 -- 10101000000000000000000000000000
temp &= ~(GPIO_MODER_MODER0 << (position * 2U)); // 001111111111 // temp res = 0000000000000000000000000000000
temp |= ((1 & 3) << (position * 2U)); // 10000000000
GPIOA->MODER = temp; // temp res = 000000000000000000010000000000 // act data sheet val 1024 // GP Output mode
/* Configure the IO Speed */
temp = GPIOA->OSPEEDR; //0x0C000000 -- 1100000000000000000000000000
temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2U)); // temp res = 00000000000000000000000000000000
temp |= (2 << (position * 2U)); // 100000000000 // temp res = 00000000000000000000100000000000
GPIOA->OSPEEDR = temp;
/* Configure the IO Output Type */
temp = GPIOA->OTYPER;
temp &= ~(GPIO_OTYPER_OT_0 << position) ; // 01111 & 00000 --> 00000
temp |= (((1 & 0x00000010U) >> 4U) << position); // ((0>>4)<<5)
GPIOA->OTYPER = temp;
/* Activate the Pull-up or Pull down resistor for the current IO */
temp = GPIOA->PUPDR; //0x64000000 - 1100100000000000000000000000000
temp &= ~(GPIO_PUPDR_PUPDR0 << (position * 2U)); // temp res = 00000000000000000000000000000000
temp |= ((1) << (position * 2U)); //temp == 10000000000
GPIOA->PUPDR = temp;
}
void init_timerConfiguration()
{
TIM2 ->PSC = (uint16_t) (SystemCoreClock / 8000000) - 1; //Setting up the pre-scalar value can be 1
//Configure the Internal Clock source
TIM2->SMCR &= ~TIM_SMCR_SMS; // Internal clock source
TIM2-> CR1 |= TIM_CR1_CEN;
//Select the up counter mode
TIM2->CR1 |= TIM_COUNTERMODE_UP;
TIM2->CR1 &= ~TIM_CR1_CKD;
// Set the clock division to 1
TIM2->CR1 |= TIM_CLOCKDIVISION_DIV1;
//Set the Autoreload value
TIM2->ARR = 49999;//PERIOD
// Generate an update event to reload the Prescaler value immediately
TIM2->EGR = TIM_EGR_UG;
TIM2->CCMR1 &= ~TIM_CCMR1_CC2S;
TIM2 ->RCR |= ~TIM_RCR_REP;
TIM2 ->SR = 0;
}
int
main(int argc, char* argv[])
{
init_periperalclock();
init_gpiopins();
init_timerConfiguration();
// Infinite loop
while (1)
{
while((TIM2->SR & TIM_DIER_UIE))
{
GPIOA->ODR ^= GPIO_PIN_5;
}
}
}
#pragma GCC diagnostic pop
2020-01-29 03:38 AM
> while((TIM2->SR & TIM_DIER_UIE))
> {
> GPIOA->ODR ^= GPIO_PIN_5;
> }
Why are you masking TIMx_SR bits by a constant related to TIM_DIER ?
Nonetheless, when update happens, the LED starts to toggle and this loop loops forever, as there's nothing which would stop toggling it. Observe it by an oscilloscope, as it blinks too fast for you to see.
JW
2020-01-29 09:32 AM
To answer the actual question, what you are missing is the clearing of the status register bit after checking it.
if(TIM2->SR & TIM_SR_UIF) { // as suggested by JW above
TIM2->SR &= ~TIM_SR_UIF); // clear update status
GPIOA->ODR ^= GPIO_PIN_5;
}
See the description of the SR register in the reference manual for details.
2020-01-29 10:44 PM
Hi berendi,
I had tried clearing the SR register after posting this and It is working fine. Thanks waclawek
regards,
Naveen