一、原理图
一、驱动代码
#include "beep.h"
void beep_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //BEEP-->PB.8 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据参数初始化GPIOB.8
GPIO_ResetBits(GPIOB,GPIO_Pin_8);//输出0,关闭蜂鸣器输出
}
void beep_pwm_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能定时器3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
// GPIO_PinRemapConfig(GPIO_PartialRemap_TIM4, ENABLE); //Timer3部分重映射 TIM3_CH2->PB5
//设置该引脚为复用输出功能,输出TIM4 CH2的PWM脉冲波形 GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
//初始化TIM4
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化TIM3 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC2Init(TIM4, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIM3在CCR2上的预装载寄存器
TIM_Cmd(TIM4, ENABLE); //使能TIM3
}
/*******************************************************************************
k07样板 2 2.2 2.4
db_pwm 69 65 62 59 56 54 50 43 41
fxx 1.8k 1.9k 2.0k 2.1k 2.2k 2.3k 2.47K 2.86K 3K
*******************************************************************************/
/*******************************************************************************
k07样板 2 2.46 3
db_pwm 69 65 62 59 56 54 50 43 41
fxx 1.8k 1.9k 2.0k 2.1k 2.2k 2.3k 2.47K 2.86K 3K
*******************************************************************************/
#define F1 486 //2.057 KHZ
#define F1PSC 71 //2.057 KHZ
#define F2 442 //2.257 KHZ
#define F2PSC 71 //2.257 KHZ
#define F3 413 //2.415 KHZ
#define F3PSC 71 //2.415 KHZ
#define F4 464 //2.15 KHZ
#define F4PSC 71 //2.15 KHZ
u16 const db_table_10 [6] = {
F1, F1, F2, F2, F3, F3, }; //底 嗒 帝 开机频率
u16 const db_table_20 [6] = {
3, 7, 3, 7, 9, 35, }; //每个频率所用的时间10ms单位
u16 const db_table_psc0 [6] = {
F1PSC,F1PSC, F2PSC, F2PSC, F3PSC, F3PSC, }; //每个频率所用的时间10ms单位
u16 const db_table_11 [6] = {
F3, F3, F2, F2, F1, F1, }; //帝 嗒 底 关机频率
u16 const db_table_21 [6] = {
3, 7, 3, 7, 9, 35, }; //每个频率所用的时间10ms单位
u16 const db_table_psc1 [6] = {
F3PSC, F3PSC, F2PSC, F2PSC, F1PSC, F1PSC, }; //每个频率所用的时间10ms单位
u16 const db_table_12 [2] = {
F4, F4, }; //帝 按键频率
u16 const db_table_22 [2] = {
8, 35, }; //每个频率所用的时间10ms单位
u16 const db_table_psc2 [2] = {
F4PSC, F4PSC, }; //每个频率所用的时间10ms单位
u16 const db_table_13 [4] = {
F3, F3, F2, F2, }; //底 嗒 上电模式频率
u16 const db_table_23 [4] = {
3, 20, 7, 60, }; //每个频率所用的时间10ms单位
u16 const db_table_psc3 [4] = {
F3PSC, F3PSC, F2PSC, F2PSC, }; //每个频率所用的时间10ms单位
u16 const db_table_14 [16] = {
F3, F3, F3, F3, F3, F3, F3, F3, F3, F3, F3, F3, F3, F3, F3, F3, }; //测试模式 加速模式
u16 const db_table_24 [16] = {
3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, }; //每个频率所用的时间10ms单位
u16 const db_table_psc4 [16] = {
F3PSC, F3PSC, F3PSC, F3PSC, F3PSC, F3PSC, F3PSC, F3PSC, F3PSC, F3PSC, F3PSC, F3PSC, F3PSC, F3PSC, F3PSC, F3PSC, }; //每个频率所用的时间10ms单位
u8 const size_table1x []=
{
(sizeof (db_table_10)) / (sizeof (db_table_10[0])), //求数组字节总数
(sizeof (db_table_11)) / (sizeof (db_table_11[0])),
(sizeof (db_table_12)) / (sizeof (db_table_12[0])),
(sizeof (db_table_13)) / (sizeof (db_table_13[0])),
(sizeof (db_table_14)) / (sizeof (db_table_14[0])),
};
/******************************************************************************/
//================================================
// 使能蜂鸣器函数
//================================================
u16
buz_musc_fz, //赋数组的频率
buz_fz_timer, //赋数组每个频率的时间
buz_kong_timer; //防止响蜂鸣超时
u8
buz_musc_type, //选择使用蜂鸣类型 0=开机音 1=关机音 2=按键音 3=上电音 4=测试音
buz_musc_num, //决定选择数组的第几位
buz_musc_len, //赋数组字节总位数
buz_musc_read_type; // 蜂鸣类型 1=开机声 2=关机声 3=按键声 4=上电声 5=加速测试声
u8 F_buz_start,buzzer_flag;
u16 timerPsc;
void start_musc (u8 _musc_nm)
{
buz_musc_read_type = 0;
buz_musc_fz = 0; // 所有变量清0
buz_fz_timer = 0;
buz_musc_type = 0;
buz_musc_num = 0;
buz_musc_len = 0;
buzzer_flag = 0;
buz_musc_type = _musc_nm; // 蜂鸣声音的类型
if (buz_musc_type > 4) {
F_buz_start = 0;buz_musc_type = 0; } // 不使能蜂鸣函数
else {
F_buz_start = 1; } // 开始使能蜂鸣函数
close_beep(); // 关闭蜂鸣器电源脚输出
disable_beep_pwm(); // 关闭蜂鸣器PWM输出
buz_kong_timer = 0; // 响蜂鸣超时清0
}
//================================================
// 使能蜂鸣器函数
//================================================
void musc_scan (void)
{
//=========================================================== 开始
if (F_buz_start)
{
//======================================================== 无蜂鸣时间
if (buz_fz_timer == 0)
{
switch (buz_musc_type) //蜂鸣声音的类型
{
case 0:
buz_musc_fz = db_table_10 [buz_musc_num]; //赋频率
buz_fz_timer = db_table_20 [buz_musc_num]; //赋频率所需的时间
timerPsc=db_table_psc0[buz_musc_num];
break;
case 1:
buz_musc_fz = db_table_11 [buz_musc_num];
buz_fz_timer = db_table_21 [buz_musc_num];
timerPsc=db_table_psc1[buz_musc_num];
break;
case 2:
buz_musc_fz = db_table_12 [buz_musc_num];
buz_fz_timer = db_table_22 [buz_musc_num];
timerPsc=db_table_psc2[buz_musc_num];
break;
case 3:
buz_musc_fz = db_table_13 [buz_musc_num];
buz_fz_timer = db_table_23 [buz_musc_num];
timerPsc=db_table_psc3[buz_musc_num];
break;
case 4:
buz_musc_fz = db_table_14 [buz_musc_num];
buz_fz_timer = db_table_24 [buz_musc_num];
timerPsc=db_table_psc4[buz_musc_num];
break;
}
//装载 pwm1蜂鸣器 周期与占空比
beep_pwm_Init(buz_musc_fz,timerPsc);
TIM_SetCompare2(TIM4, buz_musc_fz/2);
// enable_beep_pwm();
if (buz_musc_num & 0x01) {
close_beep(); } //数组单数就关闭蜂鸣电源脚
else {
open_beep(); } //数组双数就打开蜂鸣电源脚
buz_musc_len = size_table1x [buz_musc_type]; //计算数组的总字节数
}
//======================================================== 无蜂鸣时间 end
//======================================================== 有蜂鸣时间
if (buz_fz_timer)
{
buz_fz_timer--; //每个蜂鸣频率的时间减减
if (buz_fz_timer == 0)
{
buz_musc_num++;
if (buz_musc_num >= buz_musc_len) //与数组字节相等就结束
{
start_musc (5); // 其它关闭蜂鸣PWM及变量清0
}
}
}
//======================================================= 有蜂鸣时间 end
}
else
{
close_beep(); // 关闭蜂鸣器电源脚输出
disable_beep_pwm(); // 关闭蜂鸣器PWM输出
}
//===========================================================结束
}
//================================================
// 扫描使能蜂鸣器函数
//================================================
void musc_select_num_scan (void)
{
switch (buz_musc_read_type)
{
case 1: start_musc (0); break; // 开机蜂鸣
case 2: start_musc (1); break; // 关机蜂鸣
case 3: start_musc (2); break; // 按键蜂鸣
case 4: start_musc (3); break; // 上电蜂鸣
case 5: start_musc (4); break; // 加速蜂鸣
default:
if (F_buz_start)
{
if (++buz_kong_timer > 1000) // 如果响蜂鸣超过了10sec
{
start_musc (5); // 其它关闭蜂鸣PWM及变量清0
}
}
else {
buz_kong_timer = 0; }
break;
}
}
主函数中调用
int main(void)
{
u8 i,led=0x00;
delay_init();
program_led_init();
can_led_init();
rs485_led_init();
beep_init();
while(1)
{
i++;
if(i>=100)
{
i=0;
led=~led;
buz_musc_read_type=1;
program_led_data(0x00,led-0xf0,0x00);
}
musc_select_num_scan (); // 蜂鸣
musc_scan ();
delay_ms(10);
}
}
三、注意点
1、BEEP_CLK是一路硬件PWM口
四、完整工程下载
完整工程请点击这