2.[STM32]高级定时器(TIM1&TIM8)

STM32F103有两个高级定时器,分别是TIM1TIM8;高级控制定时器(TIM1和TIM8)由一个16位的自动装载计数器组成,它由一个可编程的预分频器驱动。
适用场合:
测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较、PWM、嵌入死区时间的互补PWM等);
使用方法
使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。
接下来以TIM1为例子,结合蜂鸣器来说明如何使用高级定时器,本次主要使用它的计数模式,实现精确的计数功能。

蜂鸣器原理图
2.[STM32]高级定时器(TIM1&TIM8)_第1张图片
解析:
U8A为蜂鸣器正极连接3.3V电压,负极与PNP三极管相连,当三极管基极为低电平时导通,蜂鸣器鸣叫;故给Buzzer引脚不同时间的脉宽,就可以实现蜂鸣器鸣叫的频率(Buzzer与单片机的PB9引脚相连)
本次实验使用的是有源蜂鸣器,它内部带震荡体,通电就会鸣叫。

TIM1定时器程序的编写

1.创建TIM函数

void TIM1_UserConfig(u16 Period,u16 Prescaler)
//第一个形参用来设置自动重载计数周期值
//第二个形参是用来设置分频系数
//之后计算脉宽会用到

2.定义TIM结构体和中断结构体

TIM_TimeBaseInitTypeDef TIM_InitStructure;
NVIC_InitTypeDef  NVIC_InitStructure;

3.选择TIM1时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);

4.结构体参数配置
在库文件中,我们可以看到TIM1结构体的定义,包括两个u16类型的重装载值预分频值时钟分割计数模式u8类型的重复计数次数

	TIM_InitStructure.TIM_Period = Period;//重装载值
	TIM_InitStructure.TIM_Prescaler = Prescaler;//分频系数
	TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//不分割
	TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
	TIM_InitStructure.TIM_RepetitionCounter = 0;//只要重装载值计数完毕就产生更新
	TIM_TimeBaseInit(TIM1,&TIM_InitStructure);//初始化

	TIM_ClearITPendingBit(TIM1,TIM_IT_Update);//清空中断标志位
	TIM_ITConfig(TIM1,TIM_IT_Update|TIM_IT_Trigger,ENABLE);//开启中断更新和触发中断源
	TIM_Cmd(TIM1,ENABLE);//开启全局中断

5.中断配置

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//选择中断分组
	NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;//选择TIM1中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//中断优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//子占优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能
	NVIC_Init(&NVIC_InitStructure);//初始化

6.蜂鸣器配置

//beep.c
	#include "beep.h"

	void BEEP_UserConfig(void){

	GPIO_InitTypeDef  GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = BEEP;//PB9
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;//2MHz
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出模式
	GPIO_Init(BEEP_PROT,&GPIO_InitStructure);
	
	GPIO_SetBits(BEEP_PROT,BEEP);//起始状态拉高电平
}

	//beep.h
	#ifndef __BEEP_H
	#define __BEEP_H
	
	#include "sys.h"
	
	#define BEEP GPIO_Pin_9
	#define BEEP_PROT GPIOB
	
	void BEEP_UserConfig(void);
	
	#endif
	

7.中断处理函数配置

	void TIM1_UP_IRQHandler(void){

	//获取TIM1中断状态
	//若为1则产生中断
	if(TIM_GetITStatus(TIM1,TIM_IT_Update) != RESET){
	
	//获取引脚状态,若为高电平则取反变为低电平
	//GPIO_ReadOutputDataBit() 读取GPIO输出状态函数
	GPIO_WriteBit(BEEP_PROT,BEEP,(BitAction)(!GPIO_ReadOutputDataBit(BEEP_PROT,BEEP)));
	
	TIM_ClearITPendingBit(TIM1,TIM_IT_Update);//清空中断
	}
	}

8.main函数

#include "sys.h"
#include "led.h"
#include "time.h"
#include "beep.h"



 int main(void)
 {		
	
	 LED_UserConfig();
	 BEEP_UserConfig();
	 TIM1_UserConfig(50-1,7200-1);
	 
	while(1){;}
 }

脉宽过程计算分析
TIM1_UserConfig(50-1,7200-1);//5ms
我们单片机的频率为72MHz =72 000 000Hz
先对其进行7200分频 ,故分频系数Prescaler为7200
72 000 000/7200 = 1 000 0
我们需要5ms的脉宽 5ms=200hz 故用1 000 0/200=50 既重装载值Period为50
下面是我用逻辑分析仪抓取的波形,脉宽正好为5ms
2.[STM32]高级定时器(TIM1&TIM8)_第2张图片

最后,把程序下载进单片机,就可以听到蜂鸣器鸣叫了

例程代码
链接:https://pan.baidu.com/s/1j49awMoDhJbcSWNuCiR34w
提取码:mow1

你可能感兴趣的:(STM32,c语言,stm32,开发语言)