问答

汇集网友智慧,解决技术难题

21ic问答首页 - hc32l110使用定时器控制led灯亮灭

小华半导体 hc32l110 单片机 技术交流

hc32l110使用定时器控制led灯亮灭

ewrwer2025-04-22
hc32l110使用定时器控制led灯亮灭,设置的是500ms亮,500ms灭,将程序写入单片机灯亮灭的时间远超500ms,使用的是官方开发板,系统时钟设置为24MHZ,定时器分频为16,重装载值为1499。求指导是什么原因引起的,谢谢

uint32_t SystemCoreClock = 4000000;
//add clock source.
void SystemCoreClockUpdate (void) // Update SystemCoreClock variable
{
    SystemCoreClock = Clk_GetHClkFreq();
}


/**
******************************************************************************
** \brief  对MCU未引出IO端口进行默认配置.
**
** \param  none
** \return none
******************************************************************************/
static void _HidePinInit(void)
{
#if !defined(HC32L110Cxxx)       //20PIN MCU       
    uint32_t tmpReg = M0P_CLOCK->PERI_CLKEN;
        M0P_CLOCK->PERI_CLKEN_f.GPIO = 1;

  #if defined(HC32L110Bxxx)             //16PIN MCU
    M0P_GPIO->P0ADS &= 0x07;     ///< P03配置为数字端口
        M0P_GPIO->P3ADS &= 0xE3;     ///< P32/P33/P34配置为数字端口
    M0P_GPIO->P0DIR        |= 0xF8;     ///< P03配置为端口输入
    M0P_GPIO->P3DIR        |= 0x1C;     ///< P32/P33/P34配置为端口输入
        M0P_GPIO->P0PU  |= 0xF8;     ///< P03配置为上拉
        M0P_GPIO->P3PU  |= 0x1C;     ///< P32/P33/P34配置为上拉

  #endif
          M0P_CLOCK->PERI_CLKEN = tmpReg;
#endif
}


/**
******************************************************************************
** \brief  Setup the microcontroller system. Initialize the System and update
** the SystemCoreClock variable.
**
** \param  none
** \return none
******************************************************************************/
void SystemInit(void)
{
    stc_clk_systickcfg_t stcCfg;

    // TODO 从Flash加载修调值并启用内部高速时钟(当前为手动设置24MHz)
    Clk_SetRCHFreq(ClkFreq24Mhz);  // 设置内部高速时钟频率为24MHz
    Clk_Enable(ClkRCH, TRUE);     // 启用内部高速时钟

    SystemCoreClockUpdate();      // 更新系统核心时钟频率变量
    _HidePinInit();               // 初始化未使用的隐藏引脚

    // 配置系统定时器
    DDL_ZERO_STRUCT(stcCfg);      // 清零配置结构体
    stcCfg.bNoRef = TRUE;         // 不使用外部参考时钟(使用内核时钟)
    stcCfg.u32LoadVal = 0xFFFFFF; // 设置24位重载值(最大计数值)
    Clk_SysTickConfig(&stcCfg);   // 应用SysTick配置
}
#include "gpio.h"
#include "IR_light.h"
#include "bsp_key.h"
#include "base_tim.h"
extern volatile uint16_t msCounter;
void system_clock(void);
int main(void)
{
        system_clock();
        base_tim_init();
        IR_light_Init();
        while(1)
        {
                if (msCounter < 500)
                {
                        IR_light_On();
                }
                else
                {
                        IR_light_Off();
                }
                // 当计数器达到1000时重置
                if (msCounter >= 1000)
                {
                        msCounter = 0;
                }

        }
}


void system_clock(void)
{
    //CLK INIT
    stc_clk_config_t stcClkCfg;
    stcClkCfg.enClkSrc  = ClkRCH;
    stcClkCfg.enHClkDiv = ClkDiv1;
    stcClkCfg.enPClkDiv = ClkDiv1;

    Clk_Init(&stcClkCfg);
}
#include "base_tim.h"
en_result_t enResult ;
// 全局变量
volatile uint16_t msCounter = 0;

//使用16分频 + 重装载值1499   定时器时钟= 24MHz/16=1.5MHz(0.6667μs/周期)  重装载值=1.5MHz×1ms−1=1499  1.5MHz/(1499+1)=1ms
en_result_t base_tim_init(void)  
{  
    uint16_t          u16ArrData = 1499;     // 自动重装载值
    uint16_t          u16InitCntData = 0;     // 初始计数值;
    // 初始化定时器0
    // ...
    Clk_SetPeripheralGate( ClkPeripheralBt, TRUE );//使能定时器0

    //定时器基础配置
    stc_bt_config_t  timerConfig;    //定时器配置结构体`
    timerConfig.enGate = BtGateDisable;    //门控极性控制,门控禁止
    timerConfig.enPRS = BtPCLKDiv16;    //预分频器配置,16分频
    timerConfig.enTog = BtTogDisable;    //反转输出使能,禁止
    timerConfig.enCT = BtTimer;    //定时/计数功能选择,定时器功能
    timerConfig.enMD = BtMode2;    //计数模式配置,16位计数器/定时器
    timerConfig.pfnTim0Cb = tim0_handler;    //定时器0回调函数
    //Bt初始化
    if (Ok != Bt_Init(TIM0, &timerConfig))
    {
        enResult = Error;
    }
    //中断使能
    Bt_ClearIntFlag(TIM0);    //清除中断标志
    Bt_EnableIrq(TIM0);    //使能更新中断
    EnableNvic(TIM0_IRQn,3,TRUE);
    //设置重载值,计数值,启动计数
    Bt_ARRSet(TIM0, u16ArrData);
    Bt_Cnt16Set(TIM0, u16InitCntData);
    Bt_Run(TIM0);
    return enResult;
}
void tim0_handler(void)
{
    if (Bt_GetIntFlag( TIM0 ))
    {
        // 清除中断标志
        Bt_ClearIntFlag(TIM0);
        msCounter++;
    }
}
#include "IR_light.h"
//led---P03
void IR_light_Init(void)
{
    Gpio_InitIO(0,3 ,GpioDirOut );       
}
void IR_light_On(void)
{
    Gpio_SetIO(0,3,1);
}
void IR_light_Off(void)
{
    Gpio_SetIO(0,3,0);
}
根据代码中IR_light理论是500ms亮500ms灭为什么在硬件上灯亮灭一次时间远远超过500ms?
回答 +关注 0
61人浏览 0人回答问题 分享 举报
0 个回答

您需要登录后才可以回复 登录 | 注册