目录
四、定时器与中断
目标:
使用定时器中断,让LED灯间隔一秒闪烁
注释掉前面工程写的串口收发,外部中断等。
引脚:
无
知识点:
1、
TIM2时挂载到总线下的APB1(这里的频率是36MHZ)上的,经过一系列的过程,TIM2的频率是72MHZ = 72 000 000HZ
定时时间:计数:72000000次为一秒
有一个预分频器和一个重装值;预分频将频率降低,重装值为计数最大值(向上计数的时候);
如果预分频器分频为:(7200-1)表示分频7200,最后频率为72MHZ 除以7200 = 10000HZ,也就是计数10000次为1秒
此时如果重装值为(10000-1 = 9999)则表示计时一秒,(9999表示从0~9999共计10000次)
简而言之,(预分频数+1)乘以(重装值+1)除以72 就是计时时长,单位为us
2、
static 关键字
①、使变量像全局变量一样一直存在程序运行的全过程,但是只能在声明该变量的时候的作用域有效
②另外初始化的时候如果没有显示赋值,则初始化为0,没有static关键字的时候,值是不确定的。
步骤:
1、创建文件
在工程目录下边创建tim.c和tim.h两个文件
2、编写代码
tim.c:
#include "tim.h"
#include "stm32f10x.h"
void tim_config(void)
{
TIM_TimeBaseInitTypeDef tim_struct;//声明配置定时器的结构体
NVIC_InitTypeDef nvic_tim_struct; //声明配置NVIC的结构体
//配置TIM2的NVIC的优先级组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//使能定时器的时钟
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2,ENABLE);
//配置定时器结构体
//72MHZ=72000000次/S = (TIM_Period+1)*(TIM_Prescaler+1)
//表示计数72000次,耗时1ms,现在需要计时1S = 1000ms,需要72 000 000次
tim_struct.TIM_Period = 9999; //重装值
tim_struct.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
tim_struct.TIM_Prescaler = 7200 - 1; //预分频数
tim_struct.TIM_ClockDivision = TIM_CKD_DIV1; //不分频,72MHZ
//初始化定时器
TIM_TimeBaseInit(TIM2,&tim_struct);
//将定时器与中断绑定
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
//配置NVIC的结构体
nvic_tim_struct.NVIC_IRQChannel = TIM2_IRQn;
nvic_tim_struct.NVIC_IRQChannelCmd = ENABLE;
nvic_tim_struct.NVIC_IRQChannelPreemptionPriority = 1;
nvic_tim_struct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&nvic_tim_struct); //初始化NVIC
//使能定时器(允许开始计数)
TIM_Cmd(TIM2,ENABLE);
}
tim.h:
void tim_config(void);
main.c:
#include "stm32f10x.h" //引入库函数
#include "main.h"
#include "led.h" //引入LED相关的文件
#include "exti.h" //加入刚写的外部中断相关文件
#include "usart.h" //加入串口相关文件
#include "tim.h" //加入定时器相关文件
void delay(uint16_t time)
{
uint16_t i = 0;
while(time--)
{
i = 8000;
while(i--);
}
}
int main()
{
LED_Init(); //初始化LED(PC13引脚)
tim_config();
GPIO_SetBits(GPIOC,GPIO_Pin_13); //让LED上电的时候熄灭
//空循环,等待中断
while(1)
{
}
}
//定时器2中断服务函数
void TIM2_IRQHandler(void)
{
static char temp;
if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET) //表示发生了中断
{
if(temp == 0){
temp = 1;
GPIO_SetBits(GPIOC,GPIO_Pin_13); //关灯
}else{
temp = 0;
GPIO_ResetBits(GPIOC,GPIO_Pin_13); //开灯
}
//清除中断标志位
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
3、烧录程序(烧录方式更新):
不使用USC转TTL了,使用J-Link烧录器,直接在KEIl软件中下载