GPIO Latch
该示例使用ENH_TIM0,实现 GPIO 触发锁存器状态,并记录计数器计数的功能。
P2_4设定为GPIO输出引脚,设定P2_4引脚电平随时间变化不断翻转。
P2_2设定为GPIO输入引脚,同时将该引脚设定为ENHTIM的计数触发引脚。
将P2_2与P2_4引脚连接,当P2_2电压发生上升沿变化时会触发计数。累计变化三次后,触发ENHTIM中断,在中断函数内打印三次触发时计数器数值。
环境需求
该示例支持以下开发套件:
Hardware Platforms |
Board Name |
---|---|
RTL87x2G HDK |
RTL87x2G EVB |
更多信息请参考快速入门。
硬件连线
连接P2_4和P2_2。
编译和下载
该示例的工程路径如下:
Project file: samples\peripheral\enhtimer\latch_gpio\proj\rtl87x2g\mdk
Project file: samples\peripheral\enhtimer\latch_gpio\proj\rtl87x2g\gcc
请按照以下步骤操作构建并运行该示例:
打开工程文件。
按照 快速入门 中 编译APP Image 给出的步骤构建目标文件。
编译成功后,在路径
mdk\bin
或gcc\bin
下会生成 app binapp_MP_xxx.bin
文件。按下复位按键,开始运行。
测试验证
当EVB启动后,在Debug Analyzer工具内观察如下log。
Start latch_gpio test!
当P2_2和P2_4引脚连接后,在Debug Analyzer工具上,会不断打印GPIO触发锁存时的计数器数值。
代码介绍
该章节分为以下几个部分:
源码路径
工程路径:
sdk\samples\peripheral\enhtimer\latch_gpio\proj
源码路径:
sdk\samples\peripheral\enhtimer\latch_gpio\src
该工程的工程文件代码架构如下:
└── Project: input_polling
└── secure_only_app
└── Device includes startup code
├── startup_rtl.c
└── system_rtl.c
├── CMSIS includes CMSIS header files
├── CMSE Library Non-secure callable lib
├── Lib includes all binary symbol files that user application is built on
└── rtl87x2g_io.lib
├── Peripheral includes all peripheral drivers and module code used by the application
├── rtl_rcc.c
├── rtl_pinmux.c
├── rtl_gpio.c
├── rtl_nvic.c
└── rtl_enh_tim.c
└── APP includes the ble_peripheral user application implementation
├── main_ns.c
└── io_latch_gpio.c
初始化
初始化流程包括了 board_gpio_init
, driver_gpio_init
和 driver_enhance_timer_init
。
board_gpio_init
中包含了PAD与PINMUX设置。
配置PAD:设置引脚、PINMUX模式、PowerOn、内部上拉。
配置PINMUX:分配引脚为GPIO功能。
driver_gpio_init
包含了对GPIO外设的初始化。
使能PCC时钟。
设置GPIO的输出引脚
GPIO_Pin
为P2_4。在GPIO初始化中,设置
GPIO_Dir
为输出模式。
RCC_PeriphClockCmd(APBPeriph_GPIOA, APBPeriph_GPIOA_CLOCK, ENABLE);
...
GPIO_InitStruct.GPIO_Pin = GPIO_PIN_OUTPUT;
GPIO_InitStruct.GPIO_Dir = GPIO_DIR_OUT;
driver_enhance_timer_init
包含了对ENHTIM外设的初始化。
使能PCC时钟。
设置
ENHTIM_ClockDiv
为ENHTIM_CLOCK_DIVIDER_1
,即一分频模式。设置
ENHTIM_Mode
为ENHTIM_MODE_FreeRun
,即自由运行模式。设置
ENHTIM_LatchCountEn[0]
为ENABLE,即开启GPIO触发锁存功能。设置
ENHTIM_LatchCountTrigger[0]
为TRIGGER_RISING_EDGE,即上升沿触发。设置
ENHTIM_LatchCountThd
为3,即触发中断FIFO阈值为3。设置
ENHTIM_LatchTriggerPad
为INPUT_PIN。设置
ENHTIM_TimerGPIOTriggerEn
为ENABLE,即使能GPIO触发计时功能。配置ENHTIM中断;使能ENHTIM计时中断以及达到FIFO阈值中断;使能ENHTIM外设。
RCC_PeriphClockCmd(APBPeriph_ENHTIMER, APBPeriph_ENHTIMER_CLOCK, ENABLE);
...
ENHTIM_InitStruct.ENHTIM_ClockDiv = ENHTIM_CLOCK_DIVIDER_1;
ENHTIM_InitStruct.ENHTIM_Mode = ENHTIM_MODE_FreeRun;
ENHTIM_InitStruct.ENHTIM_LatchCountEn[0] = ENABLE;
ENHTIM_InitStruct.ENHTIM_LatchCountTrigger[0] = ENHTIM_LATCH_TRIGGER_RISING_EDGE;
ENHTIM_InitStruct.ENHTIM_LatchCountThd = 3;
ENHTIM_InitStruct.ENHTIM_LatchTriggerPad = INPUT_PIN;
/* Enable ENHTIM IRQ */
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = ENHTIMER_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
ENHTIM_ClearINTPendingBit(ENHTIMER_NUM, ENHTIM_INT_TIM);
ENHTIM_INTConfig(ENHTIMER_NUM, ENHTIM_INT_TIM, ENABLE);
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(ENHTIMER_NUM, ENABLE);
功能实现
当GPIO输入引脚上升沿触发次数达到FIFO设定阈值,触发RNHTIM中断,进入中断处理函数 Enhanced_Timer0_Handler
。
判断中断状态位是否为
ENHTIM_INT_LATCH_CNT_FIFO_THD
,失能中断。执行
ENHTIM_GetLatchCountFIFOLength()
,获取FIFO内数据个数。执行
ENHTIM_ReadLatchCountFIFO()
,获取计数值并打印。清除中断标志位,重新使能中断。
void Enhanced_Timer0_Handler()
{
...
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);
}
}