03、【江科大自化协stm32F103c8t6】笔记之【入门32单片机及TIM定时中断初始化参数配置】

六、TIM定时中断

TIM基本结构---------------------------------编写原理 如图中所述
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 72M对7200进行分频,得到的就是10K的计数频率 ,在10k的频率下计10000个数就是1s

1、RCC开启时钟

这个基本上每个代码都是第一步,不用多想,在这里打开时钟后,定时器的基准时钟和整个外设的工作时钟就都会同时打开了

2、选择时基单元的时钟源

对于定时中断,我们就选择内部时钟源

3、配置时基单元

包括这里的预分频器、自动重装器、计数模式等等,这些参数用一个结构体就可以配置好了

4、配置输出中断控制,允许更新中断输出到NVIC

5、配置NVIC

在NVIC中打开定时器中断的通道,并分配一个优先级

6、运行控制

——————————————————————————————————————整个模块配置完成后,我们还需要使能一下计数器,要不然计数器是不会运行的,当定时器使能后,计数器就会开始计数了,当计数器更新时,触发中断,最后我们再写一个定时器的中断函数,这样这个中断函数每隔一段时间就会自动执行一次了,好,这些就是我们初始化定时器的大体思路了

下面是江科大自化协的代码例程:

#include "stm32f10x.h"                  // Device header

//extern uint16_t Num; //引用其他文件(主函数)的Num变量

void Timer_Init(void)
{
//开启时钟

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//TIM2是APB1总线上的外设
	
//选择时基单元的时钟	

	TIM_InternalClockConfig(TIM2); //tim.h--->选择内部时钟,可以不写,因为定时器上电后默认选择内部时钟
	
//初始化时基单元   类似于GPIO的初始化
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //配置时基单元
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //指定时钟分频 ,1分频 影响不大,跳转到定义还可以改成2、4分频   
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数(还有向下、三种中央对其计数)
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1; //周期 ARR自动重装器的值//有1的误差//形成CNT计数  重装值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;  //PSC预分频器的值 10k的计数频率 计10000的数//有1的误差//形成CNT计数  倍数变化
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器的值   //高级定时器才有 这里通用计时器 不用
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);//这里选择的是TIM2,注意下面的NVIC通道
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);//TIM_TimeBaseInit解释里面有,中断同时初始化,这时需要手动把更新中断标志位清除一下,防止reset直接到1
	
//使能更新中断,中断输出控制

	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //使能中断 update 更新中断
	

//NVIC
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //优先级分组
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2在NVIC里的通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
//启动定时器,运行控制

	TIM_Cmd(TIM2, ENABLE); //启动定时器,这样定时器就可以开始工作了,当产生更新时就会触发中断
}

//——————————————————————————————————————————————————————————————————————————————————————————到这里这个定时器初始化代码就完成了

//接下来写中断函数了

/*
void TIM2_IRQHandler(void) //startup_stm32f10x_md.s------->定时器2 的中断函数

{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)//看更新中断标志位
	{
		//Num++;
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清零标志位
	}
}
*/

外部时钟当计数器用

外部中断GPIO的配置,采用上拉,浮空不好
在这里插入图片描述

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

#include "stm32f10x.h"                  // Device header

//PA0 TIM2的ETR引脚
void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//外部中断要配置GPIO
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);//通过ETR引脚的外部时钟模式2配置
	//TIM_ExtTRGPSC_OFF 不需要分频   //TIM_ExtTRGPolarity_NonInverted极性,高电平或上升沿有效      //0x00不用滤波器
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 10 - 1; //从0计到9 //CNT计数器的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;//不需要分频  //如果有预分频了 就是遮挡几次加一次  //被分频
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM2, ENABLE);
}

uint16_t Timer_GetCounter(void)
{
	return TIM_GetCounter(TIM2);
}

/*
void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}
*/


七、跨越不同.c文件的变量

跨文件使用相同变量,如果不处理妥当就会报错

解决方法
1、比如中断里面的变量,如果想要在主函数使用,在使用变量的那个文件(中断文件)的上面,用extern声明一下要用的变量
比如:extern uint16_t Num;
2、把中断函数复制粘贴到主函数的下方,然后注释掉中断里面的中断函数,放在使用它的地方,这样更方便

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Clockwisee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值