定时器是MCU里面一个非常重要的设备,它让你可以设计出在指定时间运行特定代码.
或者在固定时间间隔重复运行某个函数,从而达到自己想要的目的
所在学习单片机是,定时器一点要搞懂,这会使你再开发中省掉很多麻烦!
我在上一篇的基础上把文件结构整理了一下
main.c
#include "main.h"
// 主函数
int main(void)
{
sysTimerInit(); // 定时器初始化
LED_Config(); // LED初始化
while(1) // 无限循环
{
if(_500MsFlag==1) // 500ms运行一次if里面的代码
{
_500MsFlag = 0;
led_func();
}
}
}
LED.c
#include "main.h"
// LED灯的引脚IO口定义
#define LED_GPIO GPIO0
#define LED_PIN 6
// LED初始化配置函数
void LED_Config(void)
{
LED_GPIO->PMS &= ~(0x0F << (LED_PIN*4));
LED_GPIO->PMS |= (0x01 << (LED_PIN*4));
LED_GPIO->DR &= ~(0x01 << LED_PIN);
LED_GPIO->SR &= ~(0x01 << LED_PIN);
}
void LED_ON(void)
{
LED_GPIO->DOSET = 1<<LED_PIN; //LED 亮
}
void LED_OFF(void)
{
LED_GPIO->DOCLR = 1<<LED_PIN; //LED 灭
}
int led_cnt=0; //LED翻转延迟计数器
void led_func(void) // LED翻转控制函数
{
led_cnt++;
led_cnt &=0x01;
if(led_cnt==0)
LED_OFF();
if(led_cnt==1)
LED_ON();
}
sys_timer.c
#include "CMS32F030x.h" // Device header
static void sysTimer0Init(void)
{
SYSCON->APBCKEN |= (1<<1); //使能定时器时钟输入,系统时钟默认为48MHz
TIMER0->CON = 1<<6; //计数器模式为连续模式
TIMER0->CON |= 1<<5; //计数器中断使能
TIMER0->CON |= 1<<2; //分频数为1/16
TIMER0->CON |= 1<<1; //计数器宽度32bit,
TIMER0->LOAD = 500*1000*3; //设置定时器触发门限,500ms
NVIC_EnableIRQ(TIMER0_IRQn);
NVIC_SetPriority(TIMER0_IRQn, 1);
TIMER0->CON |= (1<<7);
}
void sysTimerInit(void)
{
sysTimer0Init();
}
volatile uint32_t _500MsFlag; //定时器触发标志寄存器
//定时器中断处理函数,如果使能定时器中断功能,在定时器计数达到指定值的时候,有中断系统自动调用运行
void TIMER0_IRQHandler(void)
{
if (TIMER0->RIS & 0x01)
{
_500MsFlag = 1;
TIMER0->ICLR = 1;
}
}
我们可以看到main.c变得非常简洁
LED.c也进行的整理,更容易阅读和理解
工程运行的效果是LED灯500毫秒翻转一次
这里使用了一个定时器0中断函数 void TIMER0_IRQHandler(void);