【STM32CubeMX开发】-2.1-TIM_生成一个1ms定时器中断

STM32 Tim定时器配置与测试

目录

1 Tim定时器的时钟源

2 Tim定时器的配置

2.1 中断配置

3 生成代码

4 测试结果

结尾


1 Tim定时器的时钟源

TIM1的时钟来源自APB1 Timer clocks,时钟树上所有总线频率均设置为了STM32F0能达到的最高频率,此时APB1 Timer clocks = 48MHz。

2 Tim定时器的配置

依次选择Pinout&Configuration -- > Timers -- > TIM1,参数配置如下:

Clock Source:选择Internal Clock内部时钟源。TIMInternal Clock来自APB1 Timer clock(MHz)

Prescaler(PSC – 16 bits value):时钟源分频系数(TIMx_PSCPSC),一个计数的时间长度为48/48MHz = 1微妙;

Counter Mode:(TIMx_CR1中的DIR)Up向上计数,Down向下计数,Center Aligned mode1/2/3;

Counter Period(AutoReload Register – 16 bits value):(TIMx_ARR中的ARR一个定时周期的时间,1000 * 1微妙 = 1毫秒;

Internal Clock Division:(TIMx_CR1中的CKD位)时钟分频因子。定义在定时器时钟频率与数字滤波器使用的采样频率之间的分频比例;

RepetitionCounter:配置重复计数器的值,这里设置为0,表示不使用重复计数功能;

auto-reload preload:(TIMx_CR1中的ARPE位)自动重装载预装载允许位。定义在TIMx_ARR和实际的自动重装载寄存器之间是否设置缓冲器;

Trigger Output (TRGO) Parameters :一般是用来设置用作其他外设的触发源的。比如将Trigger Event Selection选择为Update Event,然后在其他外设比如ADC中配置外部触发源时选择该定时器的触发事件(如果可以的话),这样在定时器产生Update Event时就可以启动外设,实现用定时器来控制外设启动的功能;

2.1 中断配置

NVIC Settings中,选择合适的中断优先级并勾选TIM1的中断使能。

3 生成代码

单击GENERATE CODE,生成代码:通过HAL_TIM_Base_Start(&htim1) 启动TIM1TIM1_BRK_UP_TRG_COM_IRQHandler中断函数间隔500ms被周期调用一次。

Main.c

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM1_Init();
  /* USER CODE BEGIN 2 */
  demo_init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

stm32f0xx_it.c

void TIM1_BRK_UP_TRG_COM_IRQHandler(void)
{
  /* USER CODE BEGIN TIM1_BRK_UP_TRG_COM_IRQn 0 */
  /** 1ms timed interrupt **/
	demo_main();
	
  /* USER CODE END TIM1_BRK_UP_TRG_COM_IRQn 0 */
  HAL_TIM_IRQHandler(&htim1);
  /* USER CODE BEGIN TIM1_BRK_UP_TRG_COM_IRQn 1 */

  /* USER CODE END TIM1_BRK_UP_TRG_COM_IRQn 1 */
}

demo.c

#include "main.h"
#include "demo.h"
#include "tim.h"

#define LED_SWITCH_TIMER       500    // Unit:ms
#define FUNCTION_CALL_CYCLE    1      // Unit:ms

void demo_init(void)
{
    /********************************Start timer TIM1**********************************/
	HAL_TIM_Base_Start_IT(&htim1);       
}

void demo_main(void)
{
    static uint16_t led_timer = 0;
    static uint8_t led_flg = 0;		
	
	  if(led_timer < (LED_SWITCH_TIMER / FUNCTION_CALL_CYCLE))
		{
				led_timer += FUNCTION_CALL_CYCLE; 
		}
	  else
	  {
	      led_timer = 0;
			
				if(led_flg == 0)
				{
					   led_flg = 1;
					
						 HAL_GPIO_WritePin(GPIOB,LED_DO_Pin,GPIO_PIN_RESET);   // ON LED
				}
				else
				{
					   led_flg = 0;
					
					   HAL_GPIO_WritePin(GPIOB,LED_DO_Pin,GPIO_PIN_SET);     // OFF LED
				}	
	  }

}

4 测试结果

LED间隔500ms周期拉高拉低。

结尾

获取更多“汽车电子资讯”和“工具链使用”,

请关注优快云博客“汽车电子助手”,做您的好助手。

<think>好的,我现在需要帮用户解决基于STM32F407开发板,使用定时器中断实现电子时钟并通过LCD1602显示的代码示例的问题。用户还提到了使用STM32CubeMXKeil,所以我需要结合这些工具来提供解决方案。 首先,我应该回顾一下用户提供的引用内容。引用[1]提到使用STM32CubeMX新建工程,定时器TIM3中断1秒一次,计算公式涉及ARR和PSC。引用[2]详细说明了定时器的配置,包括分频系数、计数模式、自动重装载值等。引用[3]和[4]则涉及HAL库中的定时器中断处理和回调函数的使用。 接下来,我需要确定如何配置定时器中断生成1秒的周期。根据引用中的信息,定时器的时钟源是内部时钟,分频系数和ARR值需要计算。假设系统时钟是168MHz(STM32F407的常见配置),定时器时钟可能为84MHz(因为APB1总线上的定时器时钟通常是系统时钟的一半)。例如,如果使用TIM3,分频系数PSC设为8399,这样定时器时钟为84MHz/(8400) = 10kHz。ARR设置为10000-1,这样中断周期为10kHz的倒数乘以10000,即1秒。这样配置是否正确?需要验证计算公式:T = (ARR+1)*(PSC+1)/Tclk。 然后,LCD1602的驱动需要GPIO配置,用户可能需要使用4位或8位模式。STM32CubeMX中需要配置对应的GPIO引脚,并编写发送命令和数据的函数。要注意延时和时序,可能需要微秒级的延时函数,可以使用HAL_Delay或者更精确的方法。 在代码结构方面,主函数初始化后,启动定时器,并在中断服务函数中更新时间。秒、分、时的变量在中断中递增,同时要注意进位(如60秒进1分,60分进1小时等)。LCD显示部分需要定期刷新,可能在主循环中调用显示函数,或者在定时器中断中更新显示,但后者可能影响实时性,所以主循环中处理更好。 还需要考虑HAL库的中断处理流程。根据引用[4],中断发生后会调用HAL_TIM_IRQHandler,进而调用回调函数HAL_TIM_PeriodElapsedCallback。用户需要重写这个回调函数来增加时间变量。 可能的错误点包括定时器配置错误导致中断周期不准,LCD引脚连接错误,或者时序问题导致显示不正常。需要提醒用户检查硬件连接,比如RS、RW、E引脚以及数据线的连接是否正确。 最后,示例代码需要包括STM32CubeMX的配置步骤,如定时器和GPIO的设置,以及Keil中的代码编写,包括初始化、中断处理和LCD驱动部分。可能还需要提到如何将LCD1602库函数集成到项目中,比如现有的驱动程序或自行编写。 现在需要将这些思考整理成一个结构化的回答,分步骤说明配置和代码实现,确保用户能够按照步骤操作。同时生成相关问题,帮助用户深入理解相关知识点。</think>### 基于STM32F407的电子时钟实现步骤 #### 1. STM32CubeMX配置 **1.1 定时器配置(TIM3为例)** - **时钟源**:选择`Internal Clock`(内部时钟)[^2] - **分频系数(PSC)**:8399(将84MHz分频为10kHz) - **自动重装载值(ARR)**:9999(周期=10000/10kHz=1秒) - **使能自动重装载**:Enable - **NVIC设置**:勾选`TIM3 global interrupt`[^1] **1.2 GPIO配置(LCD1602)** - **数据线(D4-D7)**:选择4位模式,例如PA0-PA3 - **控制线(RS, RW, E)**:例如PA4(RS), PA5(RW), PA6(E) - **模式**:推挽输出(GPIO_Output) #### 2. Keil代码实现 **2.1 定时器中断回调函数** ```c volatile uint8_t sec=0, min=0, hour=12; // 时间变量 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM3) { sec++; if(sec >=60) { sec=0; min++; } if(min >=60) { min=0; hour++; } if(hour>=24) hour=0; } } ``` **2.2 LCD1602驱动函数(示例)** ```c void LCD_SendCmd(uint8_t cmd) { HAL_GPIO_WritePin(RS_GPIO_Port, RS_Pin, GPIO_PIN_RESET); // 发送高4位 GPIOA->ODR = (GPIOA->ODR & 0xFFF0) | ((cmd >>4) & 0x0F); // 触发E脉冲 HAL_GPIO_WritePin(E_GPIO_Port, E_Pin, GPIO_PIN_SET); HAL_Delay(1); HAL_GPIO_WritePin(E_GPIO_Port, E_Pin, GPIO_PIN_RESET); // 发送低4位(类似上述过程) } ``` **2.3 主函数逻辑** ```c int main(void) { HAL_Init(); MX_GPIO_Init(); MX_TIM3_Init(); HAL_TIM_Base_Start_IT(&htim3); // 启动定时器中断[^3] LCD_Init(); // 初始化LCD1602 LCD_PrintString("Time:"); while (1) { char buf[16]; sprintf(buf, "%02d:%02d:%02d", hour, min, sec); LCD_SetCursor(0, 1); LCD_PrintString(buf); HAL_Delay(200); // 每200ms刷新显示 } } ``` #### 3. 关键参数验证 定时器周期计算公式: $$ T = \frac{(ARR+1) \times (PSC+1)}{T_{clk}} = \frac{10000 \times 8400}{84 \times 10^6} = 1 \text{秒} $$ #### 4. 硬件连接注意事项 - **LCD1602引脚**:需连接对比度调节电位器(VO引脚) - **背光供电**:A/K引脚接3.3V和GND - **数据线模式**:若使用4位模式,D0-D3可不连接 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汽车电子助手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值