zl程序教程

您现在的位置是:首页 >  硬件

当前栏目

STM32F030R8Tx使用HAL库实现PWM驱动蜂鸣器

驱动 实现 HAL PWM 使用 蜂鸣器
2023-09-14 09:16:38 时间
  • 准备工程,此例程在此链接的工程的基础上添加PWM功能

https://blog.csdn.net/mygod2008ok/article/details/106890382

  • 需要添加stm32f0xx_hal_tim.c和stm32f0xx_hal_tim_ex.c两个文件到工程

  • 在stm32f0xx_hal_conf.h文件打开HAL_TIM_MODULE_ENABLED宏 

  • 新建BSP_pwm.c和BSP_pwm.h两个文件并加入工程

 

  • BSP_pwm.c中的内容如下

#include "BSP_pwm.h"
#include "stm32f0xx_hal_conf.h"
#include "stm_log.h"

#define  BUZZER_BEEP       (uint32_t)(244 - 1)  /* Period Value  */

#define PWM_PRESCALER_VALUE    (FREQ_VALUE/1000000-1)

TIM_HandleTypeDef    buzzer_TimHandle;
TIM_OC_InitTypeDef   buzzer_sConfig;

static uint8_t s_beep_status = BEEP_STOP;
/**
* @brief 蜂鸣器PWM初时化
*/
static void BSP_buzzer_beep_init(void)
{
	buzzer_TimHandle.Instance = TIM16;
  __HAL_RCC_TIM16_CLK_ENABLE();
  buzzer_TimHandle.Init.Prescaler         = 48-1;
  buzzer_TimHandle.Init.Period            = BUZZER_BEEP;
  buzzer_TimHandle.Init.ClockDivision     = 0;
  buzzer_TimHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;
  buzzer_TimHandle.Init.RepetitionCounter = 0;
  buzzer_TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
	HAL_StatusTypeDef err_code = HAL_TIM_PWM_Init(&buzzer_TimHandle);
	APP_ERROR_CHECK(err_code);
	

  /*##-2- Configure the PWM channels #########################################*/
  /* Common configuration for all channels */
  buzzer_sConfig.OCMode       = TIM_OCMODE_PWM1;
  buzzer_sConfig.OCPolarity   = TIM_OCPOLARITY_HIGH;
  buzzer_sConfig.OCFastMode   = TIM_OCFAST_DISABLE;
  buzzer_sConfig.OCNPolarity  = TIM_OCNPOLARITY_HIGH;
  buzzer_sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;

  buzzer_sConfig.OCIdleState  = TIM_OCIDLESTATE_RESET;

  /* Set the pulse value for channel 1 */
  buzzer_sConfig.Pulse = BUZZER_BEEP/2;
	err_code = HAL_TIM_PWM_ConfigChannel(&buzzer_TimHandle, &buzzer_sConfig, TIM_CHANNEL_1);
	APP_ERROR_CHECK(err_code);
	
}



/**
* @brief 启动蜂鸣器
*/
void start_buzzer_beep_sound(void)
{
	if(s_beep_status == BEEP_STOP)
	{
		s_beep_status = BEEP_START;
	}
}


/**
* @brief 启动buzzer pwm
*/
static void buzzer_pwm_start(void)
{
	 BSP_buzzer_beep_init();
	  GPIO_InitTypeDef   GPIO_InitStruct;
  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* TIMx Peripheral clock enable */


  /* Enable GPIO Channels Clock */
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /* Configure PB.04 (TIM3_Channel1), PB.05 (TIM3_Channel2), PB.00 (TIM3_Channel3),
     PB.01 (TIM3_Channel4) in output, push-pull, alternate function mode
  */
  /* Common configuration for all channels */
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  GPIO_InitStruct.Alternate = GPIO_AF2_TIM16;
  GPIO_InitStruct.Pin = GPIO_PIN_8;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	HAL_TIM_PWM_Start(&buzzer_TimHandle, TIM_CHANNEL_1);

}

/**
* @brief 停止buzzer pwm
*/
static void buzzer_pwm_stop(void)
{
	HAL_TIM_PWM_Stop(&buzzer_TimHandle, TIM_CHANNEL_1);
	HAL_TIM_PWM_DeInit(&buzzer_TimHandle);
	GPIO_InitTypeDef   GPIO_InitStruct;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	GPIO_InitStruct.Pin = GPIO_PIN_8;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
	

}



/**
* @brief 蜂鸣器响应时长处理
* @note
* - 此函数在25HZ中调用
*/
void buzzer_beep_sound_handler(void)
{
	static uint8_t cnt;
	switch(s_beep_status)
	{
		case BEEP_START:
		{
			buzzer_pwm_start();
		  s_beep_status = BEEP_SOUNDING;
		  cnt = 0;
			break;
		}
		case BEEP_SOUNDING:
			if(++cnt >= 10)
			{
				s_beep_status = BEEP_STOP;
			  buzzer_pwm_stop();
			}
			break;
		default:
			break;
	}
	
}


  • pwm频率计算 

  #define  BUZZER_BEEP       (uint32_t)(244 - 1)   

   buzzer_TimHandle.Init.Prescaler         = 48-1;   

  buzzer_TimHandle.Init.ClockDivision     = 0;

  buzzer_TimHandle.Init.Period            = BUZZER_BEEP;
 
  buzzer_TimHandle.Init.CounterMode       = TIM_COUNTERMODE_UP;
  buzzer_TimHandle.Init.RepetitionCounter = 0;
  buzzer_TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; 

MCU工作频率为48MHz,预分频为48,时钟分频为1,则PWM时钟源频率为1MHz,周期为244us,向上计数,则pwm的频率为1000000/244=4098Hz

  • BSP_pwm.h中的内容如下

#ifndef __BSP_PWM_H_
#define __BSP_PWM_H_
#include "main.h"

#ifdef __cplusplus
extern "C" {
#endif



typedef enum
{
	BEEP_START = 1,
	BEEP_SOUNDING,
	BEEP_STOP,
}E_BUZZER_STATUS;



void start_buzzer_beep_sound(void);
void buzzer_beep_sound_handler(void);

#ifdef __cplusplus
}
#endif

#endif
  • 在main函数中调用start_buzzer_beep_sound函数启动一次蜂鸣器嘀声

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	RTT_INIT();
  HAL_Init();
  SystemClock_Config();
 
	BSP_adc_init();
	
  BSP_wdt_init(5000);
   
	delay_init();
  
	
	MX_RTC_Init();
	
	 BSP_start_adc_count(8);
	
	start_buzzer_beep_sound();
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
	if(s_wakeup_flag)  //任务处理模式
	{
		BSP_wdt_feed();
		tick_25hz_handler();
		tick_1hz_handler();
	}
	else  // 省电模式
	{
	}
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
  • 在tick_25hz_handler函数中调用buzzer_beep_sound_handler函数处理pwm产生嘀声

/**
* @brief 25Hz handler
*
*/
static void tick_25hz_handler(void)
{
	if((s_wakeup_flag & TICK_FOR_25HZ) == 0)
	  return;
	s_wakeup_flag &= CLEAR_TICK_FOR_25HZ;
//####################################################################################
	//---------TODO this to add 25hz event handler-----------
	BSP_adc_convert_handler();
  buzzer_beep_sound_handler();
}
  • 运行结果,每次上电或复位都会产生一次嘀声,Demo下载链接

https://download.csdn.net/download/mygod2008ok/12540745