【嵌入式学习-STM32F103-TIM-定时中断和外部时钟】

这篇具有很好参考价值的文章主要介绍了【嵌入式学习-STM32F103-TIM-定时中断和外部时钟】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

定时器四部分讲解内容,本文是第一部分

1、定时器基本定时,定一个时间,然后让定时器每隔一段时间产生一个中断,来实现每隔一个固定时间执行一段程序的目的,比如要做一个时钟、秒表或者使用一些程序算法

2、定时器输出比较的功能,输出比较这个模块最常见的用途是产生PWM波形,用于驱动电机等设备,使用stm32的PWM波形来驱动舵机和直流电机的例子

3、定时器输入捕获的功能,学习使用输入捕获这个模块来测量方波频率的例子

4、定时器的编码器接口,使用这个编码器接口,能够更加方便地读取正交编码器的输出波形,在编码电机测速中,应用广泛

TIM简介

72M/65536/65536得到中断频率,取倒数就是59.65s
级联,一个定时器的输出,当作另外一个定时器的输入,最大时间达到59.65s * 65536 * 65536

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

高级定时器连接的是性能更高的APB2总线,通用定时器和基本定时器连接的是APB1总线,在RCC开启时钟时注意。

高级定时器具有重复计数器、死区生成、互补输出、刹车输入等功能主要是为了三相无刷电机的驱动设计的。

高级到低级向下兼容

C8T6只有1个高级定时器和3个通用定时器

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

基本定时器

时基单元:预分频器、计数器、自动重装载寄存器

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
预分频器之前,连接的就是基准计数时钟的输入,由于基本定时器只能选择内部时钟,所以可以认为这根线直接到输入端这里,也就是内部时钟CK_INT,内部时钟来源是RCC_TIMxCLK,频率值一般都是系统的主频72MHZ。
stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
如果预分频器写1,那就是2分频,输出频率=输入频率/2=36MHZ
如果预分频器写2,那就是3分频,输出频率=输入频率/3=24MHZ

预分频器的值和实际的分频系数相差1,即实际分频系数=预分频器的值+1,这个预分频器的值是16位,所以最大值可以写65535,也就是65536分频。预分频器就是对输入的基准频率提前进行一个分频的操作。

计数时钟每来一个上升沿,计数器的值就加1,计数器是16位,所以里面的值可以从0一直加到65535.如果再加的话,计数器就会回到0重新开始。所以计数器的值在计时过程中会不断自增运行,当自增运行到目标值时,产生中断,那就完成了定时的任务。

自动重装载寄存器:存储目标值的寄存器。在运行的过程中,计数值不断自增,自动重装值是固定的目标,当计数值等于自动重装值时,也就是计时时间到了。那他会产生一个中断信号,并且清零计数器。计数器自动开始下一次的计数计时。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

UI折线箭头代表这里会产生中断信号,像这种计数值等于自动重装值产生的中断,称为更新中断,这个更新中断之后,就会通往NVIC,我们再配置好NVIC的定时器通道,那么定时器的更新中断就能够得到CPU的响应。

U向下箭头表示更新事件,更新事件不会触发中断,但可以触发内部其他电路的工作。

主从触发

它能让内部的硬件在不受程序的控制下实现自动运行。主模式触发DAC有啥用?
在我们使用DAC时,可能会用DAC输出一段波形,那就需要每隔一段时间来触发一次DAC,让它输出下一个电压点。正常思路,先设置一个定时器产生中断,每隔一段时间在中断程序中调用代码手动触发一次DAC转换,然后DAC输出,缺点:这样会使主程序处于频繁被中断的状态,这回影响主程序的运行和其他中断的响应。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
所以定时器就设计了一个主模式,使用主模式可以把这个定时器的更新事件映射到这个触发输出TRGO(trigger out)的位置,然后TRGO直接接到DAC的触发转换引脚上。这样,定时器的更新就不需要再通过触发中断来触发DAC转换。无需软件参与,实现硬件自动化

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

通用定时器

通用定时器和高级定时器支持3种计数模式,向上计数、向下计数和中央对齐这三种模式。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
内外时钟源选择和主从触发模式结构

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

对于基本定时器而言,定时只能选择内部时钟,也就是系统频率72MHZ,
对于通用定时器而言,定时还可以选择外部时钟,第一个外部时钟来自TIMx_ETR引脚的外部时钟。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
TIMx_ETR是一个定时器的输入端口,可以用来接收外部的时钟信号。在其引脚接上一个外部方波时钟。然后配置一下内部的极性选择、边沿检测和预分频器电路,再配置输入滤波电路,这些电路可以对外部时钟进行一定的整型,因为外部引脚时钟,难免有毛刺,这些电路可对输入的波形进行滤波。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

滤波后的信号兵分两路
上面一路ETRF进入触发控制器,可以选择作为时基单元的时钟。如果要在ETR外部引脚提供时钟或者相对ETR时钟进行计数,把这个定时器当作计数器来用,可配置以下一路的电路,stm32中称为==“外部时钟模式2”==

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

除了ETRF可以提供时钟,TRGI还可以提供时钟,主要用作触发输入来使用的。
触发输入作为外部时钟来使用,称为“外部时钟模式1”
通过TRGI有5通路

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

TRGO可以通向其他定时器,而通向其他定时器的时候,就可以接到其他定时器的ITR引脚上,通过这一路就可以实现定时器级联

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

总结

外部时钟模式1的输入可以是ETR引脚,其他定时器,CH1引脚的边沿、CH1引脚和CH2引脚。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

一般情况下,外部时钟通过ETR引脚即可
对于时钟输入而言,最常用的还是内部的72MHZ的时钟,如果要使用外部时钟,首选ETR引脚外部时钟模式2的输入。,这一路最简单最直接

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
定时器的编码器接口,可以读取正交编码器的输出波形

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
定时器的主模式输出,可以把内部的一些事件映射到这个TRGO引脚上,比如基本定时器分析中,将更新事件映射到TRGO,用于触发其他定时器、DAC或ADC。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

右边:输出比较电路,总共有4个通道,可以用于输出PWM波形,驱动电机

左边:输入捕获电路,总共四个通道,可以用于测量输入方波的频率、占空比

中间寄存器:捕获/比较寄存器,是输入捕获和输出比较电路公用的,因为输入捕获和输出比较不能同时使用,因此寄存器机器引脚是公用的。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

通用定时器与高级定时器的区别

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
第一个:申请中断的地方,增加了一个重复次数计数器,有了这个计数器之后,就可以实现每隔几个计数周期,才发生一次更新事件和更新中断。原来的结构是每个计数周期完成后都会发生更新。相当于对输出的更新信号又做了一次分频。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
以下是高级定时器对输出比较模块的升级

DTG是死区生成电路,右边的输出引脚由原来的一个变为两个互补的输出,可以输出一对互补的PWM波。为了驱动三相无刷电机

刹车输入:给电机驱动提供安全保障,如果外部引脚BKIN产生了刹车信号,或者内部时钟失效,产生了故障,那么控制电路就会自动切断电机的输出,防止以外的发生。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

定时中断基本结构图

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

定时中断和内外时钟源选择

运行控制:就是控制寄存器的一些位,比如启动停止、向上或向下计数等,操作这些寄存器,就能控制时基单元的运行。

左边:为时基单元提供时钟的部分.

第一个定时中断使用RCC的内部时钟

第二个定时器外部时钟就是用外部时钟模式2

右边:计时时间到,产生更新中断后信号的去向(如果高级定时器,还会有一个重复计数器)

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

中断信号会先在状态寄存器里置一个中断标志位,这个标志位会通过中断输出控制,到NVIC申请中断。中断输出控制就是一个中断输出的允许位,如果需要某个中断,就记得允许一下。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

时序

预分频器时序

缓冲寄存器(影子寄存器)真正起作用的寄存器,比如我们在某一时刻,把预分频寄存器由0改为1,如果在此时立刻改变时钟的分频系数,

那么就会导致这里,在一个计数周期内,前半部分和后半部分的频率不一样。这里计数计到一半,计数频率突然改变,而缓冲寄存器,当计数计到一半的时候改变了分频值,这个变化并不会立刻生效,而是会等到本次计数周期结束时产生更新事件,预分频寄存器的值才会被传递到缓冲寄存器里面,才会生效。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

因此,可以看到,即使在计数中途改变了预分频值,技术频率仍然会保持原来的频率,直到本轮计数完成,在下一轮计数时,改变后的分频值才会起作用。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

计数器时序

内部时钟分频因子为2,就是分频系数为2,第一行是内部时钟72MHZ,第二行是时钟使能,高电平启动,第三行是计数器时钟,因为分频系数为2,所以这个频率是内部时钟除2,然后计数器在计数器时钟每个上升沿自增,当增加到0036的时候,发生溢出,那再来一个上升沿,计数器清零,计数器溢出,产生一个更新事件脉冲,另外还会置一个更新中断标志位UIF,该标志位置1,就回去申请中断,然后中断响应后,需要在中断程序中手动清零。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
引入影子寄存器的目的实际上是为了同步,就是让值的变化和更新事件同步发生,防止在运行中途更改造成错误。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
下图,在计数的中途,突然把F5改为36,影子寄存器是真正起作用的。它在自动加载寄存器改变后,还是F5,所以现在计数的目标还是计算到F5,产生更新事件,同时要更改的36才被传递到影子寄存器里,在下一个计数周期36才会有效。
stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

RCC时钟树

RCC时钟树是stm32用来产生和配置时钟,并且把配置好的时钟发送到各个外设的系统,时钟是所有外设运行的基础,所以时钟是最先需要配置的东西。

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
中间:SYSCLK是系统时钟72MHZ。在时钟产生电路,有四个震荡源,分别是内部的8MHZ高速RC振荡器,外部的4-16MHZ高速石英晶体振荡器,即晶振,一般是8MHZ,外部的32.768KHZ低速晶振,一般是给RTC提供时钟的,最后是内部的40KHZ低速RC振荡器,这个可以给看门狗提供时钟。

高速晶振是用来提供系统时钟,如提供给AHB APB2 APB1总线

外部的石英振荡器比内部的RC振荡器更加稳定,因此一般用外部晶振,如果系统很简单,不需要精确的时钟,可选择内部时钟

ST配置流程

在SystemInit函数里,ST配置时钟,首先它会启动内部时钟,选择内部8MHZ为系统时钟,暂时以内部8MHZ的时钟运行,然后再启动外部时钟,进入PLL锁相环进行倍频,8MHZ倍频9倍,得到72MHZ,等到锁相环输出稳定后,选择锁相环输出为系统时钟,这样就把系统时钟由8MHZ切换到72MHZ

CSS:安全保障

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
无论高级、通用还是基本定时器,它们的内部基准时钟都是72MHZ
stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
控制位“外部时钟使能”–>RCC_APB2/1PeriphClockCmd

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
打开时钟,就是在这个位置写1,让左边的时钟能够通过与门输出给外设。
stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

代码部分

程序现象

1、使用定时中断的功能,定时器使用内部时钟定了1秒的时间,每隔1秒申请一下中断,然后在中断函数里执行Num++,最后在OLED上显示Num
stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

2、定时器外部时钟,使用外部时钟驱动定时器,在定时器指定的外部引脚上,输入一个方波信号,来提供定时器计数的时钟,目前用对射式红外传感器来手动模拟一个外部时钟,用挡光片一次遮挡、移开、遮挡、移开提供一个方波。OLED上的CNT就是定时器中计数器的值,每遮挡移开一次,计数器加1,然后计数器计到9后自动清零。同时申请中断,执行Num++。
stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

定时中断

接线图

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

步骤

第一步:RCC开启时钟,定时器的基准时钟和整个外设的工作时钟就都会同时打开

第二步: 选择时基单元的时钟源,对于定时中断,我们选择内部时钟源

第三步:配置时基单元,包括预分频器、自动重装器、计数模式等等

第四步:配置输出中断控制,允许更新中断输出到NVIC

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

第六步:运行控制

第七步:使能计数器

最后:当计数器更新时,触发中断,写一个定时器中断函数

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
定时1s,即定时频率为1HZ

相当于1 = 72MHz/(PSC + 1) /(ARR + 1),PSC=7200,ARR=10000

	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;                        //ARR的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;                     //PSC的值,对72M进行7200分频,得到10K的计数频率,在10K的频率下,计算10000个数,就是1s的时间。

在当前工程搜索中断源
stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
启动文件找定时器2的中断服务函数

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

Timer.c

#include "stm32f10x.h"
#include "Timer.h"

//如果你想跨文件使用变量,可以在使用变量的那个文件的上面,用extern声明一下要用的变量
extern uint16_t Num;

//初始化定时器
void Timer_Init(void)
{
	//开启RCC内部时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	
	//选择时基单元的时钟(定时器上电后默认就是使用内部时钟)
	TIM_InternalClockConfig(TIM2);
	
	//配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;                        //ARR的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;                     //PSC的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;             //重复计数器的值
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	//本质:在调用中断前,中断状态寄存器不能有标志位
	//避免刚一上电就立刻进入中断,在TimeBaseInit的后面和中断的前面(手动清除中断标志位)
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	
	//使能更新中断,开启了更新中断到NVIC的通路
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  //TIM_IT_Update Update更新中断
	
	//NVIC配置
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ;  //定时器2在NVIC的通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	//最后NVIC_Init
	NVIC_Init(&NVIC_InitStructure);
	
	//启动定时器,此时定时器开始工作,当产生更新时,就会触发中断
	TIM_Cmd(TIM2, ENABLE);
}

//当定时器产生更新中断时,这个函数就会自动被执行
void TIM2_IRQHandler(void)
{
	//检查中断标志位,TIM_FLAG_Update为想看的中断标志位
	if(TIM_GetFlagStatus(TIM2, TIM_FLAG_Update)== SET)
	{
		//清除相应的标志位
		TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);
		Num++;
	}
	
}

Timer.h

#ifndef __TIMER_H
#define __TIMER_H

void Timer_Init(void);

#endif /*__TIMER_H*/

main.c

在main函数里,中断函数每秒自动把Num++,然后在主循环里显示。

预分频值和自动重装值对中断频率的影响

如果把自动重装值改为1000,那么由原来计10000个数变成了1000个数

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"
//定义全局变量Num,Num要在中断函数里执行++
uint16_t Num;

int main(void)
{
	OLED_Init();
	//初始化定时器,此时定时器开始工作
	Timer_Init();
	
	OLED_ShowChar(1, 1, 'A');
	OLED_ShowString(1, 3, "HelloWorld!");

	
	while (1)
	{
		OLED_ShowNum(1,5,Num,5);
	}
}

外部时钟

接线图

对射式红外传感器,DO数字输出接到PA0引脚,这个PA0引脚就是TIM2的ETR引脚,我们在这个引脚输入一个外部时钟
stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习

滤波器:以一个采样频率f采样N个点,如果N个点都一样,才会输出有效。
stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
引脚需要用到GPIO,在配置时基单元之前还要先配置GPIO

stm32f103 tim1中断,嵌入式学习-STM32,stm32,单片机,学习
上拉电阻防止跳动
基本任务还是定时中断,但我们不选用内部时钟,我们使用ETR外部时钟模式2
TIM_ETRClockModelConfig通过ETR引脚的外部时钟模式2配置

什么时候需要用到浮空输入呢?
如果外部的输入信号功率很小,内部的上拉电阻可能会影响到这个输入信号,这时就可以用浮空输入,放置影响外部输入的电平。文章来源地址https://www.toymoban.com/news/detail-654434.html

Timer.c

#include "stm32f10x.h"
#include "Timer.h"

//如果你想跨文件使用变量,可以在使用变量的那个文件的上面,用extern声明一下要用的变量
extern uint16_t Num;

//初始化定时器
void Timer_Init(void)
{
	//开启RCC内部时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	
	/* 初始化GPIO*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	//引脚要用到GPIO,因此在配置外部时钟模式2前要先配置GPIO
	//选择时基单元的时钟,不使用内部时钟源,通过ETR引脚的外部时钟模式2配置,不需要分频,不用滤波器
	TIM_ETRClockMode2Config(TIM2, 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;                        //ARR的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;                     //PSC的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;             //重复计数器的值
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	//本质:在调用中断前,中断状态寄存器不能有标志位
	//避免刚一上电就立刻进入中断,在TimeBaseInit的后面和中断的前面(手动清除中断标志位)
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	
	//使能更新中断,开启了更新中断到NVIC的通路
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  //TIM_IT_Update Update更新中断
	
	//NVIC配置
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ;  //定时器2在NVIC的通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	//最后NVIC_Init
	NVIC_Init(&NVIC_InitStructure);
	
	//启动定时器,此时定时器开始工作,当产生更新时,就会触发中断
	TIM_Cmd(TIM2, ENABLE);
}
//实时查看CNT的计数器的值
uint16_t Timer_GetCounter(void)
{
	return TIM_GetCounter(TIM2);
}


//当定时器产生更新中断时,这个函数就会自动被执行
void TIM2_IRQHandler(void)
{
	//检查中断标志位,TIM_FLAG_Update为想看的中断标志位
	if(TIM_GetFlagStatus(TIM2, TIM_FLAG_Update)== SET)
	{
		//清除相应的标志位
		TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);
		Num++;
	}
	
}

Timer.h

#ifndef __TIMER_H
#define __TIMER_H

void Timer_Init(void);
uint16_t Timer_GetCounter(void);  //获取计数值

#endif /*__TIMER_H*/

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"

uint16_t Num;

int main(void)
{
	OLED_Init();
	//初始化定时器,此时定时器开始工作
	Timer_Init();
	
	OLED_ShowString(1, 1, "Num:");
	OLED_ShowString(2, 1, "CNT:");

	
	while (1)
	{
		OLED_ShowNum(1,5,Num,5);
		OLED_ShowNum(1,5,Timer_GetCounter(),5);
	}
}

到了这里,关于【嵌入式学习-STM32F103-TIM-定时中断和外部时钟】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式学习笔记——STM32的USART收发字符串及串口中断

    上一篇中,介绍了串口收发相关的寄存器,通过代码实现了一个字节的收发,本文接着上面的内容,通过功能函数实现字符串的收发,然后引入中断解决收发过程中while()死等的问题。 根据昨天的字符发送函数,只需要稍作修改即可实现发送函数了,一个字符串的结尾会有一

    2024年02月03日
    浏览(67)
  • 嵌入式-stm32-江科大-EXTI外部中断

    1.1 STM32 中断系统 中断 是指在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续执行, 当中断发生时是由硬件自动调用中断函数执行的,期间编译器会保护现场最后还原现场

    2024年01月25日
    浏览(44)
  • 【STM32】STM32学习笔记-TIM定时中断(13)

    TIM(Timer)定时器 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断 16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时 不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码

    2024年01月17日
    浏览(38)
  • 嵌入式硬件——stm32F103C8T6

    如下图:    处理器核心:STM32F103C8T6内置了ARM Cortex-M3处理器,这是一种高性能、低功耗的32位RISC处理器,适用于嵌入式系统。 时钟速度:它可以工作在不同的时钟速度,最高主频可达72 MHz。 存储器:包括64KB的Flash程序存储器用于存储程序代码,以及20KB的SRAM用于存储数据和

    2024年02月05日
    浏览(46)
  • 江科大stm32视频学习笔记——TIM定时中断&定时器外部时钟

    目录 一、TIM(Timer)定时器简介  1.1 定时器类型 摘要 1.1.1 基本定时器 1.1.2 通用定时器 1.1.3 高级定时器  1.2 定时中断基本结构 1.2.1 结构框图 1.2.2 时序图 二、定时器定时中断定时器外部时钟 2.1 内部时钟闹钟代码 2.1.1 Timer.c 2.1.2 Buzzer.c加入间隔发声函数 2.1.3 main.c 2.1.4 实验视频

    2024年01月23日
    浏览(54)
  • 嵌入式开发--STM32用DMA+IDLE中断方式串口接收不定长数据

    之前讲过用 利用IDLE空闲中断来接收不定长数据 ,但是没有用到DMA,其实用DMA会更加的高效,MCU也可以腾出更多的性能去处理应该做的事情。 IDLE顾名思义,就是空闲的意思,即当监测到串口空闲超过1个串口的数据帧时,会使状态寄存器(SR或ISR)的IDLE位置位,如果此时控制

    2024年04月17日
    浏览(54)
  • [嵌入式软件][启蒙篇][仿真平台] STM32F103实现串口输出输入、ADC采集

    上一篇:[嵌入式软件][启蒙篇][仿真平台] STM32F103实现LED、按键 学C语言时,使用的printf()函数,就是通过串口打印出来的。 跟外部器件通信,比如GPS模块、蓝牙模块、wifi模块; 两个开发板之间通信,制定私有协议。 PC电脑通信,使用上位机显示数据或控制下位机。 操作:打

    2024年01月22日
    浏览(52)
  • STM32学习笔记(四)丨TIM定时器及其应用(定时中断、内外时钟源选择)

    ​  本次课程采用单片机型号为STM32F103C8T6。 ​  课程链接:江科大自化协 STM32入门教程   往期笔记链接:   STM32学习笔记(一)丨建立工程丨GPIO 通用输入输出   STM32学习笔记(二)丨STM32程序调试丨OLED的使用   STM32学习笔记(三)丨中断系统丨EXTI外部中断

    2023年04月13日
    浏览(51)
  • 嵌入式学习笔记(32)S5PV210的向量中断控制器

    6.6.1异常处理的2个阶段 可以将异常处理分为2个阶段来理解。第一个阶段是异常向量表跳转;第二个阶段是进入了真正的异常处理程序irq_handler之后的部分。 6.6.2回顾:中断处理的第一个阶段(异常向量表跳转阶段)处理 (1)第一个阶段之所以能够进行,主要依赖于CPU设计时

    2024年02月07日
    浏览(54)
  • 【嵌入式学习笔记】嵌入式基础9——STM32启动过程

    程序段交叉引用关系(Section Cross References):描述各文件之间函数调用关系 删除映像未使用的程序段(Removing Unused input sections from the image):描述工程中未用到被删除的冗余程序段(函数/数据) 映像符号表(Image Symbol Table):描述各符号(程序段/数据)在存储器中的地址、类

    2024年02月15日
    浏览(75)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包