在微五科技CF3310开发板上,提供了两个32 位可编程中断计时器模块:
其具体的处理逻辑如下:
通过对官方提供的pit32_demo的学习,了解到该定时器的基础使用方式。
要使用开发板上的定时器,有两个概念,我们需要先了解:
- 分频:为了得到准确的计时时间,通常使用开发板运行频率,取其2的整数次方 之一,得到一个合适的频率值,然后根据该频率值进行计数;否则,频率值过大,导致计数值增长太快,计数器溢出。
- 计数:在上述分频的基础上,进行计数,累积到预先设定的数值,就触发定时器进行具体的操作。
通过查看官方手册,可以了解到该开发板的具体可分频数:
在系统的src/hal/inc/pit32_hal.h中,也有具体的定义:
在pit32_demo中,分频取得是32:
那么,根据该分频,最终需要的计数值,则由下面的函数来计算:
如果系统运行在30MHz,则1秒对应的计数值为:
counter
= 30*10e6/32/1 = 937500
也就是说,每计数到该数值,就能触发一次计时器回调了。
在上述代码中,对定时器的具体设置说明如下:
PIT32_HandleTypeDef hpit32;
hpit32.instance = PIT1;
hpit32.init.counter = pit32_led_CalcCounter(g_ips_clk,PIT32_CLK_DIV_32,PIT32_1S);
hpit32.init.enableIE = ENABLE;
hpit32.init.reLoad = ENABLE;
hpit32.init.prescaler = PIT32_CLK_DIV_32;
hpit32.init.runatDebug = ENABLE;
hpit32.init.runatDoze = ENABLE;
hpit32.init.updateCNT = ENABLE;
设置好定时器后,就可以使用下面的调用来启动定时器:
HAL_PIT32_Init(&hpit32);
然后,定时器触发时,会自动调用:
void HAL_PIT32_Callback(void *hpit32)
我们的处理程序,就可以写到该回调中进行处理。
需要注意的是,这是一个全局回调,所以只能定义一次。
我在写pit32_led例子的时候,就需要先把原来的pit32_demo.c中的注释掉。
了解了以上定时器的基础使用方法,再结合eport_demo中控制LED的方法,我们就能用定时器实现一个闪亮LED的程序。
具体的代码展示如下:
- src/demo/inc/demo.h中,添加如下部分:
#ifdef PIT32_LED_EN
#include "pit32_led.h"
#endif
- src/main/main.c中,添加如下部分:
#ifdef PIT32_LED_EN
PIT32_LED_Run();
#endif
- src/demo/inc/pit32_led.h
#ifndef PIT32_LED_H_
#define PIT32_LED_H_
extern void PIT32_LED_Run(void);
#endif
- src/demo/pit32_led.c:
#include "pit32_demo.h"
#include "pit32_hal.h"
#include "eport_hal.h"
#include "cpm_hal.h"
#include "hal.h"
#include "delay.h"
#include "debug.h"
#define RETERR() do{printf("\t行号:%d ERR\r\n",__LINE__);\
return;}while(0)
EPORT_InitTypeDef eport;
EPORT_PinDef pin_num;
EPORT_TypeDef *eport_base;
int32_t led_status = 0;
uint32_t pit32_led_CalcCounter(uint32_t clk,uint32_t div, uint32_t time)
{
return (clk/(1<<div)/time);
}
void PIT32_LED_Run(void)
{
PIT32_HandleTypeDef hpit32;
hpit32.instance = PIT1;
hpit32.init.counter = pit32_led_CalcCounter(g_ips_clk,PIT32_CLK_DIV_32,PIT32_1S);
hpit32.init.enableIE = ENABLE;
hpit32.init.reLoad = ENABLE;
hpit32.init.prescaler = PIT32_CLK_DIV_32;
hpit32.init.runatDebug = ENABLE;
hpit32.init.runatDoze = ENABLE;
hpit32.init.updateCNT = ENABLE;
pin_num = EPORT_PIN4;
eport_base = EPORT;
eport.pin = pin_num;
eport.func = GPIO_FUN;
eport.dir = GPIO_DIR_OUT;
eport.output_mode = EPORT_OUTPUT_MODE_CMOS;
eport.pull_mode = EPORT_PULL_UP;
HAL_EPORT_Init(eport_base, &eport);
HAL_EPORT_TogglePin(eport_base, pin_num);
HAL_PIT32_Init(&hpit32);
while(1);
}
void HAL_PIT32_Callback(void *hpit32)
{
led_status = !led_status;
if(led_status) {
printf("Enter PIT interrupt, set LED On\r\n");
HAL_EPORT_WritePin(eport_base, pin_num, BIT_SET);
} else {
printf("Enter PIT interrupt, set LED Off\r\n");
HAL_EPORT_WritePin(eport_base, pin_num, BIT_RESET);
}
}
在以上的代码中,使用到了PIN4,实际驱动的LED,直接使用了板载的LED2,具体接线如下:
另外,上图中的两个跳线帽,短接对应的引脚后,开发板上的Type-C接口在连接到电脑后,就能直接用串口工具打开,查看调试信息了:
连接好线,在IDE中编辑下载后,实际跑起来之后,效果如视频所示。