STM32CubeMX learning tutorial 4: timer interrupt

Publisher:静逸闲云Latest update time:2019-03-24 Source: eefocusKeywords:STM32CubeMX Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

software:


STM32CubeMX V4.25.0  


System Workbench V2.4


Firmware library version:


STM32Cube FW_F1 V1.6.1


hardware:


OneNet Monoceros V2.3


Create a new project in STM32CubeMX and select the correct MCU model



First, set RCC and SYS, as shown below



Enable TIM1 and select the internal clock source (Internal Clock).



Then set the clock according to the actual situation of the board (the external crystal oscillator of the Kirin is 12M, and the highest main frequency of STM32F103x is 72M), as shown below



GPIO sets PC7 and PC10 as GPIO_OUTPUT, (These are two of the four LED pins of the Kylin V2.3)



Set one of them to high level by default and the other to low level by default, and the User Labels are LED1 and LED4 respectively.



Set TIM1 to enable interrupt



Since TIM1 is connected to the APB2 bus (how to determine which bus the current timer is on will be described at the end of the article), looking at the clock tree we know that the current frequency of APB2 is 72MHz. We hope that 2 interrupts will occur per second, so we set the pre-scaling factor to 36000-1 and the auto-reload value to 1000-1. The obtained timer update interrupt frequency is 72,000,000/36000/1000=2Hz.



Project - setting, ToolChain/IDE select SW4STM32



Check here



After saving, click the Generate Code icon in the taskbar



After the generation is complete, click "Open Project" in the pop-up dialog box. System Workbench automatically opens Eclipse and imports and opens the project. Then expand the project tree and double-click to edit main.c. Enable TIM1 and enable its interrupt before while(1)


  /* USER CODE BEGIN 2 */

 HAL_TIM_Base_Start_IT(&htim1);

 

  /* USER CODE END 2 */

Then add the following code (note that this callback function is defined as __weak by default, so we need to redefine it here, and this callback function is shared by all timers, so we need to first determine which timer interrupt is calling it through if (htim->Instance == htim1.Instance))



 

/* USER CODE BEGIN 4 */


void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)


{


    if (htim->Instance == htim1.Instance)


    {


        /* Toggle LED */


    HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);


    HAL_GPIO_TogglePin(LED4_GPIO_Port,LED4_Pin);


    }


}


/* USER CODE END 4 */


 


 


Then right-click the project, select Properties, Run-Debug Settings, click New on the right, and select Ac6 STM32 Debugging in the pop-up dialog box.

Then click the Run icon on the taskbar. Of course, an error will be reported. For the reason, please refer to another blog of mine (https://blog.csdn.net/toopoo/article/details/79680323), so you need to right-click the project name Run.cfg and change its name.


Then right-click the project name in the project tree, select "Propeties", then in Run/Debug Settings-select the project name-Edit-Main-C/C++Application, click "Search Project", and then select the default elf file that appears:


Then select the configuration file you renamed in Debugger-User Defined-Browse:


Then right click on the new cfg file, select "Open With - Text Editor", and make the following changes:


source [find interface/stlink.cfg] 更改为 source [find interface/stlink-v2.cfg]


reset_config srst_only srst_nogate connect_assert_srst This line is changed to reset_config none 


Then run it again, and it will work.


The purpose of the program is to make LED1 and LED4 flash alternately, alternating every 0.5 seconds (2Hz).


As mentioned above, how do we know that TIM1 is connected to APB2? We can check the code and open main.c


See


static void MX_GPIO_Init(void);

Right-click MX_GPIO_Init(void), select "Open Declaration" from the menu, and then jump to its definition.


static void MX_GPIO_Init(void)

{

 

  GPIO_InitTypeDef GPIO_InitStruct;

 

  /* GPIO Ports Clock Enable */

  __HAL_RCC_GPIOD_CLK_ENABLE();

  __HAL_RCC_GPIOC_CLK_ENABLE();

  __HAL_RCC_GPIOA_CLK_ENABLE();

 

  /*Configure GPIO pin Output Level */

  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);

 

  /*Configure GPIO pin Output Level */

  HAL_GPIO_WritePin(LED4_GPIO_Port, LED4_Pin, GPIO_PIN_RESET);

 

  /*Configure GPIO pins : LED1_Pin LED4_Pin */

  GPIO_InitStruct.Pin = LED1_Pin|LED4_Pin;

  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

 

}

Right-click on HAL_RCC_GPIOD_CLK_ENABLE() and select "Open Declaration" from the menu. This will jump to the stm32f1xx_hal_rcc.h file, where the code is as follows:


#define __HAL_RCC_GPIOD_CLK_ENABLE()   do { \

                                        __IO uint32_t tmpreg; \

                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);\

                                        /* Delay after an RCC peripheral clock enabling */\

                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);\

                                        UNUSED(tmpreg); \

                                      } while(0U)

 

#define __HAL_RCC_ADC1_CLK_ENABLE()   do { \

                                        __IO uint32_t tmpreg; \

                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\

                                        /* Delay after an RCC peripheral clock enabling */\

                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\

                                        UNUSED(tmpreg); \

                                      } while(0U)

 

#define __HAL_RCC_TIM1_CLK_ENABLE()   do { \

                                        __IO uint32_t tmpreg; \

                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\

                                        /* Delay after an RCC peripheral clock enabling */\

                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\

                                        UNUSED(tmpreg); \

                                      } while(0U)

It can be seen that the TIM_CLK related register is APB2ENR, indicating that it is hung on the APB2 bus.


Or we can also look at the data sheet


It can be seen that TIM1 and TIM8 are mounted on APB2.


Keywords:STM32CubeMX Reference address:STM32CubeMX learning tutorial 4: timer interrupt

Previous article:Using STM32CubeMX to develop: key interrupt experiment
Next article:STM32CubeMX serial port receive interrupt

Recommended ReadingLatest update time:2024-11-16 15:47

STM32CubeMX learning tutorial 10: Hardware I2C reading and writing AT24C02
There is a long-standing saying on the Internet that STM's I2C has bugs and is not easy to use. Indeed, many people have encountered various problems in actual applications, so most people use software to simulate IIC. With STM32CubeMX, we can try to use hardware I2C. The official optimization can't be wrong, right?
[Microcontroller]
STM32CubeMX learning tutorial 10: Hardware I2C reading and writing AT24C02
FreeRTOS system CPU usage monitoring test in STM32CubeMX
1. Test description: Use the project automatically configured by STM32CubeMX to monitor the CPU usage of the FreeRTOS system provided by it and print it through the serial port. 2. Test environment: (1) Software environment: STM32CubeMX-4.22.0, IAR-7.5, serial port debugging tool  (2) Hardware environment: Ato
[Microcontroller]
FreeRTOS system CPU usage monitoring test in STM32CubeMX
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号