2020-11-13 12:31 AM
Greetings
I have attempted to write an application, to toggle the LD4 LED (On PD12) on the STM32F407VGTx Discovery board. I am toggling the LED, on interrupt, when the timer overflows. I have placed the HAL_GPIO_Toggle() in the HAL_TIM_PeriodElapsedCallback() function. The LED is never be toggled. I have tried placing the Toggle function in the TIM6 IRQ handler itself and it works fine. I've also experimented with PWM recently and the HAL_OC_DelayElapsedCallback(), and the code is always executed. The Period_ElapsedCallback() function is the only problematic. Any help would be appreciated, to show where I'm going wrong.
Msp.c
void HAL_MspInit(void)
{
__HAL_RCC_SYSCFG_CLK_ENABLE();
_HAL_RCC_PWR_CLK_ENABLE();
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
}
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef GPIO_USART1;
//1. Enable clock for usart2 peripheral and GPIOB
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
//2. Do pin mux config(involves initialising pins for USART RX and TX)
GPIO_USART1.Pin = GPIO_PIN_6; //UART1 TX
GPIO_USART1.Mode = GPIO_MODE_AF_PP;
GPIO_USART1.Pull = GPIO_PULLUP;
GPIO_USART1.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_USART1.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOB, &GPIO_USART1);
GPIO_USART1.Pin = GPIO_PIN_7; //UART1 RX
HAL_GPIO_Init(GPIOB, &GPIO_USART1);
//3. enable IRQ and set up priority (NVIC settings)
HAL_NVIC_EnableIRQ(USART1_IRQn);
HAL_NVIC_SetPriority(USART1_IRQn, 15, 0);
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *tim_baseHandle){
if(tim_baseHandle->Instance==TIM6)
{
/* USER CODE BEGIN TIM6_MspInit 0 */
/* USER CODE END TIM6_MspInit 0 */
/* TIM6 clock enable */
__HAL_RCC_TIM6_CLK_ENABLE();
/* TIM6 interrupt Init */
HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
/* USER CODE BEGIN TIM6_MspInit 1 */
/* USER CODE END TIM6_MspInit 1 */
}
}
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM6)
{
/* USER CODE BEGIN TIM6_MspDeInit 0 */
/* USER CODE END TIM6_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM6_CLK_DISABLE();
/* TIM6 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM6_DAC_IRQn);
/* USER CODE BEGIN TIM6_MspDeInit 1 */
/* USER CODE END TIM6_MspDeInit 1 */
}
}
main.c
void UART1_Init(void);
void ErrorHandler(void);
void SystemClockConfig(void);
void GPIO_LED(void);
void TIMER6_INIT();
void HAL_IncTick();
UART_HandleTypeDef H_UART1 = {0}; //handle variable for the asynchronous USART2 periperhal config
TIM_HandleTypeDef tim6 = {0};
extern char Data[];
int main(void){
HAL_Init();
SystemClockConfig();
UART1_Init();
GPIO_LED();
TIMER6_INIT();
TIM6 -> SR = 0;
while(1){}
return 0;
}
void SystemClockConfig(void){
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
ErrorHandler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
ErrorHandler();
}
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
void UART1_Init(void){ //high level initialisation
//this is done to initialise the handle to the base address of the peripheral
H_UART1.Instance = USART1; //linking
H_UART1.Init.BaudRate = 115200;
H_UART1.Init.WordLength = UART_WORDLENGTH_8B;
H_UART1.Init.StopBits = UART_STOPBITS_1;
H_UART1.Init.Parity = UART_PARITY_NONE;
H_UART1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
H_UART1.Init.Mode = UART_MODE_TX_RX;
if (HAL_UART_Init(&H_UART1) != HAL_OK)//problem occured
{
//(HAL_OK is a keyword found in the init function, which has a structure for the status of the init after you try to initialise)
ErrorHandler();
}
}
void ErrorHandler(void){
while(1);
}
/*
* basic timer initialisation. always counts up
*/
void TIMER6_INIT(void){
TIM_MasterConfigTypeDef sMasterConfig = {0};
tim6.Instance = TIM6;
tim6.Init.Prescaler = 8400;
tim6.Init.CounterMode = TIM_COUNTERMODE_UP;
tim6.Init.Period = 1000-1;
tim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if(HAL_TIM_Base_Init(&tim6) == HAL_OK){
return HAL_TIM_Base_Start_IT(&tim6);
}
}
void GPIO_LED(void){
GPIO_InitTypeDef gpioLED = {0};
__HAL_RCC_GPIOD_CLK_ENABLE();
gpioLED.Mode = GPIO_MODE_OUTPUT_PP;
gpioLED.Pin = GPIO_PIN_12 | GPIO_PIN_13;
gpioLED.Pull = GPIO_NOPULL;
gpioLED.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOD, &gpioLED);
}
void HAL_TIM_PeriodElaspedCallback(TIM_HandleTypeDef *timer){
if(timer->Instance == TIM6){
if(TIM6 -> SR & TIM_SR_UIF){
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);
TIM6->SR = ~(TIM_SR_UIF);
}
}
}
it.c
extern TIM_HandleTypeDef tim6;
extern UART_HandleTypeDef H_UART1;
extern char Data[50];
void SysTick_Handler(void){
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
}
void TIM6_DAC_IRQHandler(void){
#include "main.h"
extern TIM_HandleTypeDef tim6;
extern UART_HandleTypeDef H_UART1;
extern char Data[50];
void SysTick_Handler(void){
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
}
void TIM6_DAC_IRQHandler(void){
HAL_TIM_IRQHandler(&tim6);
}
Solved! Go to Solution.
2020-11-14 01:39 AM
2020-11-13 05:59 AM
> if(TIM6 -> SR & TIM_SR_UIF){
The flags are cleared in HAL_TIM_IRQHandler. If it's made it to HAL_TIM_PeriodElaspedCallback, then you already know it's an update interrupt.
Within HAL_TIM_IRQHandler:
/* TIM Update event */
if(__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
{
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) !=RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
HAL_TIM_PeriodElapsedCallback(htim);
}
}
2020-11-13 07:03 AM
Thank you for looking through my code.
However, I have also tried removing the code segment, that checks if the flag has been set and the flag-reset from the TIM_PeriodElapsedCallback() and it still does not seem to work. Initially, I just checked if the instance of the timer is TIM6, and I toggled my LED, like below, which was to no avail.
void HAL_TIM_PeriodElaspedCallback(TIM_HandleTypeDef *timer){
if(timer->Instance == TIM6){
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);
}
}
2020-11-14 01:39 AM
> HAL_TIM_PeriodElaspedCalllback
Elasped ?
JW
2020-11-14 02:33 AM
Good catch! I wonder how do people get such errors. It seems that they use copy-paste where they shouldn't (ST's example code) and do not use it where they really should use it (function names etc.). :)
2020-11-14 11:15 PM
For that mistake, I wish the ground could swallow me up.. Thank you @Community member .
2020-11-15 03:48 AM
There are only two kinds of software developers: those who make this type of errors, and those who don't admit it.
JW