Search code examples
carmcortex-mstm32f4

Header files for STM32F439 timer interrupts


I wrote the following code to program a STM32F439 microcontroller based on the ARM Cortex-M4 processor core. I defined a timer interrupt handler that is triggered every time when TIM7 counts to the end of 1 second so that it executes a specified piece of code every second. The contents of functions InitRCC() (which initialises RCC to enable GPIOs) and ConfGPIO() (which configures GPIO pins) are omitted.

#include "main.h"
#include "stm32f439xx.h"
#include "core_cm4.h"
#include "gpioControl.h"

// Configure Timer 7 and automatically start the timer
void ConfTimer7()
{
    RCC->APB1ENR |= RCC_APB1ENR_TIM7EN; 
    
    // Reset the peripheral interface
    RCC->APB1RSTR |= RCC_APB1RSTR_TIM7RST;
    
    // Wait a minimum of two clock cycles
    __ASM("NOP");
    __ASM("NOP");
    
    // Clear the reset bit
    RCC->APB1RSTR &= ~(RCC_APB1RSTR_TIM7RST);
    
    // Wait a minimum of two clock cycles
    __ASM("NOP");
    __ASM("NOP");
    
    // Disable Timer 7
    TIM7->CR1 &= ~(TIM_CR1_CEN);
    
    // Clear the prescaler register of Timer 7
    TIM7->PSC &= ~(TIM_PSC_PSC_Msk);
    
    // Set the prescaler value of Timer 7 to 24
    TIM7->PSC |= 2499; // Timer 7 frequency = 42*10^6/(2499+1) = 16.8 kHz
    
    // Clear the auto-reload register of Timer 7
    TIM7->ARR &= ~(TIM_ARR_ARR_Msk);
    
    // Set the count to 16800 (count to 1s)
    TIM7->ARR |= 16800;  
    
    // Set Timer 7 to run in "free-run" mode
    TIM7->CR1 &= ~(TIM_CR1_OPM);
    
    // Enable timer interrupt for Timer 7
    TIM7->DIER |= TIM_DIER_UIE;
    
    // Enable Timer 7
    TIM7->CR1 |= TIM_CR1_CEN;
}

void TIM7_IRQHandler()
{
    
    TIM7->SR &= ~(TIM_SR_UIF); // Clear the timer interrupt flag
    
    // Code to be executed every second
}

int main(void)
{   
    InitRCC();
    ConfGPIO();
    
    // Disable interrupts before configuring the system
    _disable_irq();
    
    // Set the timer interrupt to priority 0
    NVIC_SetPriority(TIM7_DAC_IRQn, 0);
    
    // Configure Timer 7
    ConfTimer7();
    
    // Enable the global interrupt system
    _enable_irq();
   
    while (1)
    {

    }
}

When I tried to build the target in Keil µVision 5, the following warnings and errors are shown:

src\main.c(526): warning:  #223-D: function "_disable_irq" declared implicitly
    _disable_irq();
src\main.c(529): error:  #20: identifier "TIM7_DAC_IRQn" is undefined
    NVIC_SetPriority(TIM7_DAC_IRQn, 0);
src\main.c(535): warning:  #223-D: function "_enable_irq" declared implicitly
    _enable_irq();

How to fix these errors and warnings? Are there any more header files I need to add so that functions void _enable_irq(void) and void _disable_irq(void) and the identifier "TIM7_DAC_IRQn" are defined? Or is there any alternative to these functions or identifiers in the existing header files?


Solution

  • Never include core_cm4.h or stm32f439xx.h directly.

    You need to define the correct part number macro STM32F439xx using a command line flag eg: -DSTM32F439xx.

    After that you should only include "stm32f4xx.h". This will include the correct CMSIS headers which define _enable_irq and _disable_irq and all the valid IRQ numbers for the part.

    Regarding TIM7_DAC_IRQn, this is incorrect. The DAC shares an interrupt with TIM6, and TIM7 has its own separate one. Chose either TIM6_DAC_IRQn or TIM7_IRQn.