2812中有三个定时器,结构都是一样的。
一般的操作就是设置周期,使能中断,启动计时器。
我们先定义定时器的基类,然后对每个定时器再分别定义各自的子类。
一般地,我们都将特定芯片的类申明在一个命名空间内。
namespace NF281x{
class CTimer{
CTimer( const CTimer& );
public:
CTimer( volatile unsigned long& tim,volatile unsigned long& prd,volatile unsigned int& tcr,volatile unsigned int& tpr,volatile unsigned int& tprh );
protected:
volatile unsigned long& m_tim;
volatile unsigned long& m_prd;
volatile unsigned int& m_tcr;
volatile unsigned int& m_tpr;
volatile unsigned int& m_tprh;
};
为定时器添加方法:
inline const volatile unsigned long& getCounter()const{
return m_tim;
}
inline void setCounter( const unsigned long& count ){
m_tim = count;
}
inline const volatile unsigned long& getPeriod()const{
return m_prd;
}
inline void setPeriod( const unsigned long& prd ){
m_prd = prd;
}
/**
* 定时器计时到0是否发生
* @return
*/
inline bool isTimerZeroFlag()const{
return NDm::isBitSet(m_tcr);
}
inline void clrTimerZeroFlag(){
NDm::bitSet(m_tcr);
}
/**
* 定时器中断是否使能
* @return
*/
inline bool isInterruptEn()const{
return NDm::isBitSet(m_tcr);
}
inline void enInterrupt(){
NDm::bitSet(m_tcr);
}
inline void disInterrupt(){
NDm::bitClr(m_tcr);
}
/**
* 定时器重新开始运行
*/
inline void restart(){
NDm::bitClr(m_tcr);
}
/**
* 听事情停止
*/
inline void stop(){
NDm::bitSet(m_tcr);
}
/**
* 定时器是否已经运行
* @return
*/
inline bool isStarting()const{
return 0==NDm::getBit(m_tcr);
}
/**
* 重新加载
*/
inline void reload(){
NDm::bitSet(m_tcr);
}
/**
* 获取时钟周期
* 没SysCycle个系统时钟周期,定时器计数减1
* @return
*/
inline unsigned int getSysCycle()const{
return (m_tprh<<8)|(m_tpr&0x00FF);
}
/**
* 设置时钟周期
* @param cycle
*/
inline void setSysCycle( const unsigned int& cycle ){
m_tpr = (cycle&0x00FF);
m_tprh = (cycle>>8);
}
下面添加一个对timer0子类的实现:
namespace NF281x{
/**
* CPU定时器0
* 使用中断INT1.7
*/
class CTimer0:public CTimer{
public:
CTimer0();
};
}
下面举个例子来看看,定时器在代码中如何使用的。其中也使用了PIE模块的使用。
这个例子是使用定时器,产生定时中断,来测试LED。
首先定义中断函数:
extern "C" interrupt void myTimer(){
CLed::ins().testOnce();
CPieCtl::ins().ack_tInt0();
}
其中CLed对LED的操作进行了封装。一般是使用GPIO控制的。
CPIeCtl::ins()是CPie类的一个对象。
在中断处理函数中一定要对Timer0中断进行ack。
下面对定时器进行初始化操作
void timerTaskInit(){
CTimer0 timer0;
timer0.stop();
CPieCtl& pie = CPieCtl::ins();
pie.setIrs_tInt0( myTimer );
timer0.setSysCycle(48000);
timer0.setPeriod(100);
timer0.enInterrupt();
timer0.reload();
timer0.clrTimerZeroFlag();
timer0.restart();
}