STM32
直播中

河神大人

8年用户 1478经验值
擅长:电源/新能源
私信 关注
[问答]

为什么使用STM32F103C8T6定时器的级联?

为什么使用STM32F103C8T6定时器的级联?

回帖(1)

连伴叙

2021-11-24 09:59:15

为什么使用STM32F103C8T6定时器的级联,主要是因为某些对于计时要求高的场合,而STM32F1单片机16位的定时器最多计数65535,那么很明显us级别的计时只能维持65.535ms,有时候解算过程可能不止65.535ms,因此需要级联一个32位定时器作为计数器或者计时器。
那么,在使用SMT32F1的定时器级联前,首先需要知道哪些可以级联以及定时器Master(主)Slave(从)关系,可以参见这篇博文:级联关系图


然后就是铺代码了:
(这段代码来自第七实验室开放的AHRS姿态融合中的一段,我对其中每一步都做了注释,因为姿态解算需要用到积分,所以计时器很重要,同时Kalman滤波计算量大,在STM32F1平台上用时比较长,必须使用定时器级联才能获取十分准确的时间)


定时器配置:
/**************************实现函数********************************************
*函数原型:                void Initial_Timer3(void)
*功  能:          初始化TIM2为高16位 TIM3为低16位
*输入参数:                无
*输出参数:                没有       
*******************************************************************************/
void Initial_Timer3(void)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE);         /*开启时钟*/
       
        TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
        TIM_TimeBaseStructure.TIM_Period = 0xffff;         /*自动重装值 即从0计数到0xffff*/
        TIM_TimeBaseStructure.TIM_Prescaler = 0x0;           /*不分频 真实分频为 TIM_Prescaler + 1 */            
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;/*不分频*/   
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /*向上计数*/
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
       
        TIM_PrescalerConfig(TIM2, 0, TIM_PSCReloadMode_Update);/*不分频*/
        TIM_UpdateDisableConfig(TIM2, ENABLE);/*暂停TIM2 等待TIM3的配置完再开启*/
       
       
        /* 查表来源 :https://blog.csdn.net/zwlforever/article/details/89021249 */
        /*============================================================================*/
        TIM_SelectInputTrigger(TIM2, TIM_TS_ITR2);/*选择TIM2的输入触发源为TIM3 查表可以找到*/
        /*============================================================================*/       
       
        TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_External1);/*TIM2从模式选择外部时钟*/
        TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);/*使能TIM2的级联功能*/
        TIM_ARRPreloadConfig(TIM2, ENABLE);        /*为TIM2装载配置并使能*/
       
        TIM_TimeBaseStructure.TIM_Period = 0xffff; /*自动重装值 即从0计数到0xffff*/   
        TIM_TimeBaseStructure.TIM_Prescaler = 71;         /*71+1分频,每次计数等价于1us*/
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;        /*不分频*/
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /*向上计数*/
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
        TIM_ARRPreloadConfig(TIM3, ENABLE);/*为TIM3装载配置并使能*/       
       
        TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);/*TIM3为从模式中的复位模式*/
        TIM_UpdateRequestConfig(TIM3, TIM_UpdateSource_Regular);/*计数器更新来源于计数溢出*/
        /*============================================================================*/
        TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update);/*选择TIM3触发输出的原因:计数器更新*/
        /*============================================================================*/
        TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);/*使能TIM3的级联功能*/
       
        TIM_Cmd(TIM3, ENABLE); /*启动TIM3*/
        TIM_Cmd(TIM2, ENABLE); /*启动TIM2*/            
}


获取us级的时间读取:
/**************************实现函数********************************************
*函数原型:                uint32_t micros(void)
*功  能:          读取系统运行的时间 ,返回单位为us 的时间数。       
*输入参数:                无
*输出参数:                处理器当前时间,从上电开始计时  单位 us
*******************************************************************************/
uint32_t micros(void)
{
        uint32_t temp=0 ;
        temp = TIM2->CNT; //读高16位时间
        temp = temp<<16;
        temp += TIM3->CNT; //读低16位时间
        return temp;
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分