通用定时器中断实验
定时器中断时钟源解析
我们这个实验使用来自APB1总线的时钟(AHB时钟频率是72MHz),我们注意到AHB->APB1分频器->APB1中如果APB1预分频器的分频系数是1那么TIMXCLK的时钟频率为“TIMCLK=APB1=AHB”,如果APB1预分频器的分频系数为N(N不为1),那么TIMXCLK的时钟频率为“TIMCLK=2xAPB1=2xAHB/N”。
但是当我们调用ST公司提供的初始化时钟源库函数时,APB1分频器默认的分频系数是2,因此最终TIMXCLK=2xAPB1=2xAHB/2=AHB。
TIMXCLK时钟频率=CLK_INT时钟频率,然后通过触发控制器传递给CK_PSC进行第二次分频处理,最终CNT计数器接收到的时钟脉冲为“CLK_INT/(CK_PSC+1)”,(分频系数为何为CK_PSC+1我们稍后再论)
教你如何看逻辑信号图
向上计数模式(时钟分频因子=1)
首先,CK_INT为TIMER的初始时钟源,CNT_EN代表着TIMER使能,CK_CNT是计数器接受的脉冲频率(在CK_PSC寄存器中进行分频后的),计数寄存器的重装载值为36,“中断事件更新”与“计时器溢出”还有“更新中断标志置1”同步进行,但是我们看到如果我们不手动清除中断标志,那么系统会一直处于执行中断当中无论中断条件是否满足。
中央对齐计数模式(时钟分频因子=1,ARR=6)
中央对齐计数模式有些不同的是,分别在向上计数溢出与向下计数溢出时均触发中断,而且如果我们不在每次中断后清除中断标志位,那么无论是否满足中断条件中断行为都会一直存在。
相关寄存器简介
事件产生寄存器(TIMx_EGR)
更新事件中断是通用定时器执行的普通中断。
状态寄存器(TIMx_SR)
计数器(TIMx_CNT)
预分频器(TIMx_PSC)
自动重装载寄存器(TIMx_ARR)
该寄存器用于在计数器的计数值溢出后重新加载计数器的溢出值。
控制寄存器 1(TIMx_CR1)
该寄存器用于请求中断和配置计数器模式,一旦中断触发,所有寄存器都会更新。
用库函数配置带有中断的通用定时器
库函数介绍
TIM_ClearITPendingBit与TIM_ClearFlag函数的区别
TIM_ClearITPendingBit 清除的是一些中断标志位,TIM_ClearFlag清除的是定时器的状态标志,比如定时器捕获状态位定时器触发标志位。
定时器参数的选取
通用定时器参数主要有两个PSC预分频系数与ARR计数器重装载值。溢出时间指的是“从0x00到TOP的时间”。
设计要求
通过定时器中断配置,每500ms中断一次,然后中断服务函数中控制LED实现LED1状态取反(闪烁)。
TIMX程序设计流程
第一步:初始化TIMER3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 使能APB1的外设时钟
第二步:初始化定时器3(配置ARR的值与PSC的值)
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Down;
TIM_TimeBaseInitStructure.TIM_Period = 0x1C20; // 5000
TIM_TimeBaseInitStructure.TIM_Prescaler = 0x1388; // 7200
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); // 初始化TIMER3
第三步:初始化NVIC嵌入式中断向量
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure); // 初始化NVIC嵌入式外部中断
为什么我们先于NVIC初始化配置NVIC中断向量分组呢?
NVIC中断向量分组是用于约束全体中断向量的,如果我们单独把它放到某一个头文件里,就不能表示这个含义,而且如果我们在不同头文件里声明不同的中断向量分组,那么会乱套的。
第四步:配置TIMX的中断
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); // 配置TIMER3的具体中断行为
为什么NVIC的TIM中断通道已经开启,我们还配置TIMX的中断干啥?
我们一开始所使能的是TIMX中断通道,TIMX中断的模式很复杂,有多种中断模式,因此我们先使能TIMX的总中断通道,在进一步配置TIMX中断的属性,例如不同的中断条件:向上计数溢出,向下计数溢出……。
第五步:使能TIMX外设
TIM_Cmd(TIM3, ENABLE); // 使能TIMER3外设
第六步:编写相应的中断服务函数
void TIM3_IRQHandler() // 应该在相应的中断文件内编写中断服务函数
{
if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) // 由于定时器有多个中断模式,因此我们一定要检查相应的中断标志位
{
LED0 = !LED0;
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // 由于定时器有多个中断模式,因此我们一定要清除相应的中断标志位
}
代码示例
Main.c
#include "led.h"
#include "timer.h"
#include "stm32f10x.h"
#include "delay.h"
int main()
{
delay_init(); // 只有初始化系统systick时钟,我们才能调用delay系列函数
LED_InitConfig(); // LED初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // NVIC中断向量分组应该先于NVIC初始化
TIMER_InitConfig(0x1C20, 0x1388); // 初始化TIMER3,其中PR=7200,ARR=5000
while(1)
{
LED1 = !LED1;
delay_ms(250);
}
}
Led.c
#include "led.h"
#include "stm32f10x.h"
void LED_InitConfig()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); // 使能LED0,LED1的时钟
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); // 配置LED0的GPIO输出属性
GPIO_ResetBits(GPIOB, GPIO_Pin_5); // 初始化PB5为低电平
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure); // 配置LED1的GPIO输出属性
GPIO_ResetBits(GPIOE, GPIO_Pin_5); // 初始化PE5为低电平
}
Led.h
#ifndef _LED_H
#define _LED_H
#include "sys.h"
void LED_InitConfig();
#define LED0 PBout(5)
#define LED1 PEout(5)
#endif
Timer.h
#ifndef _TIMER_H
#define _TIMER_H
#include "sys.h"
void TIMER_InitConfig(u16 ARR, u16 PR);
#endif
Timer.c
运行结果
链接:https://blog.csdn.net/weixin_45590473/article/details/108048325
上一篇:浅谈中断挂起与中断标志的区别
下一篇:PWM输出实验详细示例
推荐阅读最新更新时间:2024-11-12 23:54
推荐帖子
- 那个大神知道酷派8079手机主板电路的核心芯片怎么找?
- 那个大神知道酷派8079手机主板电路的核心芯片怎么找?那个大神知道酷派8079手机主板电路的核心芯片怎么找?手机的核心芯片指四核处理器芯片还是内存芯片?处理器芯片
- heber312 移动便携
- DCDC 芯片
- 找一个输入DC12V左右输出5V1A芯片和5V输入3.3V输出500MA的芯片有推存的吗谢谢DCDC芯片LM2576,REG1117太多了。LM2576,LM2596,都可以实现楼主要求。5V1A输出的可以考虑MP2259,可以最高16V输入楼主TDK一大堆模块有没有要考虑 模块太贵了 有没有SOP8封装的芯片介绍 MP2259是SOT23-6MP2309是SOP-8封装,也可1A也可以0.5A输出
- 刘小天 LED专区
- AVR系列单片机C语言编程与应用实例
- 讲述AVR单片机C语言的书AVR系列单片机C语言编程与应用实例好东西,谢谢分享!xiexieenjoy,谢谢看看,看看,看看。先收下,在此谢过!
- ptwang Microchip MCU
- 【转】简析开关电源EMI的产生原因及五大抑制策略
- 开关电源是一种应用功率半导体器件并综合电力变换技术、电子电磁技术、自动控制技术等的电力电子产品。因其具有功耗小、效率高、体积小、重量轻、工作稳定、安全可靠以及稳压范围宽等优点,而被广泛应用于计算机、通信、电子仪器、工业自动控制、国防及家用电器等领域。但是开关电源瞬态响应较差、易产生电磁干扰(EMD,且EMI信号占有很宽的频率范围,并具有一定的幅度。这些EMI信号经过传导和辐射方式污染电磁环境,对通信设备和电子仪器造成干扰,因而在一定程度上限制了开关电源的使用。
- okhxyyo 电源技术
- 寒假有人去培训FPGA吗,求组团
- 本人打算去培训下,培训费用比较高,想找同道中人一起去,二人可打95折,三人可打9折,可以省一点银子寒假有人去培训FPGA吗,求组团打算去朋友可以留下QQ联系,一起去报名培训的时间有限效果不明显chenzhufly发表于2013-12-2914:58培训的时间有限效果不明显 主要是为了找工作,需要的较为核心东西自己一时半会儿搞不定chenzhufly发表于2013-12-2914:58培训的时间有限效果不明显 主要是为了找工作,需要
- blueworld FPGA/CPLD
- 芯片中参考电压如何在电源欠压时保持稳定
- 如图,如题芯片内部常见的掉电检测(BOD)或者欠压检测(UVLO)功能都有一个参考电源Vref进行参与但是该Vref都是正常上电时生成那么在输入欠压或者输入抖动时,该Vref还如何保持稳定(正常供电时,生成的带隙基准电压Vref的原理我明白)芯片中参考电压如何在电源欠压时保持稳定Vref一般比电源电压要低,所以可以由电源电压经线性稳压器得到。由于Vref的负载电流很小,所以把这个线性稳压器集成到芯片内很容易。有了这个线性稳压器,电源电压欠压时Vref不会
- shaorc 模拟电子