Timer Interrupt

该示例使用 TIM ,实现 1s 的定时功能。

为了便于观察现象,连接 P0_1 和 LED0。

定时时间到,触发中断,在中断处理函数中翻转 P0_1,改变 GPIO 输出极性,实现 LED0 每秒闪烁。

环境需求

该示例支持以下开发套件:

开发套件

Hardware Platforms

Board Name

RTL8752H HDK

RTL8752H EVB

更多信息请参考 快速入门

硬件连线

连接 P0_1 和 LED0 小灯。

LED 驱动电路如下图所示。

这里应该是LED驱动电路图片

LED 驱动电路图

编译和下载

该示例的工程路径如下:

Project file: board\evb\io_sample\TIM\Timer_interrupt\mdk

Project file: board\evb\io_sample\TIM\Timer_interrupt\gcc

请按照以下步骤操作构建并运行该示例:

  1. 打开工程文件。

  2. 按照 快速入门编译 APP Image 给出的步骤构建目标文件。

  3. 编译成功后,在路径 mdk\bingcc\bin 下会生成 app bin app_MP_xxx.bin 文件。

  4. 按照 快速入门MP Tool 给出的步骤将 app bin 烧录至 EVB 内。

  5. 按下 reset 按键,开始运行。

测试验证

当P0_1和LED0连接后,可观察到LED0每1秒闪烁一次。

代码介绍

该章节分为以下几个部分:

  1. 源码路径

  2. 初始化函数将在 初始化 章节介绍。

  3. 初始化后的功能实现将在 功能实现 章节介绍。

源码路径

  • 工程路径: sdk\board\evb\io_sample\TIM\Timer_interrupt

  • 源码路径: sdk\src\sample\io_sample\TIM\Timer_interrupt

该工程的工程文件代码结构如下:

└── Project: timer_interrupt
    └── secure_only_app
        └── include
            ├── app_define.h
            └── rom_uuid.h
        ├── cmsis                    includes CMSIS header files and startup files
            ├── overlay_mgr.c
            ├── system_rtl876x.c
            └── startup_rtl876x.s
        ├── lib                      includes all binary symbol files that user application is built on
            ├── rtl8752h_sdk.lib
            ├── gap_utils.lib
            └── ROM.lib
        ├── peripheral               includes all peripheral drivers and module code used by the application
            ├── rtl876x_rcc.c
            ├── rtl876x_pinmux.c
            ├── rtl876x_nvic.c
            ├── rtl876x_gdma.c
            └── rtl876x_adc.c
        ├── profile
        └── app                      includes the ble_peripheral user application implementation
            └── main.c

初始化

当 EVB 复位启动时,执行 main 函数,执行以下流程:

int main(void)
{
    extern uint32_t random_seed_value;
    srand(random_seed_value);
    __enable_irq();

    tim_demo();

    while (1)
    {

    }
}

tim_demo 中,包含 PAD/PINMUX 设置, GPIO 和 TIM 外设的初始化。

void tim_demo(void)
{
    timer_demo();
}

void timer_demo(void)
{
    LED_Status = 0;
    board_gpio_init();
    driver_gpio_init();
    driver_timer_init();
}

board_gpio_init 为 GPIO 相关的 PAD/PINMUX 设置,包含如下流程:

  1. 配置 PAD:设置引脚,PINMUX 模式,PowerOn,无内部上拉,输出低。

  2. 配置 PINMUX:配置引脚为 DWGPIO 功能。

void board_gpio_init(void)
{
    Pad_Config(GPIO_OUTPUT_PIN_0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW);
    Pinmux_Config(GPIO_OUTPUT_PIN_0, DWGPIO);
}

driver_gpio_init 为 GPIO 外设的初始化,包含如下流程:

  1. 使能 RCC 时钟。

  2. 设置 GPIO 的引脚为输出模式,失能中断。

  3. 设置 GPIO 引脚输出低。

void driver_gpio_init(void)
{
    /* Initialize GPIO peripheral */
    RCC_PeriphClockCmd(APBPeriph_GPIO, APBPeriph_GPIO_CLOCK, ENABLE);

    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin    = GPIO_PIN_OUTPUT;
    GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_ITCmd  = DISABLE;
    GPIO_Init(&GPIO_InitStruct);
    GPIO_ResetBits(GPIO_PIN_OUTPUT);
}

driver_timer_init 为 TIM 外设的初始化,包含如下流程:

  1. 使能 RCC 时钟。

  2. 配置 TIM 为用户自定义模式。

  3. 失能 PWM 输出功能,设置 TIM 的周期。

  4. 配置和使能 TIM 的 IRQ 通道。

  5. 配置 TIM 中断,使能 TIM。

void driver_timer_init(void)
{
    RCC_PeriphClockCmd(APBPeriph_TIMER, APBPeriph_TIMER_CLOCK, ENABLE);

    TIM_TimeBaseInitTypeDef TIM_InitStruct;
    TIM_StructInit(&TIM_InitStruct);

    TIM_InitStruct.TIM_PWM_En = PWM_DISABLE;
    TIM_InitStruct.TIM_Period = TIMER_PERIOD ;
    TIM_InitStruct.TIM_Mode = TIM_Mode_UserDefine;
    TIM_TimeBaseInit(TIMER_NUM, &TIM_InitStruct);

    /*  Enable TIMER IRQ  */
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = TIMER_IRQN;
    NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);

    TIM_ClearINT(TIMER_NUM);
    TIM_INTConfig(TIMER_NUM, ENABLE);
    TIM_Cmd(TIMER_NUM, ENABLE);

}

功能实现

当 TIM 定时时间到后,触发中断,进入中断处理函数 Timer4_Handler

  1. 清除 TIM 中断,失能 TIM。

  2. 判断当前 LED 状态,翻转 GPIO 输出电平。

  3. 重新使能 TIM。

void Timer4_Handler(void)
{

    TIM_ClearINT(TIM4);
    TIM_Cmd(TIM4, DISABLE);
    if (!LED_Status)
    {
        GPIO_SetBits(GPIO_PIN_OUTPUT);
        LED_Status = 1;
    }
    else
    {
        GPIO_ResetBits(GPIO_PIN_OUTPUT);
        LED_Status = 0;
    }
    //Add user code here
    TIM_Cmd(TIM4, ENABLE);

}