STM8S的定时器有多种配置方法,但今天只讨论定时中断的配置。
以定时器TIM4为例,我们希望能用一个函数初始化定时器并起动它。
TIM4的情况如下:
TIM4是一个8bit的计时器,时钟源是F_master。TIM4的分频系数DIVx有8种:1、2、4、8、16、32、64、128。在计数器溢出(即计数值TIM4_CNT等于计数上限TIM4_ARR)时,能够产生计数器溢出中断。
函数功能要求:
定时器初始化函数:
/**
* @brief 按照指定的参数初始化TIM4
* @param frequency - 中断频率
* @param priority - 中断优先级
* @retval None
*/
void TIM4_PeriodicPriority(uint32_t frequency, uint8_t priority)
{
uint8_t i;
const uint8_t div_tim4[8] = { 1, 2, 4, 8, 16, 32, 64, 128};
const uint8_t div_cfg[8] = { TIM4_PRESCALER_1, TIM4_PRESCALER_2,
TIM4_PRESCALER_4, TIM4_PRESCALER_8,
TIM4_PRESCALER_16, TIM4_PRESCALER_32,
TIM4_PRESCALER_64, TIM4_PRESCALER_128};
uint32_t arr_tim4 = 0;
uint8_t check = NG;
//中断优先级参数检查
if (priority != ITC_PRIORITYLEVEL_0
&& priority != ITC_PRIORITYLEVEL_1
&& priority != ITC_PRIORITYLEVEL_2
&& priority != ITC_PRIORITYLEVEL_3){
check = NG;
return;
}
//中断频率参数检查
if (frequency > CLK_GetClockFreq())
{
check = NG;
return;
}
//分频系数越大,计时分辨率越低,但频率范围变大
for (i = 0; i < sizeof(div_tim4); i++)
{
arr_tim4 = (CLK_GetClockFreq() / div_tim4[i]) / frequency; //t = 1/f, t/1 = ARR/(SYSCLK/TIM4DIV)
if (arr_tim4 <= 255)
{
check = OK;
break;
}
}
if (check != OK)
{
return;
}
TIM4_DeInit();
TIM4_TimeBaseInit((TIM4_Prescaler_TypeDef)div_cfg[i], arr_tim4);
TIM4_ClearFlag(TIM4_FLAG_UPDATE);
//TIM4_ARRPreloadConfig(ENABLE);
ITC_SetSoftwarePriority(ITC_IRQ_TIM4_OVF, (ITC_PriorityLevel_TypeDef)priority);
TIM4_ITConfig (TIM4_IT_UPDATE, ENABLE);
enableInterrupts();
TIM4_Cmd(ENABLE);
}
实际上,可以为上述函数增加1个返回值:只在 参数都正确 & 分频器配置成功 时才返回OK,其他情况一律返回NG。
至于中断服务函数,一般都在stm8s_it.c中,TIM4的中断服务函数也不例外,下面给出示例
/**
* @brief Timer4 Update/Overflow Interrupt routine.
* @param None
* @retval None
*/
INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
{
/* In order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction.
*/
if (TIM4_GetFlagStatus(TIM4_FLAG_UPDATE) == SET)
{
TIM4_ClearFlag(TIM4_FLAG_UPDATE);
tim_ms[0] ++; //当计时频率1000Hz能够配置成功时,每次累加刚好表示时间经过了1ms
}
}