国民技术N32G457REL7 TIMER的使用

1.认识定时器

        定时器是一种用于计时的机械或电子装置,广泛应用于各种领域。它的基本原理是通过计数来实现计时功能。定时器内部通常包含一个计数器,该计数器根据输入的时钟信号进行计数,从而计算出时间。

        另外定时器还可以用于构造PWM脉冲调制信号,用于电机以及LED等等电子设备的电压控制等等。

        定时器的定时周期:

                T = (重装载值寄存器的值+1)* (预分频值寄存器的值+1)/ 时钟频率;

2.PWM的构造及定义

        PWM(Pulse Width Modulation)控制是一种常见的电子技术,通过调整信号的脉冲宽度来实现对电路或设备的精确控制。这项技术在各个领域都有广泛的应用,从电机控制到照明调光,再到通信信号传输,都发挥着重要作用。

        可以通过定时器构造相应的PWM脉冲,通过设置定时器通道的占空比,控制对应通道输出高电平或者低电平的时间。占空比指的是,在定时器的定时周期内,定时器的通道输出高电平或者低电平的时间在定时周期的时间占比。

3.基本定时器的软件驱动

3.1 SDK下载

        这里采用国民官网提供的SDK包,以示例工程带领各位道友理解基本定时器的实现。SDK对应的下载链接如下:
- 半导体解决方案--国民技术|官方网站https://www.nationstech.com/support/dow/

        资源有中文版本和英文版本的,大家可以根据需求自行下载.

3.2 软件实现

        示例工程的路径如下:     

        该工程的功能可以参考工程中DOC/的readme文件查看,这里不做过多的解释.

/**
 * @brief  Configures the different system clocks.
 */
void RCC_Configuration(void)
{
    /* PCLK1 = HCLK/4 */
    RCC_ConfigPclk1(RCC_HCLK_DIV4);//这里选择的时钟频率为4分频,即定时器2的系统时钟为36MHz

    /* TIM2 clock enable */
    RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM2, ENABLE);//开启定时器2的时钟

    /* GPIOC clock enable */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOC, ENABLE);//开启定时器2通道对应IO的时钟
}

/**
 * @brief  Configure the GPIO Pins.
 */
void GPIO_Configuration(void)//这里就是配置了IO口
{
    GPIO_InitType GPIO_InitStructure;

    /* GPIOC Configuration:Pin6, 7, 8 and 9 as alternate function push-pull */
    GPIO_InitStruct(&GPIO_InitStructure);
    GPIO_InitStructure.Pin        = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitPeripheral(GPIOC, &GPIO_InitStructure);
}

/**
 * @brief  Configure the nested vectored interrupt controller.
 */
void NVIC_Configuration(void)//配置定时器的中断结构体,向中断控制器中注册中断
{
    NVIC_InitType NVIC_InitStructure;

    /* Enable the TIM2 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel                   = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;

    NVIC_Init(&NVIC_InitStructure);
}

int main(void)
{
    /* System Clocks Configuration */
    RCC_Configuration();

    /* NVIC Configuration */
    NVIC_Configuration();

    /* GPIO Configuration */
    GPIO_Configuration();

    /* ---------------------------------------------------------------
    TIM2 Configuration: Output Compare Timing Mode: 定时器的输出频率为6MHz
    TIM2 counter clock at 6 MHz
    CC1 update rate = TIM2 counter clock / CCR1_Val = 146.48 Hz
    CC2 update rate = TIM2 counter clock / CCR2_Val = 219.7 Hz
    CC3 update rate = TIM2 counter clock / CCR3_Val = 439.4 Hz
    CC4 update rate = TIM2 counter clock / CCR4_Val = 878.9 Hz
    --------------------------------------------------------------- */

    /* Compute the prescaler value */
    PrescalerValue = (uint16_t)(SystemCoreClock / 12000000) - 1;//计算重装载值

    /* Time base configuration */
    TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.Period    = 65535;//设置预分频值
    TIM_TimeBaseStructure.Prescaler = 0;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP;

    TIM_InitTimeBase(TIM2, &TIM_TimeBaseStructure);初始化定时器的结构体

    /* Prescaler configuration */
    TIM_ConfigPrescaler(TIM2, PrescalerValue, TIM_PSC_RELOAD_MODE_IMMEDIATE);//这里设置了定时器2的重装载值

    /* Output Compare Timing Mode configuration: Channel1 */
    TIM_InitOcStruct(&TIM_OCInitStructure);
    TIM_OCInitStructure.OcMode      = TIM_OCMODE_TIMING;
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = CCR1_Val;//设置定时器2通道1的比较值
    TIM_OCInitStructure.OcPolarity  = TIM_OC_POLARITY_HIGH;

    TIM_InitOc1(TIM2, &TIM_OCInitStructure);

    TIM_ConfigOc1Preload(TIM2, TIM_OC_PRE_LOAD_DISABLE);//这里失能2通道1的重载功能

    /* Output Compare Timing Mode configuration: Channel2 */
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = CCR2_Val;//设置定时器2通道2的比较值

    TIM_InitOc2(TIM2, &TIM_OCInitStructure);

    TIM_ConfigOc2Preload(TIM2, TIM_OC_PRE_LOAD_DISABLE);//这里失能2通道2的重载功能

    /* Output Compare Timing Mode configuration: Channel3 */
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = CCR3_Val;//设置定时器2通道3的比较值

    TIM_InitOc3(TIM2, &TIM_OCInitStructure);

    TIM_ConfigOc3Preload(TIM2, TIM_OC_PRE_LOAD_DISABLE);//这里失能2通道3的重载功能

    /* Output Compare Timing Mode configuration: Channel4 */
    TIM_OCInitStructure.OutputState = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.Pulse       = CCR4_Val;//设置定时器2通道4的比较值

    TIM_InitOc4(TIM2, &TIM_OCInitStructure);

    TIM_ConfigOc4Preload(TIM2, TIM_OC_PRE_LOAD_DISABLE);//这里失能2通道4的重载功能

    /* TIM IT enable */
    TIM_ConfigInt(TIM2, TIM_INT_CC1 | TIM_INT_CC2 | TIM_INT_CC3 | TIM_INT_CC4, ENABLE);//配置定时器2的中断

    /* TIM2 enable counter */
    TIM_Enable(TIM2, ENABLE);//使能定时器

    while (1)
        ;
}






       上述代码中采用的时钟源为HCLK,即下图所示的时钟频率为72M,所以4分频后对应的APB总线对应的时钟频率为18M,但当APB分频系数为2、4、8时,TIMxCLK=APB总线频率×2,由此定时器的时钟频率为18*2=36MHz,由此得到定时器当前软件配置的定时器的定时周期为:

T = (65535+1)*1 / 36000000 = 0.0018204444444444

约为0.0018秒即1毫秒左右的时间。

        工程功能如下图所示:

        即代码中设置的CCR寄存器的值与定时器的计数值进行比较,当定时器的计数值大于CCR寄存器的值时就会触发定时器的CCR1,CCR2,CCR3,CCR4的中断,在中断中,则会检测这些中断的标记为,当标记被置为后,定时器对应的通道将会将会输出与未触发中断前相反的电平状态。

        中断的处理代码具体如下:

        


/******************************************************************************/
/*                 N32G45X Peripherals Interrupt Handlers                     */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_n32g45x.s).                                                 */
/******************************************************************************/
void TIM2_IRQHandler(void)
{
    if (TIM_GetIntStatus(TIM2, TIM_INT_CC1) != RESET)
    {
        TIM_ClrIntPendingBit(TIM2, TIM_INT_CC1);

        /* Pin PC.06 toggling with frequency = 73.24 Hz */
        GPIO_WriteBit(GPIOC, GPIO_PIN_6, (Bit_OperateType)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_PIN_6)));
        capture = TIM_GetCap1(TIM2);
        TIM_SetCmp1(TIM2, capture + CCR1_Val);
    }
    else if (TIM_GetIntStatus(TIM2, TIM_INT_CC2) != RESET)
    {
        TIM_ClrIntPendingBit(TIM2, TIM_INT_CC2);

        /* Pin PC.07 toggling with frequency = 109.8 Hz */
        GPIO_WriteBit(GPIOC, GPIO_PIN_7, (Bit_OperateType)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_PIN_7)));
        capture = TIM_GetCap2(TIM2);
        TIM_SetCmp2(TIM2, capture + CCR2_Val);
    }
    else if (TIM_GetIntStatus(TIM2, TIM_INT_CC3) != RESET)
    {
        TIM_ClrIntPendingBit(TIM2, TIM_INT_CC3);

        /* Pin PC.08 toggling with frequency = 219.7 Hz */
        GPIO_WriteBit(GPIOC, GPIO_PIN_8, (Bit_OperateType)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_PIN_8)));
        capture = TIM_GetCap3(TIM2);
        TIM_SetCmp3(TIM2, capture + CCR3_Val);
    }
    else
    {
        TIM_ClrIntPendingBit(TIM2, TIM_INT_CC4);

        /* Pin PC.09 toggling with frequency = 439.4 Hz */
        GPIO_WriteBit(GPIOC, GPIO_PIN_9, (Bit_OperateType)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_PIN_9)));
        capture = TIM_GetCap4(TIM2);
        TIM_SetCmp4(TIM2, capture + CCR4_Val);
    }
}

4.PWM脉冲调制信号的构造,博主在下篇文章中更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值