赞
踩
本章介绍使用STM32CubeMX对基本定时器进行配置的方法,STM32F103高性能系列设备包括基本定时器、高级控制定时器、通用定时器、看门狗定时器和 SysTick 定时器,但是STM32F103C6t6上资源比较有限(高级定时器TIM1,通用定时器TIM2和TIM3),没有真正的基本定时器,其实通用定时器和高级定时的功能是包含基本定时器的,因此如果没有使用到通用定时和高级定时的附加功能,也就是基本定时器了。本章介绍基本定时器,其他的定时器由后续章节一一介绍,最后通过示波器和打印结果来展现实现结果,如果有LED灯也可以,通过定时器来控制LED灯闪烁来观察现象。
定时器就像单片机的闹钟一样,定时器的核心就是计算器, 要实现计数功能,首先要给它一个时钟源,定时器根据时钟的输出信号,每隔“一秒"(一个单位时间),计数单元的数值就增加一,当计数单元数值增加到“设定的闹钟提醒时间"时,计数单元就会向中断系统发出中断申请,产生"响铃提醒",使程序跳转到中断服务函数中执行。
下面是三种定时的比较:
我们这里给出基本定时器的框图,基本定时器比较简单,也是通用定时器和高级定时器的基础,分析基本定时器,可以很好的分解通用定时器和高级定时器。
从上图我们可以看到基本定时器主要由下面四个部分组成:
**时钟源:**定时器时钟 TIMxCLK,即内部时钟 CK_INT所以定时器时钟,通过下图可以看到不同定时器所在的总线,从而确定他们的时钟源,STM32F103C6T6的高级定时器TIM1定时挂在APB2上,通用定时器TIM2。
**预分频器(TIMx_PSC):**定时器时钟经过 PSC 预分频器之后,即计数器时钟 CK_CNT,用来驱动计数器计数。 PSC 是一
个16 位的预分频器,可以对定时器时钟 TIMxCLK 进行 1~65536 之间的任何一个数进行分频。具体计算方式为: CK_CNT=TIMxCLK/(PSC+1)。
下图为预分频系数从1变到2的计数器时序图:图中CK_PSC是脉冲信号,预分频系数为2,所以最下面的预分频计数器计数0,1,中间的计数器寄存器记一次数。
**计数器(TIMx_CNT):**计数器 CNT 是一个 16 位的计数器,只能往上计数,最大计数值为 65535。当计数达到自动重装载寄存器的时候产生更新事件,并清零从头开始计数。
**自动重装载寄存器(TIMx_ARR):**自动重装载寄存器 ARR 是一个 16 位的寄存器,这里面装着计数器能计数的最大数
值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断。
下图为分频系数为1,自动重装载寄存器(TIMx_ARR)为36的计数器时序图。当计数器满36则进行重装,同时触发更新事件,更新中断标志等动作。
定时器有如下三种计数模式
**递增计数模式:**计数器从 0 计数到自动重载值,然后重新从 0 开始计数并生成计数器上溢事件。
**递减计数模式:**计数器从自动重载值开始递减到 0,然后重新从自动重载值开始计数并生成计数器下溢事件。
**中心对齐模式:**计数器从 0 开始计数到自动重载值 – 1 ,生成计数器上溢事件;然后从自动重载值开始向下计数到 1 并生成计数器下溢事件。之后从0 开始重新计数。
有了以上的基础知识,下面我们通过实验来验证一下
选择芯片stm32f103c6t6,新建工程
设置时钟源,最小系统外部晶振8Mhz,作为外部高速HSE时钟源。由于没有外接外部低速晶振,这里低速时钟源选择旁路时钟源。
配置时钟树,这里使用官方推荐的配置
配置引脚功能,先配置一个GPIO,过会使用定时器控制其输出高低电平,方便用示波器测试,我们使用通用定时器TIM2,已知TIM2挂在APB1上。
内部时钟设置为不分频(CKD),则CK_PSC的时钟频率等于APB1的时钟频率72MHz,即72000 000Hz。若要定时时间为1s,则即可设置7200分频(预分频器寄存器 (TIMx_PSC)的值为7200-1),定时器的时钟CK_CNT的频率为10000Hz.则自动重载寄存器 (TIMx_ARR)设置为10000-1即定时为1s.TRGO为触发输出,可以触发内部ADC/DAC,这里我们没有用到这个功能,参数为默认设置。
T = (psc+1)(arr+1)/Tclk=(7200)(1000)/72us=1000ms = 1s
在NVIC Settings框勾选开启定时器中断。优先级为默认。或者在NVIC配置中使能TIM2中断。
Code Generator中设置只拷贝使用到的库,分离.c和.h文件
设置好项目名称和路径,点击GENERATE CODE即可,生成后使用keil5 IDE打开。
在usart.c文件后面添加如下代码,代码中添加了#ifdef宏定义进行条件编译,如果使用GUNC编译,则PUTCHAR_PROTOTYPE 定义为int __io_putchar(int ch)函数,否则定义为int fputc(int ch, FILE *f)函数。
/* USER CODE BEGIN 0 */
#include "stdio.h"
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END 0 */
实现一个LED等间隔1s闪烁一次的功能,代码如下
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0); //PA0
printf("TIM2 \r\n");
HAL_Delay(1000);
}
/* USER CODE END 3 */
}
代码编译成功
在下载前检查keil是否检测到ST-LINK,选择魔法棒进行设置
如图所示,已经检测到ST-LINK 下载器
点击load,自动下载固件
烧录器ST-LINK V2和最小系统板的连接如图所示: 四线连接 SWDIO,GND,SWCLK,和3.3V电源
使用串口打印和示波器两种方式测试,打印可以看到周期输出,示波器可以精准的读到输出频率和时间间隔。
本章介绍了STM32F103系列设备中基本定时器的用法,其实前面交到的PWM也是定时器的典型应用,接下来在介绍其他的定时用法。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。