【APM32E030R Micro-EVB开发板评测】+ 使用定时器
定时器初始化void TMR_init(void)
{
TMR_TimeBase_TtimeBaseConfig;
/* Enable Clock */
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR14);
/* Set clockDivision = 1 */
timeBaseConfig.clockDivision =TMR_CKD_DIV1;
/* Up-counter */
timeBaseConfig.counterMode =TMR_COUNTER_MODE_UP;
/* Set divider = 71.So TMR1 clock freq ~= 72/(71 + 1) = 1MHZ */
timeBaseConfig.div = 71 ;
/* Set counter = 0xffff */
timeBaseConfig.period = 0xFF;
/* Repetition counter = 0x0 */
timeBaseConfig.repetitionCounter =0;
TMR_ConfigTimeBase(TMR14, &timeBaseConfig);
/* Enable update interrupt*/
TMR_EnableInterrupt(TMR14, TMR_INT_UPDATE);
NVIC_EnableIRQRequest(TMR14_IRQn, 2);
/*Enable TMR14*/
TMR_Enable(TMR14);
}
定时器中断函数
void TMR14_IRQHandler(void)
{
if (TMR_ReadIntFlag(TMR14, TMR_INT_FLAG_UPDATE) == SET)
{
/* The interrupt flag bit must be cleared first. */
TMR_ClearIntFlag(TMR14, TMR_INT_FLAG_UPDATE);
led_tick++;
lcd_tick++;
tick++;
}
}
在定时器中断函数里定义几个计数变量,用于给不同的功能提供时间参考。
通过计数函数来调整执行内容,实现流畅的LED闪烁和LCD更新
int main(void)
{
uint8_t i=0;
uint8_t led_index =0;
uint8_t lcd_index =0;
GPIO_Config_T gpioConfig;
RCM_EnableAHBPeriphClock(LED2_GPIO_CLK | LED3_GPIO_CLK);
/* LED2 GPIO configuration */
gpioConfig.pin = LED2_PIN;
gpioConfig.mode = GPIO_MODE_OUT;
gpioConfig.outtype = GPIO_OUT_TYPE_PP;
gpioConfig.speed = GPIO_SPEED_50MHz;
gpioConfig.pupd = GPIO_PUPD_NO;
GPIO_Config(LED2_GPIO_PORT, &gpioConfig);
/* LED3 GPIO configuration */
gpioConfig.pin = LED3_PIN;
GPIO_Config(LED3_GPIO_PORT, &gpioConfig);
/* Turn LED2 on */
GPIO_ClearBit(LED2_GPIO_PORT, LED2_PIN);
/* Turn LED3 off */
GPIO_SetBit(LED3_GPIO_PORT, LED3_PIN);
TMR_init();
I2CInit();
OLED_Init();
OLED_ColorTurn(0);//0正常显示,1 反色显示
OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
OLED_Interval_On();
Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();
OLED_Clear();
OLED_Dot_All_On();
Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();Delay();
OLED_Clear();
OLED_ShowPicture(0,0,128,64,BMP1,1);
OLED_Refresh();
OLED_Clear();
for(i=0;i<5;i++)
{
OLED_ShowChinese(24+(16*i),0,i,16,1);//科学小火箭
}
OLED_ShowString(24,16,"KE XUE JIA",16,1);
OLED_ShowString(24,32,"2025/08/08",16,1);
OLED_ShowString(0,48,"ASCII:",16,1);
OLED_ShowString(63,48,"CODE:",16,1);
OLED_Refresh();
lcd_index = 32;
for (;;)
{
if(led_tick>=1000)
{
led_tick = 0;
/* LED Toggle*/
if(led_index++ == 0) APM_TINY_LEDToggle(LED2);
if(led_index++ == 1) APM_TINY_LEDToggle(LED3);
if(led_index>1) led_index = 0;
}
if(lcd_tick>=2000)
{
lcd_tick = 0;
if(lcd_index<128)
{
OLED_ShowChar(48,48,lcd_index,16,1);//显示ASCII字符
OLED_ShowNum(103,48,lcd_index,3,16,1);
OLED_Refresh();
lcd_index++;
}
if(lcd_index>=128) lcd_index = 32;
}
}
}
程序运行后,根据计时器更新ASCII字符与对应编号,同时LED也正常闪烁,实现互不干扰的运行。
我一直觉得把Timer作做延时计时有点浪费。
感觉一个systick可以替代不少的timer Timer的应用还是蛮高级的嘛 阳光爆裂 发表于 2025-8-11 17:00
我一直觉得把Timer作做延时计时有点浪费。
感觉一个systick可以替代不少的timer ...
你说的对,但这里并不是简单的延时,而是类似基于定时器的状态机,通过定时器来触发执行条件,程序执行不阻塞。 我就是对事件触发一直都没有弄明白。
另外,项目上暂时也用不到——当然,也可能我的水平没有认识到。 Timer定时器的典型应用 这个定时器的配置和中断服务程序写得不错,LED闪烁和LCD更新的逻辑也很清晰。
Timer14的基本功能,溢出中断。
谢谢楼主的分享 这个定时器的配置和中断处理对于初学者来说是个不错的示例,代码结构也很清晰。
页:
[1]