/******************************************************************************************************************* *File Name : Timer0.c *Description : the file include the timer0 function define for ATMEGA128. *Date : 2008/06/02 *Author : yuanguiyou --History : ------------------------------------------------------------------------------------------------------------------ *change info: *******************************************************************************************************************/ #include "timer0.h" #include #include //extern void IsrTimer0(void); static Timer0Param_t gtpTimerParam = /*定时器默认参数,如果RAM空间非常紧张可以考虑将这些数据存储到FLASH或者EEPROM */ { /*并且可以将前面四个结构体成员去掉,改用直接从I/O寄存器读写。 */ WAVEMODE_GEN | (COMPMODE_NONE<<4) | CLKSEL_1024 |DIS_FORC, ENTIMER0_INT|DIS_ASSR, 0x00, 0x00, NULL }; /*读写TIMER0配置参数。当改变参数存储类型时必须修改这些函数。*/ #define GetTimerCntrl() (gtpTimerParam.ucTCntl) #define GetWaveMode() (gtpTimerParam.ucTCntl & WAVEMODE_MASK) #define GetCompMode() (gtpTimerParam.ucTCntl & (COMPMODE_MASK << 4)) #define GetClkSel() (gtpTimerParam.ucTCntl & CLKSEL_MASK) #define GetTimerIntCfg() (gtpTimerParam.ucOtherCntrl & TIMER0_INT_MASK) #define GetAssr() (gtpTimerParam.ucOtherCntrl & ~(TIMER0_INT_MASK)) #define GetTimerCount() (gtpTimerParam.tbTCN) #define GetTimerCompCount() (gtpTimerParam.tbOCR) #define GetTimerIsr() (gtpTimerParam.pfTimer0Isr) #define SetTimerCntrl(ucCntrl) (gtpTimerParam.ucTCntl = (ucCntrl)) #define SetWaveMode(ucWaveMode) (gtpTimerParam.ucTCntl |= ((ucWaveMode)& WAVEMODE_MASK)) #define SetCompMode(ucCompMode) (gtpTimerParam.ucTCntl |= (((ucCompMode)& COMPMODE_MASK) << 4)) #define SetClkSel(ucClockSel) (gtpTimerParam.ucTCntl |= ((ucClockSel)& CLKSEL_MASK)) #define SetTimerIntCfg(ucEnInt) (gtpTimerParam.ucOtherCntrl |= ((ucEnInt)& TIMER0_INT_MASK)) #define SetAssr(ucAssr) (gtpTimerParam.ucOtherCntrl |= ((ucAssr)& ASSR_MASK)) #define SetTimerCount(tbTCount) (gtpTimerParam.tbTCN = (tbTCount)) #define SetTimerCompCount(tbOCount) (gtpTimerParam.tbOCR = (tbOCount)) #define SetTimerIsr(pfTimer0IsrFun) (gtpTimerParam.pfTimer0Isr = (pfTimer0IsrFun)) /************************************************************************************************************************* *函数名 :Timer0Init *功能 :初始化定时器 *参数 :无 *返回 :无 *全局变量:使用静态全局变量gtpTimerParam中的配置来初始化定时器 *************************************************************************************************************************/ void Timer0Init(void) { TCCR0 = CLKSEL_NONE; /*关闭定时器 */ TIFR |= (_BV(TIMER0_OVF) | _BV(TIMER0_COMP)); /*清零TIMER0中断标志 */ TIMSK &= ~(_BV(TIMER0_OVF) | _BV(TIMER0_COMP)); /*清零TIMER0使能标志 */ TCNT0 = GetTimerCount(); /*设置TCNO初始化值 */ OCR0 = GetTimerCompCount(); /*设置OCR0初始值 */ ASSR = GetAssr(); /*异步寄存器初始化 */ TCCR0 = GetTimerCntrl(); /*控制寄存器初始化 */ if (GetCompMode() != (COMPMODE_NONE << 4)) /*如果使能OC0输出,初始化0C0口为输出*/ { PORTB |= _BV(PB4); DDRB |= _BV(PB4); } if (GetTimerIntCfg()) /*中断初始化 */ { if (GetWaveMode() == WAVEMODE_GEN) { TIMSK |= _BV(TIMER0_OVF); } else { TIMSK |= _BV(TIMER0_COMP); } sei(); } } /************************************************************************************************************************* *函数名 :StopTimer0 *功能 :停止定时器 *参数 :无 *返回 :无 *全局变量:无 *************************************************************************************************************************/ void StopTimer0() { TCCR0 = CLKSEL_NONE; } /************************************************************************************************************************* *函数名 :SIGNAL(SIG_OVERFLOW0) *功能 :定时器溢出中断处理函数 *参数 :无 *返回 :无 *全局变量:使用静态全局变量gtpTimerParam中的配置来进行操作 *************************************************************************************************************************/ SIGNAL(SIG_OVERFLOW0) { TCNT0 = GetTimerCount(); /*复位为原来的值 */ if (GetTimerIsr() != NULL) /*调用用户中断处理函数 */ { pfIsrFun pfIsrTmp = GetTimerIsr(); pfIsrTmp(); } } /************************************************************************************************************************* *函数名 :SIGNAL(SIG_OUTPUT_COMPARE0) *功能 :定时器比较输出中断处理函数 *参数 :无 *返回 :无 *全局变量:使用静态全局变量gtpTimerParam中的配置来进行操作 *************************************************************************************************************************/ SIGNAL(SIG_OUTPUT_COMPARE0) { TCNT0 = GetTimerCount(); OCR0 = GetTimerCompCount(); if (GetTimerIsr() != NULL) { pfIsrFun pfIsrTmp = GetTimerIsr(); pfIsrTmp(); } } /************************************************************************************************************************* *函数名 :Timer0Ioctl *功能 :处理各种传递给定时器的配置参数 *参数 :ucCmd--操作命令 pArg--传递的参数 *返回 :成功返回0,pArg错误返回0xFF,ucCmd错误返回0xFE *全局变量:使用静态全局变量gtpTimerParam中的配置来进行操作 *注意 :该代码可以使用改进的算法。使用定义一个函数数组FunArray,每个ucCmd对于一个数组元素。这样就可以直接使用 FunArray[ucCmd](pArg)来进行操作,大大提高性能。使用这种方法是必须把原来各个Setxxx,Getxxx定义为函数 *************************************************************************************************************************/ uint8_t Timer0Ioctl(uint8_t ucCmd,void *pArg) { uint8_t ucRet = 0; if (pArg == NULL) return 0xFF; switch (ucCmd) { case IOCTL_GET_TIME_CNTRL: (*(uint8_t*)pArg) = GetTimerCntrl(); break; case IOCTL_GET_WAVE_MODE: (*(uint8_t*)pArg) = GetWaveMode(); break; case IOCTL_GET_COMP_MODE: (*(uint8_t*)pArg) = GetCompMode(); break; case IOCTL_GET_CLK_SEL: (*(uint8_t*)pArg) = GetClkSel(); break; case IOCTL_GET_INT_CFG: (*(uint8_t*)pArg) = GetTimerIntCfg(); break; case IOCTL_GET_ASSR: (*(uint8_t*)pArg) = GetAssr(); break; case IOCTL_GET_TIME_COUNT: (*(uint8_t*)pArg) = GetTimerCount(); break; case IOCTL_GET_TIME_COMP_COUNT: (*(uint8_t*)pArg) = GetTimerCompCount(); break; case IOCTL_GET_TIMER_ISR: (*(pfIsrFun*)pArg) = GetTimerIsr(); break; case IOCTL_SET_TIME_CNTRL: if ((*(uint8_t*)pArg) != GetTimerCntrl()) { SetTimerCntrl((*(uint8_t*)pArg)); TCCR0 = (*(uint8_t*)pArg); } break; case IOCTL_SET_WAVE_MODE: if ((*(uint8_t*)pArg) != GetWaveMode()) { SetWaveMode((*(uint8_t*)pArg)); TCCR0 |= GetWaveMode(); } break; case IOCTL_SET_COMP_MODE: if ((*(uint8_t*)pArg) != GetCompMode()) { SetCompMode((*(uint8_t*)pArg)); TCCR0 |= GetCompMode(); } break; case IOCTL_SET_CLK_SEL: if ((*(uint8_t*)pArg) != GetClkSel()) { SetClkSel((*(uint8_t*)pArg)); TCCR0 |= GetClkSel(); } break; case IOCTL_SET_INT_CFG: if ((*(uint8_t*)pArg) != GetTimerIntCfg()) { SetTimerIntCfg((*(uint8_t*)pArg)); if (GetTimerIntCfg()) { if (GetWaveMode() == WAVEMODE_GEN) TIMSK |= _BV(TIMER0_OVF); else TIMSK |= _BV(TIMER0_COMP); } else { if (GetWaveMode() == WAVEMODE_GEN) TIMSK &= ~_BV(TIMER0_OVF); else TIMSK &= ~_BV(TIMER0_COMP); } } break; case IOCTL_SET_ASSR: if ((*(uint8_t*)pArg) != GetAssr()) { SetAssr((*(uint8_t*)pArg)); ASSR = GetAssr(); } break; case IOCTL_SET_TIME_COUNT: if ((*(TIMER_BITS_T*)pArg) != GetTimerCount()) { SetTimerCount((*(TIMER_BITS_T*)pArg)); TCNT0 = GetTimerCount(); } break; case IOCTL_SET_TIME_COMP_COUNT: if ((*(uint8_t*)pArg) != GetTimerCompCount()) { SetTimerCompCount((*(TIMER_BITS_T*)pArg)); OCR0 = GetTimerCompCount(); } break; case IOCTL_SET_TIMER_ISR: if (((pfIsrFun)pArg) != GetTimerIsr()) { SetTimerIsr((pfIsrFun)pArg); } break; default : ucRet = 0x01; break; } return ucRet; }