一:STM32定时器多任务并发器

1.实验内容
通过定时器Timer方式实现时间的精准控制,相当于给CPU上了一个闹钟,CPU平时处理其它任务,当定时时间到了以后,处理定时相关的任务。内容要求为设置一个5秒的定时器,每隔5秒从串口发送“hello windows!”;同时设置一个2秒的定时器,让LED等周期性地闪烁,实现一个多任务并发运行的功能。在此实验我们不采用定时器来同时完成上面两个周期性任务。
2.建立工程
(1)创建新项目并选择芯片:
在STM32cubeMx主页面中创建新项目,在芯片中我们所使用的是STM32F103C8T6。
(2)配置参数:

  • 配置io口参数
    应实验要求我们要设置一个2秒的定时器,让LED等周期性地闪烁,这里我们选择PC13作为LED灯的输出,如下图:
    在这里插入图片描述

  • 配置系统时钟
    点击左侧 “Pinout & Configuration”→“RCC”,在 “High Speed Clock (HSE)” 中选择 “Crystal/Ceramic Resonator”(使用外部晶振)。
    如下图:
    在这里插入图片描述

点击 “Clock Configuration”,将系统时钟(HCLK)配置为 72MHz:
若外部晶振为 8MHz,设置PLL Source为HSE,PLL MUL为x9,使PLLCLK为 72MHz;
确保AHB Prescaler为/1,APB1 Prescaler为/2,APB2 Prescaler为/1,最终HCLK显示为 72MHz。
配置好后如下图所示:
在这里插入图片描述

  • 配置SYS
    选择调试接口,选择SYS,在右侧的Debug中选择Serial Wire如下图:
    在这里插入图片描述

  • 配置TIM2与TIM3
    定时器 TIM2配置如下:
    在这里插入图片描述
    TIM3配置如下:
    在这里插入图片描述

  • 开启中断
    如下图所示我们配置好TIM2和TIM3后开启中断
    在这里插入图片描述
    在这里插入图片描述

  • USART1 配置
    模式:异步通信(Asynchronous)。
    参数:波特率115200、数据位8、停止位1、无校验。
    如下图:
    在这里插入图片描述

  • 项目配置
    如下图:
    在这里插入图片描述
    在这里插入图片描述
    配置好以上后我们生成项目点击GENERATE CODE进入keil5
    3.编写代码:
    (1)在主函数内输入启动定时器函数

	HAL_TIM_Base_Start_IT(&htim2);
	HAL_TIM_Base_Start_IT(&htim3);

如图:
在这里插入图片描述
如此我们就可以启动定时器2和定时器3
(2)在主函数上方定义需要发送的信息(“hello windows!”)

	uint8_t hello[20]="hello windows!\r\n";

如下图:
在这里插入图片描述
(3)编写定时器中断函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	static uint32_t time_cnt =0;
	static uint32_t time_cnt3 =0;
	if(htim->Instance == TIM2)
	{
		if(++time_cnt >= 400)
		{
			time_cnt =0;
			HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
		}
	}
	if(htim->Instance == TIM3)
	{
		if(++time_cnt3 >= 1000)
		{
			time_cnt3 =0;
    HAL_UART_Transmit(&huart1,hello,20,100000);
		}
			
	}
}

如下图:
在这里插入图片描述
5秒的定时器,每隔5秒从串口发送“hello windows!”;同时2秒的定时器,让LED等周期性地闪烁,按照参数配置中一次中断时间为0.005s所以当发生一千次中断时串口会发送一次信息,而led会在发生四百次中断时会闪烁一次。
(4)结果展示
串口:

屏幕录制 2025-10-20 190420

led:

leddd

二:PWM呼吸灯效果实现

1.STM32CubeMx配置
(1)建立工程:
在STM32cubeMx主页面中创建新项目,在芯片中我们所使用的是STM32F103C8T6。
(2)配置参数

  • 配置系统时钟
    点击左侧 “Pinout & Configuration”→“RCC”,在 “High Speed Clock (HSE)” 中选择 “Crystal/Ceramic Resonator”(使用外部晶振)。
    如下图:
    在这里插入图片描述
    点击 “Clock Configuration”,将系统时钟(HCLK)配置为 72MHz:
    若外部晶振为 8MHz,设置PLL Source为HSE,PLL MUL为x9,使PLLCLK为 72MHz;
    确保AHB Prescaler为/1,APB1 Prescaler为/2,APB2 Prescaler为/1,最终HCLK显示为 72MHz。
    配置好后如下图所示:
    在这里插入图片描述
  • 配置SYS
    选择调试接口,选择SYS,在右侧的Debug中选择Serial Wire如下图:
    在这里插入图片描述
  • 配置TIM3
    定时器 TIM3(PWM 输出):
    模式:PWM Generation CH1,预分频器PSC=71,自动重装值ARR=999(频率 = 72MHz/(71+1)/(999+1)=1kHz)。
    引脚:PA6设为TIM3_CH1复用推挽输出。
    如下图:
    在这里插入图片描述

在这里插入图片描述

  • TIM4配置
    定时器 TIM4(PWM 输出):
    模式:PWM Generation CH1,预分频器PSC=71,自动重装值ARR=999。
    引脚:PB6设为TIM4_CH1复用推挽输出。
    如下图:
    在这里插入图片描述在这里插入图片描述
    (3)如上操作生成代码后进入main.c文件实现代码
int main(void) {
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();

  // 启动TIM3和TIM4的PWM输出(通道1)
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);

  // 呼吸灯参数初始化
  uint16_t tim3_duty = 0;  // TIM3占空比(0~999)
  uint16_t tim4_duty = 0;  // TIM4占空比(0~999)
  int8_t step = 5;         // 占空比变化步长(每次增减5,控制变化速度)

  while (1) {
    // 更新TIM3的PWM占空比
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, tim3_duty);
    // 更新TIM4的PWM占空比
    __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, tim4_duty);

    // 调整占空比(从0→999→0循环)
    tim3_duty += step;
    tim4_duty += step;

    // 当占空比达到最大值(999)或最小值(0)时,反向变化
    if (tim3_duty >= 999 || tim3_duty <= 0) {
      step = -step;  // 步长取反,改变变化方向
    }

    // 延时10ms,控制呼吸灯变化速度(延时越短,变化越平滑)
    HAL_Delay(10);
  }
}

2.实验结果

呼吸

三:实验总结

本次实验围绕嵌入式系统中定时器精准定时与PWM波形生成两大核心功能展开,通过实际编程与硬件验证,深入理解了嵌入式多任务并发与模拟信号输出的实现逻辑,收获颇丰。
1.定时器多任务并发实验的理解与收获
在第一个实验中,我们采用定时器(Timer)替代传统的循环延时或 delay 函数,实现了多任务的“并发”运行。传统延时方式会让CPU陷入“空等”,浪费算力;而定时器则像给CPU设置“闹钟”,平时CPU可处理其他任务,定时时间到达后再响应中断、执行对应任务。
实验中,我们成功配置了两个定时器:一个5秒定时器用于串口周期性发送“hello windows!”,另一个2秒定时器控制LED闪烁。这一过程让我深刻体会到**嵌入式系统中“时间片”与“中断驱动”的设计思想——通过硬件定时器的中断机制,将CPU时间合理分配给不同任务,避免了单任务阻塞导致的功能停滞。
对于“无定时器实现多任务”的思考,进一步拓展了我的思路:可采用
“轮询+时间戳”**的方式,在主循环中不断检查两个任务的“目标执行时间”是否到达,若到达则执行对应任务并更新时间戳。这种方式本质上是用软件模拟定时器的时间管理逻辑,虽不如硬件定时器精准,但能在无定时器资源时实现多任务的近似并发。
2.PWM呼吸灯实验的原理与实践
第二个实验聚焦PWM(脉冲宽度调制)技术在LED呼吸灯中的应用。PWM通过改变“高电平占空比”(即一个周期内高电平时间的比例),可实现对输出“平均电压”的调节——占空比越大,LED亮度越高;占空比越小,亮度越低。实验中,我们使用TIM3和TIM4定时器分别输出占空比随时间变化的PWM波形,驱动外接LED与开发板上的PC13端口LED,实现了“呼吸”效果(亮度从暗到亮再到暗的循环)。
在实践过程中,我掌握了PWM的核心配置步骤:
(1)定时器时基配置:设置自动重装载值(ARR)与预分频系数(PSC),确定PWM的周期;
(2)输出比较模式配置:将定时器通道配置为PWM模式,使能输出比较功能;
(3)占空比动态调整:在程序中周期性修改“比较寄存器”(CCR)的值,让占空比随时间线性变化,从而模拟“呼吸”的渐变效果。

更多推荐