ESK32-21001扩展板上带有一个无源蜂鸣器,根据无源蜂鸣器的驱动原理我们需要使用MCU的PWM资源来控制,可以是通过GPTM定时器来实现硬件输出PWM,也可以通过GPTM定时器来控制GPIO的输出电平翻来实现软件输出PWM,从控制方式来说,硬件PWM更加节省软件资源,相比于软件PWM的实现方式,阻塞更少。
HT32F54253通用功能定时器GPTM
▆16-bit 向上 / 向下自动重载计数器▆ 定时器多达 4 个独立通道
▆ 16-bit 可编程预分频器,可以对其时钟源进行 1 ~ 65536 之间的任意数值的分频产生计数
器时钟频率
▆ 输入捕捉功能
▆ 比较匹配输出
▆ PWM 波形产生功能,具有边沿对齐和中心对齐两种计数模式
▆ 单脉冲输出模式
▆ 内建可处理编码器接口信号的带两个输入口的正交解码器
通用定时器包括一个 16-bit 向上 / 向下计数器,四个 16-bit 捕捉 / 比较寄存器 (CCR),一个 16-bit计数器重载寄存器 (CRR) 和多个控制 / 状态寄存器。它们可用于多种用途,包括通用计时、输入信号脉冲宽度测量、输出波形产生,如单脉冲波形产生或 PWM 输出。 GPTM 还内建可处理编码器接口信号的带两个输入口的正交解码器。
原理图
引脚复用
实现功能
参考官方例程,通过GPTM定时器的PWM输出引脚,实现对BUZZER的控制,让其输出声响。
实现代码
- /*******************************************************************************
- * [url=home.php?mod=space&uid=288409]@file[/url] BUZZER.c
- * [url=home.php?mod=space&uid=187600]@author[/url] King
- * [url=home.php?mod=space&uid=895143]@version[/url] V1.00
- * [url=home.php?mod=space&uid=212281]@date[/url] 07-Oct-2022
- * [url=home.php?mod=space&uid=247401]@brief[/url] ......
- *******************************************************************************/
- /* Define to prevent recursive inclusion -------------------------------------*/
- #define __BUZZER_C__
- /* Includes ------------------------------------------------------------------*/
- #include "BUZZER.h"
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- #define BEE_TM_PRE (4)
- #define BEE_SYS_CLK (LIBCFG_MAX_SPEED) // Calculate with fix value (#define)
- #define BEE_DUTY (40) // 40%
- /* Private macro -------------------------------------------------------------*/
- #define BEE_TIME_MS(t, f) ((f) * (t) / 1000)
- /* Private variables ---------------------------------------------------------*/
- volatile uint16_t BUZZER_Times;
- volatile uint16_t BUZZER_Active;
- volatile uint16_t BUZZER_InActive;
- volatile uint32_t BUZZER_Count;
- /* Private function prototypes -----------------------------------------------*/
- /* Private functions ---------------------------------------------------------*/
- /* Exported variables --------------------------------------------------------*/
- /* Exported function prototypes ----------------------------------------------*/
- /*******************************************************************************
- * @brief
- * @param
- * @retval
- * [url=home.php?mod=space&uid=93590]@Attention[/url]
- *******************************************************************************/
- void BUZZER_Init(uint32_t uFrequency)
- {
- /* Enable peripheral clock */
- CKCU_PeripClockConfig_TypeDef CKCUClock = {{ 0 }};
- CKCUClock.Bit.AFIO = 1;
- CKCUClock.Bit.GPTM0 = 1;
- CKCU_PeripClockConfig(CKCUClock, ENABLE);
- /* Configure AFIO mode as TM function */
- AFIO_GPxConfig(GPIO_PC, AFIO_PIN_12, AFIO_FUN_GPTM0);
- uint32_t Reload = (BEE_SYS_CLK / BEE_TM_PRE / uFrequency) - 1;
- /* Time base configuration */
- TM_TimeBaseInitTypeDef TimeBaseInit;
- TimeBaseInit.Prescaler = BEE_TM_PRE - 1;
- TimeBaseInit.CounterReload = Reload;
- TimeBaseInit.RepetitionCounter = 0;
- TimeBaseInit.CounterMode = TM_CNT_MODE_UP;
- TimeBaseInit.PSCReloadTime = TM_PSC_RLD_IMMEDIATE;
- TM_TimeBaseInit(HT_GPTM0, &TimeBaseInit);
- TM_ClearFlag(HT_GPTM0, TM_FLAG_UEV);
- /* Channel n output configuration */
- TM_OutputInitTypeDef OutputInit;
- OutputInit.Channel = TM_CH_2;
- OutputInit.OutputMode = TM_OM_PWM2;
- OutputInit.Control = TM_CHCTL_DISABLE;
- OutputInit.ControlN = TM_CHCTL_DISABLE;
- OutputInit.Polarity = TM_CHP_NONINVERTED;
- OutputInit.PolarityN = TM_CHP_NONINVERTED;
- OutputInit.IdleState = MCTM_OIS_LOW;
- OutputInit.IdleStateN = MCTM_OIS_HIGH;
- OutputInit.Compare = ((Reload + 1) * (100 - BEE_DUTY)) / 100;
- OutputInit.AsymmetricCompare = 0;
- TM_OutputInit(HT_GPTM0, &OutputInit);
- /* Enable TM interrupt */
- NVIC_EnableIRQ(GPTM0_IRQn);
- }
- /*******************************************************************************
- * @brief
- * @param
- * @retval
- * @attention
- *******************************************************************************/
- void BUZZER_Start(uint16_t Times, uint16_t Frequency, uint16_t Active_ms, uint16_t InActive_ms)
- {
- uint32_t Reload = (BEE_SYS_CLK / BEE_TM_PRE / Frequency) - 1;
- uint32_t Compare = ((Reload + 1) * (100 - BEE_DUTY)) / 100;
- BUZZER_Times = Times;
- BUZZER_Active = BEE_TIME_MS(Active_ms, Frequency);
- BUZZER_InActive = BEE_TIME_MS(InActive_ms, Frequency);
- BUZZER_Count = BUZZER_Active + BUZZER_InActive;
- TM_SetCounterReload(HT_GPTM0, Reload);
- TM_SetCaptureCompare(HT_GPTM0, TM_CH_2, Compare);
- TM_IntConfig(HT_GPTM0, TM_INT_UEV, ENABLE);
- TM_ChannelConfig(HT_GPTM0, TM_CH_2, TM_CHCTL_ENABLE);
- TM_Cmd(HT_GPTM0, ENABLE);
- }
- /*******************************************************************************
- * @brief
- * @param
- * @retval
- * @attention
- *******************************************************************************/
- uint32_t BUZZER_IsFinish(void)
- {
- return (BUZZER_Times ? FALSE : TRUE);
- }
- /*******************************************************************************
- * @brief
- * @param
- * @retval
- * @attention
- *******************************************************************************/
- void GPTM0_IRQHandler(void)
- {
- TM_ClearFlag(HT_GPTM0, TM_INT_UEV);
- if(BUZZER_Count)
- {
- BUZZER_Count--;
- if(BUZZER_Count == BUZZER_InActive)
- {
- TM_ChannelConfig(HT_GPTM0, TM_CH_2, TM_CHCTL_DISABLE);
- }
- if(BUZZER_Count == 0)
- {
- BUZZER_Count = BUZZER_Active + BUZZER_InActive;
- TM_ChannelConfig(HT_GPTM0, TM_CH_2, TM_CHCTL_ENABLE);
- if(BUZZER_Times)
- {
- BUZZER_Times--;
- }
- if(BUZZER_Times == 0)
- {
- TM_Cmd(HT_GPTM0, DISABLE);
- }
- }
- }
- }
- /*******************************************************************************
- * @brief
- * @param
- * @retval
- * @attention
- *******************************************************************************/
- void BUZZER_Demo(void)
- {
- /* BUZZER 4 times, 3 kHz, active 50 ms, inactive 50 ms */
- BUZZER_Init(0);
- BUZZER_Start(4, 3000, 50, 50);
- while(BUZZER_IsFinish() == FALSE);
- /* BUZZER 2 times, 800 Hz, active 1000 ms, inactive 500 ms */
- BUZZER_Init(0);
- BUZZER_Start(2, 800, 1000, 500);
- while(BUZZER_IsFinish() == FALSE);
- }
运行结果
上电后,蜂鸣器先是以3kHz的频率间隔50ms快速响4声音,然后再以800Hz的频率响1秒停顿0.5秒的节奏循环响2个周期。
软件工程源代码
Project.zip
(845.42 KB, 下载次数: 10)
|