打印
[开发板与模块]

【ESK32-30519 + ESK32-21001测评】02.TIMER+BUZZER

[复制链接]
3183|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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 还内建可处理编码器接口信号的带两个输入口的正交解码器。




原理图
  • ESK32-30519




  • ESK32-21001






引脚复用



实现功能
参考官方例程,通过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)

使用特权

评论回复

相关帖子

沙发
海滨消消| | 2022-10-10 14:53 | 只看该作者
这是什么时候的测评活动啊

使用特权

评论回复
板凳
xld0932|  楼主 | 2022-10-10 15:00 | 只看该作者
海滨消消 发表于 2022-10-10 14:53
这是什么时候的测评活动啊

HT32F54253触控开发板 免费申请评测福利活动
https://bbs.21ic.com/icview-3243964-1-1.html?fromuser=xld0932
(出处: 21ic电子技术开**坛)

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:上海灵动微电子股份有限公司资深现场应用工程师
简介:诚信·承诺·创新·合作

67

主题

2995

帖子

29

粉丝