完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
定时器的最基本的功能是用来周期性的定时,当然,它还用来实现如下功能:
1) 输入捕获。脉冲计数,在上升沿或下降沿检测,已经PWM的输入检测; 2) 输出比较。脉冲输出和步进电机的控制; 3) PWM生成。电压输出控制、直流减速电机控制等; 4) 编码器接口、霍尔传感器接口等。 当然,根据所用芯片不同,定时器还能提供更多的功能,比如与DMA的配合等。本篇准备用定时器产生的时间中断,周期性地控制LED灯的亮灭,以期对定时器的编程有基本的理解。 1 STM32的定时器 YIE002-STM32所用的芯片为STM32F103C8T6,属于STM32F1系列,在此系列,STM32提供了大量的定时器:2个基本定时器(TIM6、TIM7)、4个通用定时器(TIM2、TIM3、TIM4、TIM5)、2个高级控制定时器(TIM1和TIM8),以及4个特定功能定时器(SysTick、IWDG、WWDG、RTC),共有12个。另外,超大容量系列的产品中,又增加了5个通用寄存器TIM9~TIM14。 从功能上来说,高级控制通用器的功能是通用定时器的超集、通用定时器的功能是基本定时器的超集。比较通用定时器和高级控制定时器,可知它们的功能非常接近,高级控制定时器只是针对电动机的控制增加了一些功能。 因此,本篇准备使用通用定时器TIM3,构建演示程序。 1.1 定时器的时钟 TIM1和TIM8是高级控制定时器,时钟由APB2输出产生;TIM2至于TIM5是通用定时器,TIM6和TIM7是基本定时器,时钟由APB1输出产生。 从前几篇中可以知道,F103C8T6的系统时钟为72MHZ。如图1所示的时钟树,给出了定时器的时钟频率。 图1 定时器的时钟树 图1是以STM32F103C8T6为例绘制的。APB1为36MHZ,APB2为72MHZ。在我们的配置中,APB1 Prescaler是2分频;APB2 Prescaler是1分频。从图中可以看出,不论是通过挂在APB1下、还是挂在APB2下的时钟,其时钟都是72MHZ。 也即TIMxCLK均为72MHZ,与系统时钟等同。 1.2 定时器的中断时间(TIM3) STM32F1的通用定时器(本例中使用的TIM3)是通过可编程预分频器(PSC)驱动的16位自动装载计数器(CNT)构成,其基本的配置过程包括: 1) TIM3时钟使能; 2) 初始化定时器参数,设置自动重装值、分配系数、计数方式等; 3) 允许TIM3更新中断; 4) 设置TIM3的中断优先级; 5) 使能TIM3; 6) 编写中断服务函数。 使用CubeMX编程,上述6个步骤的前5个都是通过图形配置、自动生成代码的,只有中断服务函数需要编写。 编写代码之前,我们需要考虑定时器以多长的时间定时中断。计算中断时间,与TIMx_PSC寄存器(预分频寄存器)和TIMx_ARR寄存器(自动重装载寄存器)有关。具体的细节可以查看《STM32参考手册》,我们主要关注CubeLibrary中如何操作。在stm32f1xx_hal_tim.h中定义了定时器初始化的数据结构: /** @defgroup TIM_Exported_Types TIM Exported Types * @{ */ /** * @brief TIM Time base Configuration Structure definition */ typedef struct { uint32_t Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ uint32_t CounterMode; /*!< Specifies the counter mode. This parameter can be a value of @ref TIM_Counter_Mode */ uint32_t Period; /*!< Specifies the period value to be loaded into the active Auto-Reload Register at the next update event. This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */ uint32_t ClockDivision; /*!< Specifies the clock division. This parameter can be a value of @ref TIM_ClockDivision */ uint32_t RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter reaches zero, an update event is generated and counting restarts from the RCR value (N). This means in PWM mode that (N+1) corresponds to: - the number of PWM periods in edge-aligned mode - the number of half PWM period in center-aligned mode GP timers: this parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF. Advanced timers: this parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */ uint32_t AutoReloadPreload; /*!< Specifies the auto-reload preload. This parameter can be a value of @ref TIM_AutoReloadPreload */ } TIM_Base_InitTypeDef; 数据结构TIM_Base_InitTypeDef的成员变量Prescaler对应预分频寄存器、成员变量Period对应自动重装载寄存器。注意,这两个值可设置的值为[0,65535],注意不要越界。 假设TimClk为定时器时钟频率(单位:MHZ),TimOut为中断时间(也即溢出时间,单位:秒),则计算公式为: TimOut = ((Prescaler + 1) * (Period + 1)) /TimClk; TIM3的时钟频率TimClk为72MHZ,如果需要1秒的中断时间,则可以设置 Prescaler=7200-1; Period=10000-1; 计算可得TimOut = 1 秒。 常用的几个溢出时间: Period =9999 Prescaler =7199 1000ms Period =4999 Prescaler =7199 500ms Period =2499 Prescaler =7199 250ms Period =1999 Prescaler =7199 200ms Period =999 Prescaler =7199 100ms 有了这些基本概念,就可以进入编程步骤了。 2 YIE002-STM32的定时器编程 如之前一样,分为图形配置然后自动生成代码,以及手动编写代码。 2.1 Cube MX的图形配置 本篇的例子,是在03ExtIO上修改的。原来的配置没有修改,主要添加定时器TIM3的配置。如图2所示。 图2 配置TIM3 在Pinout & Configuration菜单下,选择Timers中的TIM3,将其“Internal Clock”的选项勾选上。同时设置Prescaler值为7200-1,Counter Period值设置为10000-1。 然后设置TIM3中断的优先级,可在System Core的NVIC中设置,如图3所示。 图3 设置TIM3中断优先级 之前设置的外部中断的优先级,可以不必修改,保留即可。 完成设置后,生成代码。 2.2 编写TIM3中断服务函数 定时的中断服务处理函数,在startup_stm32f103xb.s中可以看到。 EXPORT TIM1_BRK_IRQHandler EXPORT TIM1_UP_IRQHandler EXPORT TIM1_TRG_COM_IRQHandler EXPORT TIM1_CC_IRQHandler EXPORT TIM2_IRQHandler EXPORT TIM3_IRQHandler EXPORT TIM4_IRQHandler 我们需要处理的中断函数是TIM3_IRQHandler。跟踪此函数,可以知道,Cube Library提供了回调函数HAL_TIM_PeriodElapsedCallback()供用户处理定时器中断。 因此需要处理的工作包括两项: 一是在初始化函数MX_TIM3_Init()中,添加对TIM3的中断使能函数,代码如下: /* USER CODE BEGIN TIM3_Init 2 */ //robin add 20210725 if(HAL_TIM_Base_Start_IT(&htim3)!=HAL_OK) { Error_Handler(); } /* USER CODE END TIM3_Init 2 */ 二是添加对回调函数HAL_TIM_PeriodElapsedCallback()的实现,代码如下(添加在USER CODE BEGIN 4中): void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim ==(&htim3)) HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_12); } 编译下载,就可以看到实际效果了。所实现的代码,将以1秒为周期,驱动灯LED1亮灭。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1777 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1080 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1678 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
731浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
595浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
554浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 08:36 , Processed in 0.924297 second(s), Total 77, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号