GPIO Latch
该示例使用 ENHTIM 实现外部信号变化时锁存计数器的功能。
将 P2_4 引脚配置为 GPIO 输出引脚,模拟外部信号变化,电平持续翻转。将 P2_2 配置为 ENHTIM 的输入引脚,用于检测外部信号变化。
将 P2_2 引脚和 P2_4 引脚连接,当 P2_2 检测到信号的上升沿变化时,ENHTIM 会触发一次计数。在累计触发计数三次后,会触发 ENHTIM_INT_LATCH_CNT_FIFO_THD
中断,在中断函数内执行用户应用程序。

Latch gpio 框图
用户可以通过不同的宏配置来修改引脚信息,定时时间等。具体宏配置详见 配置选项。
环境需求
该示例的环境需求,可参考 环境需求。
硬件连线
连接 P2_4 和 P2_2。
配置选项
可配置如下宏修改 GPIO 的输出引脚。
#define OUTPUT_PIN P2_4 #define GPIO_PIN GPIO_GetPin(OUTPUT_PIN) #define GPIO_PORT GPIO_GetPort(OUTPUT_PIN)
可配置如下宏修改 ENHTIM 的计数触发引脚。
#define INPUT_PIN P2_2
编译和下载
该示例的编译和下载流程,可参考 编译和下载。
测试验证
当 EVB 启动后,在 Debug Analyzer 工具内观察如下 log。
Start latch_gpio test!
初始化完成后,P2_4 持续翻转电平,P2_2 每检测到一次上升沿变化会记录当前计数器值。当 P2_2 累计检测到三次上升沿后,会触发
ENHTIM_INT_LATCH_CNT_FIFO_THD
中断,在中断函数内获取并打印 GPIO 三次触发锁存时的计数器数值。ENH_TIM0 ENHTIM_INT_LATCH_CNT2_FIFO_THD ENH_TIM0 fifo length = 3 ENH_TIM0 data[0] = xxx ENH_TIM0 data[1] = xxx ENH_TIM0 data[2] = xxx ENH_TIM0 ENHTIM_INT_LATCH_CNT2_FIFO_THD ...
由于 P2_4 持续翻转,
ENHTIM_INT_LATCH_CNT_FIFO_THD
中断会持续触发,持续打印 log。
代码介绍
该章节主要介绍示例中的初始化和相应功能实现的代码和流程说明
源码路径
工程文件和源码路径如下:
工程路径:
sdk\samples\peripheral\enhtimer\latch_gpio\proj
源码路径:
sdk\samples\peripheral\enhtimer\latch_gpio\src
初始化
外设的初始化流程可参考 General Introduction 中的 初始化流程 部分。
调用
Pad_Config()
与Pinmux_Config()
,配置对应引脚的 PAD 和 PINMUX 。void board_gpio_init(void) { Pad_Config(OUTPUT_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_HIGH); Pinmux_Config(OUTPUT_PIN, DWGPIO); }
调用
RCC_PeriphClockCmd()
,开启 GPIO 时钟。对 GPIO 外设进行初始化:
定义
GPIO_InitTypeDef
类型GPIO_InitStruct
,调用GPIO_StructInit()
将GPIO_InitStruct
预填默认值。根据需求修改
GPIO_InitStruct
参数,GPIO 的初始化参数配置如下表。调用GPIO_Init()
,初始化 GPIO 外设。
GPIO Hardware Parameters |
Setting in the |
GPIO |
---|---|---|
GPIO pin |
|
|
GPIO direction |
调用
RCC_PeriphClockCmd()
,开启 ENHTIM 时钟。对 ENHTIM 外设进行初始化:
定义
ENHTIM_InitTypeDef
类型ENHTIM_InitStruct
,调用ENHTIM_StructInit()
将ENHTIM_InitStruct
预填默认值。根据需求修改
ENHTIM_InitStruct
参数,ENHTIM 的初始化参数配置如下表。调用ENHTIM_Init()
,初始化 ENHTIM 外设。
ENHTIM Hardware Parameters |
Setting in the |
ENHTIM |
---|---|---|
Counter mode |
||
Latch count function |
||
Counter latch trigger mode |
||
Latch counter fifo threshold |
3 |
|
Latch trigger pin |
|
调用
NVIC_Init()
,配置 NVIC。NVIC 相关配置可参考 中断配置。调用
ENHTIM_ClearINTPendingBit()
和ENHTIM_INTConfig()
,清除 ENHTIM 中断,使能 ENHTIM 中断。ENHTIM_ClearINTPendingBit(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT_FIFO_FULL); ENHTIM_INTConfig(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT_FIFO_FULL, ENABLE); ENHTIM_ClearINTPendingBit(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT_FIFO_THD); ENHTIM_INTConfig(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT_FIFO_THD, ENABLE);
调用
ENHTIM_Cmd()
使能 ENHTIM 外设。
功能实现
ENHTIM Latch 功能的流程如图所示:

ENHTIM Latch 流程图
当 ENHTIM 配置的触发引脚,检测到上升沿触发次数达到 FIFO 设定阈值,触发 ENHTIM 的 ENHTIM_INT_LATCH_CNT_FIFO_THD
中断,进入中断处理函数 Enhanced_Timer0_Handler
。
如果设定阈值过大,FIFO 中的数据来不及被搬走,就会触发 ENHTIM_INT_LATCH_CNT_FIFO_FULL
中断。
触发 FIFO 阈值中断
判断中断状态位是否为
ENHTIM_INT_LATCH_CNT_FIFO_THD
,失能中断。调用
ENHTIM_GetLatchCountFIFOLength()
,获取 FIFO 内数据个数。调用
ENHTIM_ReadLatchCountFIFO()
,获取计数值并打印。清除中断标志位,重新使能中断。
触发 FIFO 满中断
判断中断状态位是否为
ENHTIM_INT_LATCH_CNT_FIFO_FULL
。清除中断标志位。
void Enhanced_Timer0_Handler()
{
...
if (ENHTIM_GetINTStatus(ENH_TIM0, ENHTIM_INT_LATCH_CNT_FIFO_FULL))
{
APP_PRINT_INFO0("ENH_TIM0 ENHTIM_INT_LATCH_CNT2_FIFO_FULL\r\n");
ENHTIM_ClearINTPendingBit(ENH_TIM0, ENHTIM_INT_LATCH_CNT_FIFO_FULL);
}
if (ENHTIM_GetINTStatus(ENH_TIM0, ENHTIM_INT_LATCH_CNT_FIFO_THD))
{
APP_PRINT_INFO0("ENH_TIM0 ENHTIM_INT_LATCH_CNT2_FIFO_THD\r\n");
ENHTIM_INTConfig(ENHTIMER_NUM, ENHTIM_INT_LATCH_CNT_FIFO_THD, DISABLE);
uint8_t length = ENHTIM_GetLatchCountFIFOLength(ENH_TIM0);
uint32_t data[4] = {0};
ENHTIM_ReadLatchCountFIFO(ENH_TIM0, data, length);
/* Only for debugging, removed in actual application. */
APP_PRINT_INFO1("ENH_TIM0 fifo length = %d\r\n", length);
for (uint8_t i = 0; i < length; i++)
{
/* Only for debugging, removed in actual application. */
APP_PRINT_INFO2("ENH_TIM0 data[%d] = 0x%x\r\n", i, data[i]);
}
ENHTIM_ClearINTPendingBit(ENH_TIM0, ENHTIM_INT_LATCH_CNT_FIFO_THD);
ENHTIM_INTConfig(ENH_TIM0, ENHTIM_INT_LATCH_CNT_FIFO_THD, ENABLE);
}
}