目录
一、无源蜂鸣器原理图
二、有源蜂鸣器代码
无源蜂鸣器需要使用PWM驱动,所以应先配置PWM
PWM.c文件
#include "PWM.h"
/* TIM1四通道 PA8、PA9、PA10、PA11 TIM2四通道 PA0、PA1、PA2、PA3
TIM3四通道 PA6、PA7、PB0、PB1 TIM4四通道 PB6、PB7、PB8、PB9 */
void PWM_TIM3_Init(void) //PWM初始化 TIM3
{
//GPIO的结构体定义,定义一个GPIO类型的结构体,名字为GPIO_InitStructure
GPIO_InitTypeDef GPIO_InitStructure;
//TIM_TimeBase的结构体定义,定义一个TIM_TimeBase类型的结构体,名字为TIM_TimeBaseInitStructure
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
//TIM_OC的结构体定义,定义一个TIM_OC类型的结构体,名字为TIM_OCInitStructure
TIM_OCInitTypeDef TIM_OCInitStructure;
//开启定时器3的时钟,注意是APB1(GPIO的是APB2)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
//开启GPIO的时钟,注意是APB2
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//GPIO引脚的重映射,TIM3_CH1重映射引脚到PB4
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM3, ENABLE);
//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//选择定时器的内部时钟源 TIM3
TIM_InternalClockConfig(TIM3);
//配置定时器时基单元:TIM_TimeBase
//选择时钟分频,可以选择1分频、2分频和4分频
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //TIM_CKD_DIV1:1分频
//选择定时器计数方式,可选择向上计数、向下计数、中心对齐计数
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM_CounterMode_Up:向上计数
//设置ARR,即定时器周期:TIM_Period,取值0-65535
TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //ARR
//设置PSC,即定时器预分频器的值:TIM_Prescaler,取值0-65535
TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1; //PSC
//高级定时器才用的到,重复计算器,先用不上赋值为0
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
//TIM_TimeBase初始化
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
//初始化配置定时器输出比较单元:TIM_OC
//设置输出比较的模式:TIM_OCMode_PWM1,PWM1模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
//设置输出比较的极性:TIM_OCPolarity_High;高极性:有效电平为高电平
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
//设置输出使能
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
//设置捕获比较寄存器 CCR 的值
TIM_OCInitStructure.TIM_Pulse = 0; //CCR
//初始化定时器3通道1
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
//使能定时器3
TIM_Cmd(TIM3, ENABLE);
}
void PWM_TIM3_SetCompare1(uint16_t Compare)
{
//占空比 Duty = CCR/(ARR+1)
TIM_SetCompare1(TIM3, Compare); //设置捕获比较寄存器 CCR 的值,由公式应该取值0-100
}
PWM.h头文件
#ifndef __PWM_H
#define __PWM_H
#include "stm32f10x.h" // Device header
void PWM_TIM3_Init(void);
void PWM_TIM3_SetCompare1(uint16_t Compare);
#endif
buzzer.c文件
#include "buzzer.h" //无源蜂鸣器,PWM驱动
//音符频率定义(单位:Hz)
#define L1 262 //低音Do
#define L2 294 //Re
#define L3 330
#define L4 349
#define L5 392
#define L6 440
#define L7 494
#define M1 523 //中音Do
#define M2 587 //Re
#define M3 659
#define M4 698
#define M5 784
#define M6 880
#define M7 988
#define H1 1047 //高音Do
#define H2 1175 //Re
#define H3 1319
#define H4 1397
#define H5 1568
#define H6 1760
#define H7 1976
//定义节拍(单位:基本时间单位)
typedef enum { //枚举
T1 = 300 , //四分音符
T2 = 600 , //二分音符
T05 = 150 , //八分音符
T15 = 450 //附点四分音符
}Beat;
//乐曲数据结构
typedef struct{
uint16_t freq; //频率
uint16_t duration; //持续时间
}Note;
// 一闪一闪亮晶晶简谱
const Note music[] = {
// 一闪一闪亮晶晶
{M1,T05}, {M1,T05}, {M5,T05}, {M5,T05}, {M6,T05}, {M6,T05}, {M5,T1},
// 满天都是小星星
{M4,T05}, {M4,T05}, {M3,T05}, {M3,T05}, {M2,T05}, {M2,T05}, {M1,T1},
// 挂在天空放光明
{M5,T05}, {M5,T05}, {M4,T05}, {M4,T05}, {M3,T05}, {M3,T05}, {M2,T1},
// 好像许多小眼睛
{M5,T05}, {M5,T05}, {M4,T05}, {M4,T05}, {M3,T05}, {M3,T05}, {M2,T1},
// 一闪一闪亮晶晶
{M1,T05}, {M1,T05}, {M5,T05}, {M5,T05}, {M6,T05}, {M6,T05}, {M5,T1},
// 满天都是小星星
{M4,T05}, {M4,T05}, {M3,T05}, {M3,T05}, {M2,T05}, {M2,T05}, {M1,T1},
// 可根据实际乐谱继续补充后续音符...
};
void Buzzer_Init(void){
PWM_TIM3_Init(); //TIM3 OC1
}
void Buzzer_Freq(uint16_t freq){
uint32_t arr = (SystemCoreClock / 72)/freq-1; //72分频
if(freq == 0){
TIM_SetCompare1(TIM3,0); //关闭输出
return ;
}
TIM_PrescalerConfig(TIM3,72-1,TIM_PSCReloadMode_Immediate);
TIM_SetAutoreload(TIM3,arr);
TIM_SetCompare1(TIM3,arr/2); //50%占空比
}
void Buzzer_PlayMusic(void){
uint16_t a=0;
uint16_t notes_count = sizeof(music)/sizeof(Note);
for(a=0;a<notes_count;a++){
Buzzer_Freq(music[a].freq);
delay_ms(music[a].duration);
delay_ms(100);
Buzzer_Freq(0); //关闭声音
delay_ms(50);
}
}
buzzer.h头文件
#ifndef __PWM_H
#define __PWM_H
#include "stm32f10x.h" // Device header
void PWM_TIM3_Init(void);
void PWM_TIM3_SetCompare1(uint16_t Compare);
#endif
main.c文件
#include "stm32f10x.h"
#include "led.h"
#include "PWM.h"
#include "Buzzer.h"
#include "delay.h"
int main(void)
{
delay_init();
Buzzer_Init(); //TIM3 OC1
while(1){
Buzzer_PlayMusic();
delay_ms(500);
}
}
三、项目(代码+仿真)分享链接
后续完善