28.4
实验1:基本定时功能
本实验内容适用于野火启明6M5、启明4M2、启明2L1开发板。本实验较为简单,我们将使用AGT定时器进行定时并触发中断请求产生中断,然后通过这个中断,切换LED的电平。
28.4.1
硬件设计
本次实验需要使用到LED灯来展示定时的效果,LED灯具体的电路讲解请读者参考本教程“实验:使用寄存器点亮LED灯”小节的内容。
注
本实验仅用到LED1~3当中的其中一盏。
28.4.2
软件设计
26.4.2.1
新建工程
由于本实验需要用到LED,也会用到串口打印提示信息,因此我们在前面串口通信章节的“实验1:UART收发回显”例程的基础上修改程序。
对于e2 studio开发环境:拷贝一份我们之前的e2s工程模板“19_UART_Receive_Send”,然后将工程文件夹重命名为“28_AGT_Basic_Timing”,最后再将它导入到我们的e2 studio工作空间中。
对于Keil开发环境:拷贝一份我们之前的Keil工程模板“19_UART_Receive_Send”,然后将工程文件夹重命名为“28_AGT_Basic_Timing”,并进入该文件夹里面双击Keil工程文件,打开该工程。
工程新建好之后,在工程根目录的“src”文件夹下面新建“agt”文件夹,再进入“agt”文件夹里面新建源文件和头文件:“bsp_agt_timing.c”和“bsp_agt_timing.h”。工程文件结构如下。
列表1:文件结构
左右滑动查看完整内容
28_AGT_Basic_Timing ├─ ...... └─ src ├─ led │ ├─ bsp_led.c │ └─ bsp_led.h ├─ debug_uart │ ├─ bsp_debug_uart.c │ └─ bsp_debug_uart.h ├─ agt │ ├─ bsp_agt_timing.c │ └─ bsp_agt_timing.h └─ hal_entry.c
26.4.2.2
FSP配置
首先打开FSP配置界面,在Stacks中加入AGT,如下图所示。

点击可查看大图
我们使用AGT0来实现定时和触发中断功能,需要修改的只有“General”和“Interrupts”部分,其他按照默认即可。AGT模块的FSP配置属性如下图所示:

点击可查看大图
注
这里的计数源(Count Source)时钟需要更改为LOCO或者SUBCLOCK(两者的时钟频率都是32.768KHz),这是因为如果默认用PCLKB,它的时钟频率很高——50MHz(作为AGT计数源可设置最高8分频),而AGT计数器仅为16位,最高计数2的16次方,即65536,通过如下计算可以知道,这种情况下AGT定时器无法定时到足够的1秒钟。
• 当使用50MHz的PCLKB计数源时,AGT最大可定时时间为:65536 * (1 / (50/8)) =10485.76 us=10.48576ms。
• 10.48576毫秒远小于1秒,因此使用PCLKB=50MHz / 8分频作为时钟源的情况下AGT无法实现定时1秒。
对此的解决方法就是降低PCLKB的时钟频率,或者干脆直接换用另一个时钟频率较低的计数源:LOCO或者SUBCLOCK。实际上还有另一个方法是定时器仅定时1毫秒产生中断,然后在中断里用程序计数1000次即1秒,但是CPU频繁地进入中断是有可能会影响应用程序的性能的,这需要根据实际情况做出判断。
AGT模块配置属性描述如下:
表3:AGT属性描述:“Common”部分

表4:AGT属性描述:“General”部分

表5:AGT属性描述:“Interrupts”部分

28.4.2.3
AGT初始化函数
列表2:AGT初始化函数
左右滑动查看完整内容
/* AGT 初始化函数*/
voidAGT_Timing_Init(void)
{
/* 初始化AGT 模块*/
R_AGT_Open(&g_timer_agt0_ctrl, &g_timer_agt0_cfg);
/* 启动AGT 定时器*/
R_AGT_Start(&g_timer_agt0_ctrl);
}
在AGT初始化函数里面,首先调用R_AGT_Open函数初始化AGT模块,随后调用R_AGT_Start函数来启动AGT定时器。
28.4.2.4
AGT中断回调函数
列表3:AGT中断回调函数
左右滑动查看完整内容
/* 定时器溢出中断回调函数*/
voidagt0_timing_callback(timer_callback_args_t * p_args)
{
if (TIMER_EVENT_CYCLE_END == p_args->event)
{
/* 翻转LED1 */
LED1_TOGGLE; //每秒翻转一次
}
}
中断回调函数非常简单,使用if语句判断引起中断的事件,若是定时器溢出中断(TIMER_EVENT_CYCLE_END)则翻转一次LED1的电平。
28.4.2.5
hal_entry入口函数
注
以下hal_entry函数是以启明6M5开发板的代码为例,读者需要注意另外两块板子的调试串口初始化函数名不是“Debug_UART4_Init”。
列表4:hal_entry函数
左右滑动查看完整内容
/* 用户头文件包含*/
#include"led/bsp_led.h"
#include"debug_uart/bsp_debug_uart.h"
#include"gpt/bsp_gpt_timing.h"
voidhal_entry(void)
{
/* TODO: add your own code here */
LED_Init(); // LED 初始化
Debug_UART4_Init(); // SCI4 UART 调试串口初始化
AGT_Timing_Init(); // AGT 初始化
printf("这是一个AGT 的基本定时功能实验
");
while(1)
{
printf("The program is running ...
");
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
28.4.3
下载验证
编译并下载到开发板后,复位板子让程序运行,然后可以观察到板载LED1(红色)每秒钟翻转一次状态,即以两秒为周期在缓慢闪烁。
全部0条评论
快来发表一下你的评论吧 !