目录
BF7006包含2个基本的16位定时器Timer0和Timer1,功能上比较简单,只提供基本的定时计数功能。
uint32_t const timerGroup[HW_TIMER_MAX] = {TIMER0, TIMER1};
1. 初始化
初始化前需要把定时器停止计时。
TIMER_CFG(timerGroup[port]) &= 0xfe; //Disable timer
1.1 时钟源选择
定时器的时钟源有2个,系统时钟和内部32KHz时钟。通过TIMER_CFG 寄存器的位2选择。
1.2 设置时钟分频系数
当选择RC32KHz时,没有时钟分频系数;选择系统时钟时,通过TIMER_CFG 寄存器的位3-4选择。
当选择RC32KHz时,定时器的频率范围为:0.488(即32000 / 65535)~ 32K
当选择系统时钟(例如32MHz)时,定时器的频率范围为:61(即32 / 8 / 65535)~ 32M
因此选择当定时器频率小于32KHz时,选择RC32KHz作为时钟源,其他频率则选择系统时钟。
if(clk == 32*1000)
TIMER_CFG(timerGroup[port]) = (1 << 2); //Select 32KHz as clock source
else
{
if(clk == SystemCoreClock)
TIMER_CFG(timerGroup[port]) = 0;
else if(clk == SystemCoreClock / 2)
TIMER_CFG(timerGroup[port]) = (0x1 << 3);
else if(clk == SystemCoreClock / 4)
TIMER_CFG(timerGroup[port]) = (0x2 << 3);
else if(clk == SystemCoreClock / 8)
TIMER_CFG(timerGroup[port]) = (0x3 << 3);
}
1.3 设置自动重载
通过TIMER_CFG 寄存器的位1设置。
默认设置自动重载。
TIMER_CFG(timerGroup[port]) |= (1 << 1); //Enable auto load.
1.4 设置频率
对应的寄存器是TIMER_MOD
TIMER_MOD(timerGroup[port]) = ((clk / freq) - 1);
1.5 使能中断
TIMER_CFG 寄存器的位5使能中断。
if(port == HW_TIMER0)
NVIC_EnableIRQ(TIMER0_IRQn);
else
NVIC_EnableIRQ(TIMER1_IRQn);
TIMER_CFG(timerGroup[port]) |= (1 << 5); //Enable interrupt.
2. 启动定时器
TIMER_CFG寄存器的位0控制定时器的开启。
void timerStart(uint16_t channel)
{
if(channel & 0x01)
TIMER_CFG(timerGroup[HW_TIMER0]) |= (1 << 0);
if(channel & 0x02)
TIMER_CFG(timerGroup[HW_TIMER1]) |= (1 << 0);
}
3. 中断函数
2个定时器对应的中断函数分别是TIMER0_IRQHandler和TIMER1_IRQHandler。
可以通过TIMER_CFG寄存器的位6设置为1清除中断标志。
以定时器0为例:
void TIMER0_IRQHandler(void)
{
TIMER_CFG(TIMER0) |= (1 << 6);
}
4. 实例
例如设置定时器0,时钟源选择RC32KHz,定时器频率为2Hz,即0.5秒中断一次。
timerInit(HW_TIMER0, 32000, 2);
timerStart(1 << 0);
中断程序中将GPIOB0取反,即LED灯交替闪烁。
void TIMER0_IRQHandler(void)
{
TIMER_CFG(TIMER0) |= (1 << 6);
if((GPIO_PTD(GPIOB) & 0x01) > 0)
{
GPIO_PTD(GPIOB) &= 0xfe;
}
else
{
GPIO_PTD(GPIOB) |= 0x01;
}
}
开发板上PB0接了一个LED