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
相关文章
- Linux USB 摄像头驱动
- appium,参数化,数据驱动
- 关于领域驱动设计(DDD)中聚合设计的一些思考
- csv 文件驱动的 jMeter 并发测试
- RK系列驱动开发
- 1.安卓访问驱动-实现简单驱动
- 常用驱动的工作原理和实现机制
- rk3288驱动调试记录
- 基于数据驱动的智能空调系统需求响应可控潜力评估研究(Matlab代码实现)
- Mock服务设计与实现:MySQL驱动字节码修改增强
- Linux I2C设备驱动编写(一)
- 【Spring注解驱动开发】如何实现方法、构造器位置的自动装配?我这样回答让面试官很满意!
- 【Spring注解驱动开发】使用@PropertySource加载配置文件,我只看这一篇!!
- LabVIEW开发电机驱动单元通用测试系统
- 【测试开发】Junit5 + YAML 轻松实现参数化和数据驱动,让 App 自动化测试更高效(一)
- 前端web自动化测试:selenium怎么实现关键字驱动
- Python自动化测试:pytest实现关键字驱动
- IGBT和SiC MOSFET的驱动参数的计算方法
- 自研开源项目(3)基于pytest和数据驱动的自定义接口自动化框架caterpillar_apitest
- FPGA-(OV摄像头SCCB协议)IIC驱动代码
- ZYNQ-实现外设驱动开发-iic接口的温湿度传感器si7021
- ZYNQ-利用PS引脚实现EMIO GPIO的驱动
- ZYNQ-实现外设驱动开发-iic接口的光强度传感器GY-30
- Linux: Ethernet驱动Mellanox:mlx5,driver
- VB.net:VB.net编程语言学习之基于VS软件利用VB.net语言实现对SolidWorks进行二次开发的案例应用(启动SolidWorks代码/直接驱动模型代码/路径下模型驱动代码/创建两个文