STM32CubeMX V4.25.0
System Workbench V2.4
硬件:OneNet 麒麟座V2.3
在STM32CubeMX中新建项目,选择正确的MCU型号
首先设置RCC和SYS,如下图
然后根据板子实际情况设置时钟(麒麟座外部晶振是12M,STM32F103x的最高主频是72M),如下图
GPIO设置 PC7和 PC10为GPIO_OUTPUT, (这是麒麟座V2.3的四个LED管脚其中的两个)
设置其中一个默认为高电平,另一个默认为低电平,User Label分别是LED1和LED4。
设置TIM1,启用中断
由于TIM1是挂在APB2总线上(如何判断当前计时器在哪个总线,文章最后会描述方法),查看时钟树我们知道APB2当前频率为72MHz,我们希望每秒钟发生2次中断,就把预分频系数设置为36000-1,自动重载值为10000-1,得到的计时器更新中断频率即为72,000,000/36000/1000=2Hz。
Project - setting ,ToolChain/IDE选择 SW4STM32
勾选这里
保存以后,点击任务栏的生成代码图标
生成完毕以后在弹出的对话框点击"Open Project", System Workbench自动打开Eclipse并导入和打开了项目,然后展开项目树,双击编辑main.c,在while(1)之前启用TIM1并使能其中断
/* USER CODE BEGIN 2 */ HAL_TIM_Base_Start_IT(&htim1); /* USER CODE END 2 */然后添加如下代码(注意此回调函数默认是__weak定义的,所以我们在这里需要重新定义一下,而且此回调函数是所有定时器共用的,所以我们需要先通过 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 */
然后任务栏上点击Run图标,然后系统可能会提示你选择Run/Debug Setting,在弹出的对话框点击New,选择Ac6 STM32 Debugging,
然后再Run一次,当然会报错的,原因请查看另一篇我的博客(https://blog.csdn.net/toopoo/article/details/79680323),所以需要右键点击 项目名Run.cfg ,给它改个名字,然后右键点击项目树里面的项目名称,选择“Propeties”,然后在Run/Debug Settings-选择项目名-Edit-Debugger-User Defined-Browse 那里选择你自己改名的配置文件:
然后右键点击那个新的cfg文件,选择"Open With - Text Editor", 进行如下更改:
source [find interface/stlink.cfg] 更改为 source [find interface/stlink-v2.cfg]
reset_config srst_only srst_nogate connect_assert_srst 这一行改为 reset_config none
然后再Run一下,就可以了。
程序的作用是让LED1和LED4交替闪烁,每0.5秒进行一次交替(2Hz)。
如前文所述,我们如何知道TIM1是连接到APB2上的呢?我们可以查代码,打开main.c
看到
static void MX_GPIO_Init(void);
右键点击 MX_GPIO_Init(void),选择菜单的“Open Declaration”,然后跳转到它的定义
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); }
在HAL_RCC_GPIOD_CLK_ENABLE( )上面点击右键,选择菜单的“Open Declaration”。会跳转到 stm32f1xx_hal_rcc.h文件,里面代码如下:
#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)
可以看到TIM_CLK相关寄存器是APB2ENR,说明它是挂在APB2总线上的。
或者我们也可以查看数据手册
可以看到TIM1和TIM8是挂在APB2上的。