STM32驱动压电式蜂鸣器发出和弦音原理图加程序

一、原理图
在这里插入图片描述
一、驱动代码

#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口
四、完整工程下载
完整工程请点击这

猜你喜欢

转载自blog.csdn.net/qq_15181569/article/details/109044065