DSP

DSP 2812: 使用C++封装定时器及应用举例

2019-07-13 19:07发布

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(); }