STM32-HAL-定时器(无源蜂鸣器的驱动)

文章介绍了无源蜂鸣器的工作原理,通过STM32F407VGT6开发板,利用定时器4的通道2产生PWM方波驱动蜂鸣器,详细阐述了初始化定时器、编写驱动代码的过程,并通过逻辑分析仪验证了波形,占空比设置为50%,实现了1kHz的蜂鸣器频率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、蜂鸣器的介绍

  • 有源蜂鸣器:

    有源蜂鸣器内部有一个发声电路,也就是“源”(震荡源,与无源蜂鸣器的区别),只要通电就可以响。

  • 无源蜂鸣器:

    无源蜂鸣器相当于扬声器,无源蜂鸣器直接接直流电,只在刚接触和离开的时候发声(利用电磁感应现象,通电、断电时推动振膜发声),一般使用方波信号源驱动发声。

二、常用的无源蜂鸣器的电路

在这里插入图片描述

1、从电路图中可以看出,蜂鸣器的驱动源来自单片机的定时器4的通道2产生的PWM方波

2、其中添加了IN4148二极管为的是再使用方波信号源驱动时,防止突然断电产生的高压反向电动势击穿其他的原件以及使用寿命的缩短。

3、其中使用的SS8085三极管作为开关器件使用,当基极电压为高电平时,三极管处于饱和状态,电路通电。

三、测试准备

  • 基于STM32F407VGT6的网络开发板(其他也可)
  • 安装windows系统并安装CubemxKeil MDK的电脑

四、初始化片上外设

4.1 初始化定时器4的通道2为PWM输出模式

在这里插入图片描述设置定时器4的Clock Source Internal Clock

  • 时钟源设置为外部高速时钟

在这里插入图片描述
【重要】查看开发板的板载晶振的频率(根据自己的开发板的晶振频率设置),因此设置输入的时钟的频率为25Hz,经过分频后最后设置频率为最大168MHz

  • 时钟树设置,经过分频、倍频后

在这里插入图片描述
经过代码查看,在"stm32f4xx_hal_rcc_ex.h" 头文件中,定时器4所在的时钟桥为APB1,查看时钟树后定时器4所在的外设桥时钟频率为84MHz.

在这里插入图片描述

  • 针对TIM4-Channel2 -PWM生成进行参数设置
Internal Clock内部时钟源,即晶振震荡源作为时钟
PWM Generation CH2PWM输出为通道2
Prescaler-(16位计数)定时器的分频系数(PSC):84-1
Counter Mode向上计数模式:UP
Counter Period-(16位计数)自动重装载值(ARR):1000 - 1
Internal Clock Division(CKD)不分频,频率非很高:No Division
auto-reload-preload自动重装载:Enable
ModePWM mode 1 向上计数
Plus(CCR)寄存器值:500
CH PolarityPWM极性,初始电平为下降沿

在这里插入图片描述

PWM的频率计算式

PWM的频率

定时器的计数频率计算式

在这里插入图片描述

设置后的PWM的频率为PWM-Freq = 84MHz / (84*1000) = 1kHz
时钟的计数频率为 CLK_CNT = Clcok-Freq / (PSC + 1) = 1MHz
计数一次的时间为 1 / CLK_CNT = (PSC + 1) / Clock-Freq = 1 / 1MHz = 1us
完成一次整周期的计数时间为 (ARR + 1)*1us = 1000 * 1uS = 1ms
高点评占空时间为CCR * 1us = 500us
设置的CCR值为 500 因此占空比为 500 / 1000 = 50%
  • 设置生成Keil- MDK代码文件

4.2 编写驱动代码

简单写两个函数可以表达意思即可。

[设置定时器的CCR寄存器的值]
#define BELL_PWM_FREQ                   2000000

void beep_SetFreq(uint16_t freq)
{	
	uint32_t Period = BELL_PWM_FREQ / freq;
	uint16_t Pulse  = Period  / 2;
	
	 HAL_TIM_PWM_Init(&htim4);// 初始化定时器的PWM模式
	
	 HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_2);// 启动定时器的PWM模式	
	 
	/* Set the Autoreload value , frequency*/
	
	/*设置频率和占空比*/
	
	__HAL_TIM_SET_AUTORELOAD (&htim4, Period - 1);
	
	__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,Pulse);	
}

void beep_off(void)
{	
	HAL_TIM_PWM_Stop(&htim4,TIM_CHANNEL_2);// 停止定时器的PWM输出
}

void beep_on(void)
{
	beep_SetFreq(2000);//设置自动重装载值为2000 ARR寄存器的值为1000 占空比为50%
	HAL_Delay(1000);
	beep_off();
}

  /* USER CODE BEGIN 2 */
 	beep_on();
  /* USER CODE END 2 */


[result]
鸣响一秒后结束
修改不同的值会得到不同频率的鸣叫声

4.3 Logic分析仪查看波形

逻辑分析仪分析的波形的PWM参数设置是基于代码修改的

  • ARR = 2000 000/2000 - 1 = 1000 - 1
  • CCR = 1000 / 2 = 500
  • PWM-Freq = 84M / (1000 * 84) = 1kHz
  • Duty = 500 / 1000 = 50%

在这里插入图片描述

4.4 代码分析

__HAL_TIM_SET_AUTORELOAD (&htim4,Pulse - 1);	

这是一个宏定义,用于设置STM32中的定时器的自动重装载寄存器的值,从而实现定时器的计数周期。

  • &htim4 是定时器4的句柄,表示要设置的定时器。
  • Period 表示要设置的定时器计数周期的值,单位为定时器时钟周期数。
__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,Pulse);	

这是一个宏定义,用来设置STM32中的定时器的比较值,从而实现定时器的计数和输出控制。

  • &htim4 是定时器4的句柄,表示要设置的定时器。
  • TIM_CHANNEL_2 表示要设置的定时器通道,表示比较输出的通道。
  • Pulse 表示要设置的比较值,用于控制定时器的输出和计数。

使用时需要先配置好定时器的基本参数,如时钟源、分频系数、计数方式等,然后再使用宏定义来设置自动重装载寄存器的值和比较值,从而实现定时器的计数周期控制和计数输出控制。

### STM32 HAL驱动蜂鸣器示例 #### 配置环境与硬件连接 为了成功使用STM32F103C8T6通过HAL驱动蜂鸣器,需先确认开发环境已设置完毕。推荐采用STM32CubeIDE作为集成开发工具,并利用STM32 HAL库简化底层操作[^1]。 对于具体引脚的选择需要注意,默认情况下某些GPIO可能已被分配给其他功能如JTAG调试接口。例如PB3通常用于JTAG信号线之一(TDI),因此如果计划将其重新定义为普通I/O端口以连接至蜂鸣器,则应禁用SWD/JTAG选项或选择未被占用的其它管脚[^2]。 #### 初始化项目及外设配置 借助STM32CubeMX图形化界面完成初步设定: - 启动HSE(高速外部振荡器),这有助于提高PWM波形精度从而改善音频质量[^3]; - 设置TIMx定时器参数以便生成所需频率方波输出到指定GPIO; - 确认所选通道能够正常工作于PWM模式下; ```c // main.c excerpt showing timer setup and PWM configuration. #include "main.h" void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_TIM2_Init(void); int main(void){ HAL_Init(); SystemClock_Config(); // Ensure HSE is enabled here MX_GPIO_Init(); MX_TIM2_Init(); while (1){ __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 50); // Adjust compare value to change duty cycle HAL_Delay(1000); __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 75); HAL_Delay(1000); } } static void MX_TIM2_Init(void){ TIM_OC_InitTypeDef sConfigOC = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim2.Instance = TIM2; htim2.Init.Prescaler = 8399; // Set prescaler based on system clock frequency htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 9999; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_PWM_Init(&htim2) != HAL_OK){ Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 5000; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK){ Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK){ Error_Handler(); } HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); } ``` 上述代码片段展示了如何创建一个简单的程序来调整PWM占空比进而改变发出的声音特性。请注意修改`__HAL_TIM_SET_COMPARE()`函数中的数值可以轻松切换不同音高效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值