STM32定时器3配置时钟的坑

发布时间:2024-08-13  

STMf1的配置TIM3

我用的是原子的F1精英版,配置定时器3的时候出了点问题

问题描述

这里是主函数,在TIM3_Int_Init函数中,4999是重装载值,3599是预分频系数
计算:
如果APB1给TIM的时钟是36M的话,我使用3599预分频之后,那分频之后的频率就是 36M/3600=10K
(因为是从零开始计数,所以计算使用3600,但是代码里面要用3599)也就是说每计一个数用的时间就是1/10K = 0.0001s = 0.1ms.
我现在计数个数是5000个(0~4999),那时间就是 5000*0.1ms = 500 ms ,我让PE5每中断一次就取反一次,所以PE5的高电平时间应该是500,方波周期就是1s,频率为1Hz,
下图就是假设TIM3的时钟是36M的时候,产生的方波

这很明显就不对,所以虽然TIM是挂在时钟频率为36MHz的APB1总线上,但是最终到定时器的时钟并不是36M


int main(void)

 {

 

delay_init();     //延时函数初始化   

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级

uart_init(115200); //串口初始化为115200

  LED_Init();      //LED端口初始化

TIM3_Int_Init(4999,3599);//10Khz的计数频率,计数到5000为500ms  

    while(1)

{

LED0=0;

//delay_ms(200);    

}  

}  


定时器初始化及中断函数


//arr:自动重装值。

//psc:时钟预分频数

//这里使用的是定时器3!

void TIM3_Int_Init(u16 arr,u16 psc)

{

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

NVIC_InitTypeDef NVIC_InitStructure;


RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能

//定时器TIM3初始化

TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值

TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位

 

TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断


//中断优先级NVIC设置

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM3中断

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能

NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器



TIM_Cmd(TIM2, ENABLE);  //使能TIMx  

}

//定时器3中断服务程序

void TIM2_IRQHandler(void)   //TIM3中断

{

if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否

{

TIM_ClearITPendingBit(TIM2, TIM_IT_Update  );  //清除TIMx更新中断标志 

LED1=!LED1;

}

}

如果假设是72M,那么计算的话可以按照上面的来,最终的结果就是2Hz。那上面的那个波形图就是对的。

总的来说就是,定时器3的时钟不等于APB1的时钟


问题解决

我去看了一下那个时钟树,大概就明白了是怎么个回事,放图

在系统时钟72M进入APB1之后进行了2分频,得到了36M,所以挂在APB1总线上的外设时钟频率是36M,因为分频系数不等于1,所以APB1的36需要进行乘2才进入定时器的时钟。
这是挂在APB1上面的所有外设


#define RCC_APB1Periph_TIM2              ((uint32_t)0x00000001)

#define RCC_APB1Periph_TIM3              ((uint32_t)0x00000002)

#define RCC_APB1Periph_TIM4              ((uint32_t)0x00000004)

#define RCC_APB1Periph_TIM5              ((uint32_t)0x00000008)

#define RCC_APB1Periph_TIM6              ((uint32_t)0x00000010)

#define RCC_APB1Periph_TIM7              ((uint32_t)0x00000020)

#define RCC_APB1Periph_TIM12             ((uint32_t)0x00000040)

#define RCC_APB1Periph_TIM13             ((uint32_t)0x00000080)

#define RCC_APB1Periph_TIM14             ((uint32_t)0x00000100)

#define RCC_APB1Periph_WWDG              ((uint32_t)0x00000800)

#define RCC_APB1Periph_SPI2              ((uint32_t)0x00004000)

#define RCC_APB1Periph_SPI3              ((uint32_t)0x00008000)

#define RCC_APB1Periph_USART2            ((uint32_t)0x00020000)

#define RCC_APB1Periph_USART3            ((uint32_t)0x00040000)

#define RCC_APB1Periph_UART4             ((uint32_t)0x00080000)

#define RCC_APB1Periph_UART5             ((uint32_t)0x00100000)

#define RCC_APB1Periph_I2C1              ((uint32_t)0x00200000)

#define RCC_APB1Periph_I2C2              ((uint32_t)0x00400000)

#define RCC_APB1Periph_USB               ((uint32_t)0x00800000)

#define RCC_APB1Periph_CAN1              ((uint32_t)0x02000000)

#define RCC_APB1Periph_CAN2              ((uint32_t)0x04000000)

#define RCC_APB1Periph_BKP               ((uint32_t)0x08000000)

#define RCC_APB1Periph_PWR               ((uint32_t)0x10000000)

#define RCC_APB1Periph_DAC               ((uint32_t)0x20000000)

#define RCC_APB1Periph_CEC               ((uint32_t)0x40000000)


总结

虽然不知道系统在那里设置了乘2的操作,但是现在我就是只知道这样子去用,以后配置的时候都按照72M的时钟去配置定时器。

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    恒压变频器怎么调试参数?怎么定时控制选择?;恒压变频器怎么调试参数 调试恒压变频器的参数是确保其正常工作和满足运行要求的重要步骤。下面是一般的恒压变频器参数调试过程: 1. 了解系统要求:首先......
    恒压变频器怎么调试参数 恒压变频器怎么定时控制选择;恒压变频器怎么调试参数 调试恒压变频器的参数是确保其正常工作和满足运行要求的重要步骤。下面是一般的恒压变频器参数调试过程: 1. 了解......
    伺服控制器怎么调_伺服控制器和伺服驱动器的区别;  伺服控制器怎么调   伺服控制器的调试需要根据具体应用场景和控制器型号进行具体设置和调整。一般来说,伺服控制器的调试包括以下几个方面:   电气......
    步进电机驱动器怎么调_步进驱动器正反转怎么控制的;  步进电机驱动器怎么调   步进电机驱动器的调整包括两个方面:电气参数的设置和运动参数的调整。电气参数的设置包括电流、细分数、步进角等,而运......
    软启动器怎么调试_软启动器设置哪些参数;  软启动器怎么调试   软启动器(soft starter)是用于电动机起动控制的设备,可以通过逐步增加电机电压来减小电机的启动电流冲击,延长电机寿命,减少......
    最基本的框架。使用起来是很方便的。 delay 延时的编程思想: CM3 内核的处理器,内部包含了一个 SysTick 定时器, SysTick 是一个 24 位的倒计数定时器,当计数到 0 时,将从RELOAD......
    的需求而设计的数字示波器。利用示波器,就能够观察测量不同信号随着时间或者信号的变化。安泰测试为大家介绍一下怎么调节使用普源示波器。 普源示波器怎么调节使用? 1、示波器通电预热; 2、、调节......
    均衡器怎么调能达到最佳效果;  均衡器(Equalizer),是一种可以分别调节各种频率成分电信号放大量的电子设备,通过对各种不同频率的电信号的调节来补偿扬声器和声场的缺陷,补偿......
    变频器调速度的原理 变频器怎么调速度?;变频器调速的原理是利用变频技术将电源的频率进行调整,从而控制驱动电动机的转速。变频器可以根据所需的转速调整输出电压和频率,从而实现精确的转速控制。变频......
    郁闷的时候再上来写写这个。上面的程序就是中断服务程序里面的计时器,分别定时 2ms 5ms 500ms,计时完毕溢出是flag_time 标志来记录的,程序通过读这个标志就可以知道定时的时间是否已经到了。 下面......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>