STM32F103RCT6 -- TIM8 高级定时器,定时 1s 翻转一次LED灯

STM32F103RCT6,配置 TIM8,系统时钟 72Mhz,实现 1 秒钟的定时,将LED灯反转一次,可以分为以下几个步骤:

1. 开启 TIM8 的时钟

2. 配置 TIM8 的基本参数,包括时钟预分频系数、计数器自动重装值、计数器模式,延时时间计算公式: 延时时间 1s = (自动重装载值 TIM_Period + 1)* (时钟预分频系数 TIM_Prescaler + 1),即:1 = (99999 +1)x (719 + 1)

3. 配置 TIM8 的中断,实现定时器溢出中断、比较中断等功能

4. 在中断处理函数中设置定时器的计数状态,以便下一次定时器触发。在这个例子中,我们以 LED 灯闪烁为例,每次定时器触发后,将 LED 灯翻转一次,以便检查定时器是否正常工作

5. 最后,需要启动 TIM8 定时器

void GPIO_Config(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //开启 GPIOC 时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;

  	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出模式
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  	GPIO_Init(GPIOC, &GPIO_InitStructure);
}

void TIM8_Config(void)
{
	// 1. 使能TIM8 的时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);

	// 2. 配置定时器TIM8 的参数
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

	TIM_TimeBaseStructure.TIM_Prescaler = 719; // 时钟预分频系数为720
	TIM_TimeBaseStructure.TIM_Period = 99999; // 计数器自动重装值为10000-1=9999,即计时周期为1秒
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 计数器向上计数

	TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
	
	// 3. 配置定时器TIM8 的中断
	NVIC_InitTypeDef NVIC_InitStructure;

	NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn; // 定时器8更新中断对应的中断向量
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断

	NVIC_Init(&NVIC_InitStructure);

	TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE); // 开启定时器8更新中断

	// 4. 使能定时器TIM8
	TIM_Cmd(TIM8, ENABLE); // 启动定时器8
}


void TIM8_UP_TIM13_IRQHandler(void) // 每次定时器数数,数完就会进这个中断服务函数里面,1s钟进一次,进来一次就翻转一次LED灯
{
  if (TIM_GetITStatus(TIM8, TIM_IT_Update) != RESET) // 获取更新中断标志位,看下数数,数完了没有?也就是判断有没有到 1s 钟了?
  {
    GPIO_WriteBit(GPIOC, GPIO_Pin_13, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_13))); // 到了1s 钟,就翻转 LED 灯

    TIM_ClearITPendingBit(TIM8, TIM_IT_Update); // 清除更新中断标志,然后重新数数
  }
}

int main(void)
{
	GPIO_Config();
	TIM8_Config();

	while (1) { // 死循环,被让程序停止下来,LED 灯会一直亮灭、亮灭下去

	}
	
}

6. TIM_Prescaler 和 TIM_Period 是用来配置 TIM 计数器的两个参数,它们之间的关系可以用下面的公式表示:

TIM_CLK = PCLK / (TIM_Prescaler + 1)
TIM_TimeBase_InitStructure.TIM_Period = (TIM_CLK / TIM_Freq) - 1

其中:
TIM_CLK 是 TIM 计数器的时钟频率,
PCLK 是 APB1 总线的时钟频率(STM32F1 系列中一般都是等于 CPU 主频),PCLK = 72MHz = 72 000 000 Hz
TIM_Prescaler 是时钟预分频系数,
TIM_Period 是计数器自动重装值,
TIM_Freq 是我们期望的计数器计数频率。

通过修改 TIM_Prescaler 和 TIM_Period 中的值,我们可以改变 TIM 计数器的计数频率和计数周期。
默认情况下,STM32F1 系列的 TIM 计数器以 APB1 或APB2 总线时钟为基准进行计数(具体要看使用的是哪个定时器,挂在APB1 总线还是APB2 总线上,可以看时钟树,可以在数据手册上看APB1,APB2总线上挂载了哪些外设就知道了)。

计数周期为 TIM_Period + 1 个计数单位,并且使用 TIM_Prescaler 对 APB1 总线时钟进行预分频。

例如,在 STM32F1 系列中,如果 APB1 总线时钟为 72 MHz,而我们期望 TIM 计数器的计数频率为 1 kHz,那么:

如果 TIM_Prescaler 设置为 719,即时钟预分频系数为 720,那么 TIM_CLK 就为 100 kHz。
如果 TIM_Period 设置为 9999,那么计数周期就为 10000 个计数单位,即 10 次 TIM 计数器计满一个周期,也就是 1 秒钟。
因此,我们可以通过这两个参数的调整,来实现不同频率和周期的定时、计数等功能。

延时时间 1s = (自动重装载值ARR + 1) * (预分频系数PSC + 1) / 系统时钟频率

延时时间 1s = (TIM_Period + 1) * (TIM_Prescaler + 1) / PCLK
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值