单片机学习小组
直播中

潘飘稚

7年用户 889经验值
私信 关注

探讨一下TIMER定时器驱动

如何对tiMER定时器的寄存器进行配置呢?

如何对TIMER定时器的中断寄存器进行配置呢?

回帖(1)

张峰

2022-2-23 13:38:40
笔记:(四)TIMER定时器驱动

定时器中断,基础中断为5ms中断一次,在此基础上,可以对中断的次数Cnt进行计数,次数Cnt乘以5ms就可以得到多种定时器的时长。

寄存器相关配置



与本实验相关的寄存器有CTMC0,CTMC1,CTMAL,CTMAH,

1. CTMC0寄存器配置




2.CTMC1寄存器配置





3.CTMAL,CTMAH寄存器配置



1._ctmc0 = 0x30;意味着计数器时钟为64分频,主时钟是8MHz,64分频之后是125kHz;也就是说计数器计数一次所需要的时间为1/125k=0.0008ms;那么我们设置一个比较寄存器的值,如果我们打算每5ms中断一次,那么5ms/0.0008ms = 625;因此比较寄存器的数值应该设置为625,
2.看数据手册,我们可以知道的是,这是一个10位的定时器,用两个Byte存放该值,于是就分着高低位,低位的数值存放在ctmal寄存器中,高位的数值存放在ctmah寄存器中于是就有了这两行代码 _ctmal = 625 & 0xff ;_ctmah = 625 >> 8 ;
3.选择计数器定时器模式,选择比较器A匹配。


4.中断寄存器配置




//这里的配置
_ctmae = 1;//比较计数器A匹配中断使能
_mf0e  = 1;//多功能中断使能      
_emi   = 1;//使能总中断
_cton  = 1;//打开定时器


//由于请求标志位ctmaf寄存器,不能自动复位,因此要先判断一下,在手动清零,
DEFINE_ISR(TIMEROISR,TIMER0VECTOR)
{      
        if(_ctmaf)//比较器A匹配中断标志位置1
        {
                _ctmaf = 0;//中断标志位需要软件清0
                /* 要执行的事情写在这里 */      
        }      
}
//不能按照下面那样写
DEFINE_ISR(TIMEROISR,TIMER0VECTOR)
{      
        _ctmaf = 0;//中断标志位需要软件清0
        /* 要执行的事情写在这里 */               
}

#include "include.h"

/*******************************************************************************
* fn                timer0Init      
* brief        TIM0初始化
* param        无
* return        无
*******************************************************************************/
void timer0Init(void)
{
    /* 定时器配置 */
        _ctmc0 = 0x30;//TIM0时钟 = sys / 64; TIM0时钟 = 8MHz / 64 = 125kHz;
        _ctmc1 = 0xc1;//定时器模式、比较计数器A匹配清0计数器 计数器计数一次为0.0008ms
        _ctmal = 625 & 0xff;//0.0008ms * 625 = 5ms
        _ctmah = 625 >> 8;//tm0ah寄存器为8位,625 = 0000 0010 0111 0001; tm0ah填入值,右移取高八位,即 0000 0010
        /* 中断相关 */
        _ctmae = 1;//比较计数器A匹配中断使能
        _mf0e  = 1;//多功能中断使能      
        _emi   = 1;//使能总中断
        _cton  = 1;//打开定时器
}

/*******************************************************************************
* fn                timer0Open      
* brief        TIM0打开定时器
* param        无
* return        无
*******************************************************************************/
void timer0Open(void)
{
        _emi   = 1;//使能总中断
        _cton  = 1;//打开定时器
}
/*******************************************************************************
* fn                timer0Open      
* brief        TIM0关闭定时器
* param        无
* return        无
*******************************************************************************/
void timer0Close(void)
{
        _emi   = 0;//失能总中断
        _cton  = 0;//关闭定时器
}
/*******************************************************************************
* fn                TIMEROISR      
* brief      
* param        无
* return        无
*******************************************************************************/
DEFINE_ISR(TIMEROISR,TIMER0VECTOR)
{      
        static unsigned char sec = 0;
        if(_ctmaf)//比较器A匹配中断标志位置1
        {
                _ctmaf = 0;//中断标志位需要软件清0
                /* 这里我执行的就是5ms中断一次,然后20ms对SysCnt进行一次计数 */      
                /* 20ms定时器, */
                if(++sec >= 4)//5ms*4=20ms
                {
                        sec = 0;
                        /* 20ms定时器,对 */
                        SysCnt++;
                }
                /* 这里可以继续写几个你需要的时长的中断 */
        }      
}               
/*--------------------------------END THE FILE-----------------------------------*/


#ifndef _TIMER_H
#define _TIMER_H

#include "BH66F2652.h"

#define TIMER0VECTOR         0x10

extern void timer0Init(void);
extern void timer0Open(void);
extern void timer0Close(void);

#endif
举报

更多回帖

发帖
×
20
完善资料,
赚取积分