/**
* [url=home.php?mod=space&uid=247401]@brief[/url] Open Timer in specified mode and frequency
*
* @param[in] timer The base address of Timer module. It could be TIMER0, TIMER1, TIMER2, TIMER3.
* @param[in] u32Mode Operation mode. Possible options are
* - \ref TIMER_ONESHOT_MODE
* - \ref TIMER_PERIODIC_MODE
* - \ref TIMER_TOGGLE_MODE
* - \ref TIMER_CONTINUOUS_MODE
* @param[in] u32Freq Target working frequency
*
* [url=home.php?mod=space&uid=266161]@return[/url] Real Timer working frequency
*
* [url=home.php?mod=space&uid=1543424]@Details[/url] This API is used to configure timer to operate in specified mode and frequency.
* If timer cannot work in target frequency, a closest frequency will be chose and returned.
* [url=home.php?mod=space&uid=536309]@NOTE[/url] After calling this API, Timer is \b NOT running yet. But could start timer running be calling
* \ref TIMER_Start macro or program registers directly.
*/
uint32_t TIMER_Open(TIMER_T *timer, uint32_t u32Mode, uint32_t u32Freq)
{
uint32_t u32Clk = TIMER_GetModuleClock(timer);
uint32_t u32Cmpr = 0, u32Prescale = 0;
// Fastest possible timer working freq is (u32Clk / 2). While cmpr = 2, pre-scale = 0.
if(u32Freq > (u32Clk / 2))
{
u32Cmpr = 2;
}
else
{
if(u32Clk >= 0x4000000)
{
u32Prescale = 7; // real prescaler value is 8
u32Clk >>= 3;
}
else if(u32Clk >= 0x2000000)
{
u32Prescale = 3; // real prescaler value is 4
u32Clk >>= 2;
}
else if(u32Clk >= 0x1000000)
{
u32Prescale = 1; // real prescaler value is 2
u32Clk >>= 1;
}
u32Cmpr = u32Clk / u32Freq;
}
timer->TCSR = u32Mode | u32Prescale;
timer->TCMPR = u32Cmpr;
return(u32Clk / (u32Cmpr * (u32Prescale + 1)));
}
补充说明,用的新唐的M051开发板,12MHZ晶振 |