衡水网站推广公司/中国职业培训在线官网
STM32F1 基于普通定时器TIM3–PWM输出驱动无源蜂鸣器。(HAL库)
这里的话重点是是将PWM输出模式驱动蜂鸣器,至于PWM是什么和有源and无源蜂鸣器的区别,CSDN上有许多将的很好的文章,这里不重复了。
无源蜂鸣器的驱动
接上VCC和GND,外加一个驱动的IO口即可。这个IO口负责输出的相对应的频率(即你输入1000hz频率的信号它就发出对应1000hz频率的声音),所以现在的目标是用stm32的对应IO口输出对应频率的信号。这里要强调一下,IO口输入给无源蜂鸣器的频率,必须要在一定范围之内(大概在2khz ~ 5khz)左右,这也限制住蜂鸣器只能输出2kzh ~ 5kzh范围的声音。现在目标是找到能够输出DO,RE,MI…的频率引用Leon爱代码所转载的文章
红框为在范围2khz ~ 5khz之内的音调(有几个超出了),现在任务就是stm32里的了
STM32内的配置
怎么才能输出对应频率的声音呢,只要输出对应频率的就ok了。这个时候定时器的PWM输出就十分有用了。我们先分析一下PWM输出要配置比较重要的东西:预分频(PSC),自动重装周期(Autoload),占空比(Pulse)。关于PWM其余的配置可以不一样,也可以参照我的源码(在文末放出)
-
预分频:
预分频器(Prescaler-PSC)用来将定时器时钟源进行分频输出。 -
自动重装载周期:
开启自动重装载功能后,当计数值到达Autoload中的值时,计数器清零,如果中断打开则会触发中断
PSC, Autoload 是决定输出频率的,所以配置好这两个东西基本就稳了 -
占空比:
当计数值到达占空比的值得时候,翻转电平输出。(至于之前电平是什么,自己可以配置)
占空比是决定蜂鸣器声音大小的
其余关于PWM东西的配置放在代码中:
知道这些东西后,要怎么配置呢:
根据公式就能知道预分频和Autoload要写入什么值。
做到上面这两步就能驱动蜂鸣器输出DO,RE…了
接下来就是节拍(就是音调的延时时间)的问题
这里我是用了软件延时,不推荐用其他定时器or系统定时器来决定延时时间(因为他们用中断会妨碍到PWM输出,所以)
// 延时时间函数 500ms为一拍 1000ms为一拍半uint16_t Interval[] = {500, 500, 500, 500, 500, 500, 1000, 500, 500, 500, 500,500, 500, 1000};// 简谱中的音调 DO,RE.... uint16_t tone[] = {1, 1, 5, 5, 6, 6, 5, 4, 4, 3, 3, 2, 2, 1};int i = 0;/* USER CODE END 1 */uint16_t length_Inter = sizeof(Interval)/sizeof(Interval[0]);uint16_t length_Tone = sizeof(tone)/sizeof(tone[0]);
// 软件延时
void delay_ms(uint16_t time)
{ uint16_t i=0; while(time--){i=12000; while(i--) ; }
}while (1){for(i = 0; i < length_Inter; i++){// BRE_TIM 是配置的定时器 index_pre是存储了音调的频率(DO对应的频率)//tone是存储音调(即简谱中的数字 DO,RE,ME)__HAL_TIM_SET_AUTORELOAD(&BRE_TIM, index_pre[tone[i]]);// 进行延时 delay_ms(Interval[i]); // 接下来的话可以删掉,这下面的的代码只是打乱蜂鸣器发音,然后重新让蜂鸣器发音,好听一点点。 __HAL_TIM_SET_AUTORELOAD(&BRE_TIM, 500);delay_ms(10);}i = 0;}
完成了
百度云下载:
密码: q9wh
源码下载地址