STM32F103(八)——定时器实验

实验八 定时器实验

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

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

定时器中断实验

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
本次实验采用默认系统时钟,默认时钟频率为72M,设置分频系数为7199,设置转载值为4999即可实现溢出时间为500ms
定时器配置以及中断服务函数参考代码:

#include "timer.h"
#include "stm32f10x.h"
#include "led.h"
void TIM3_Int_Init(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能定时器时钟源
	
	TIM_TimeBaseInitStructure.TIM_Prescaler=psc;
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period=arr;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化定时器
	
	TIM_ITConfig(TIM3, TIM_IT_Update,ENABLE);//开启定时器中断,设置为更新中断类型
	
	
	NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM3,ENABLE);//使能定时器

}

void TIM3_IRQHandler()
{
	if(TIM_GetITStatus(TIM3,  TIM_IT_Update)){
		LED1=!LED1;
		TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除标志
	}
}

主函数参考代码:

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "beep.h"
#include "key.h"
#include "exti.h"
#include "sys.h"
#include "usart.h"
#include "timer.h"

int main(){
	delay_init();
	uart_init(115200);	 //串口初始化为115200
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	LED_Init();
	KEY_Init();
	EXTIX_Init();
	delay_ms(200);
	LED1=0;
	LED0=0;
	TIM3_Int_Init(4999,7199);//500ms溢出
	while(1){
		LED0=!LED0;
		delay_ms(200);
	}
}

PWM输出实验

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

在这里插入图片描述
配置IO、定时器、PWM模式参考代码:

void TIM3_PWM_Init(u16 arr,u16 psc)
{
		GPIO_InitTypeDef GPIO_InitStructure;//GPIO参初始化的第二个结构体参数
		TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStructure;
		TIM_OCInitTypeDef TIM_OCInitStructure;
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能定时器时钟源
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//GPIOB的时钟使能操作,两个参数可以查阅rcc.h文件查找
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//复用IO的时钟使能操作,两个参数可以查阅rcc.h文件查找
		
		//参数的设计可以参考gpio初始化的函数有效性检测
		GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//设置为推挽输出模式
		GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//设置GPIO的第五个引脚
		GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
		GPIO_Init(GPIOB,&GPIO_InitStructure);//第一个参数为GPIO信息,第二个参数的结构体需要自定义

		//重映射引脚
		GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);
			
		TIM_TimeBaseInitStructure.TIM_Prescaler=psc;
		TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
		TIM_TimeBaseInitStructure.TIM_Period=arr;
		TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
		TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化定时器
		
		TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM2;//模式,这里设置模式2 为大于比较值输出有效电平
		TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//极性
		TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//使能
		TIM_OC2Init(TIM3,&TIM_OCInitStructure);//通道2初始化
		
		TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);//预加载
				
		TIM_Cmd(TIM3,ENABLE);//使能定时器	
}

主函数实现呼吸灯代码:

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "beep.h"
#include "key.h"
#include "exti.h"
#include "sys.h"
#include "usart.h"
#include "timer.h"

int main(){
	delay_init();
	uart_init(115200);	 //串口初始化为115200
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	LED_Init();
	KEY_Init();
	EXTIX_Init();
	delay_ms(200);
	LED1=1;
	LED0=0;
	TIM3_PWM_Init(899,0);//不分频,PWM频率为72M/900=80kHz
	u8 dir=1;
	u16 led0pwm=0;
	while(1){
		delay_ms(20);
		if(dir) led0pwm++;
		else led0pwm--;
		
		if(led0pwm>300) dir=0;
		if(led0pwm==0)  dir=1;
		TIM_SetCompare2(TIM3,led0pwm);//改变比较值,从而改变占空比
	}
}

通用定时器输入捕获

输入捕获工作过程:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
时钟、中断、定时器配置参考代码:

void TIM5_Cap_Init(u16 arr,u16 psc)
{
	GPIO_InitTypeDef GPIO_InitStructure;//GPIO参初始化的第二个结构体参数
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	TIM_ICInitTypeDef TIM_ICInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);//使能定时器时钟源
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//GPIOA的时钟使能操作,两个参数可以查阅rcc.h文件查找
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;//设置为下拉输入模式
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;//设置GPIO的第五个引脚
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);//第一个参数为GPIO信息,第二个参数的结构体需要自定义
	GPIO_ResetBits(GPIOA,GPIO_Pin_0);//初始化为下拉状态
	
	TIM_TimeBaseInitStructure.TIM_Prescaler=psc;
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period=arr;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);//初始化定时器
	
	//输入捕获配置
	TIM_ICInitStructure.TIM_Channel=TIM_Channel_1;
	TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//初始化为上升沿捕获
	TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//设置是否直接映射还是交叉映射
	TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//这里的分频是设置多少次时间触发一次
	TIM_ICInitStructure.TIM_ICFilter=0x00;//这里的滤波器是设置稳定信号的长度,否则过滤
	TIM_ICInit(TIM5,&TIM_ICInitStructure);
	
	
	//中断初始化
	NVIC_InitStructure.NVIC_IRQChannel=TIM5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_ITConfig(TIM5, TIM_IT_Update|TIM_IT_CC1,ENABLE);//开启定时器中断,设置为更新中断、CC1IE捕获类型
	
	TIM_Cmd(TIM5,ENABLE);//使能定时器
}

中断服务函数:

u8  TIM5CH1_CAPTURE_STA=0;	//输入捕获状态	0~5溢出次数,6捕获到高电平标志,7为捕获成功标志	    				
u16	TIM5CH1_CAPTURE_VAL;	//输入捕获值
void TIM5_IRQHandler()
{
	if((TIM5CH1_CAPTURE_STA&0x80)==0)//还没捕获成功
		{
			if(TIM_GetITStatus(TIM5,  TIM_IT_Update)){
			//如果出现更新溢出
				if(TIM5CH1_CAPTURE_STA&0x40)//捕获到高电平
					{
						if((TIM5CH1_CAPTURE_STA&0x3F)==0x3F)//高电平持续时间太长
							{
								TIM5CH1_CAPTURE_STA|=0x80;//最高位置1认为已经捕获
								TIM5CH1_CAPTURE_VAL=0xFFFF;
							}else TIM5CH1_CAPTURE_STA++;
					}
			
			}
			if(TIM_GetITStatus(TIM5, TIM_IT_CC1)){//如果发生的事捕获中断  要么捕获到上升沿,要么捕获到下降沿
				if(TIM5CH1_CAPTURE_STA&0x40){//如果本来捕获到的是高电平,此时进入捕获中断,证明捕获到低电平
					TIM5CH1_CAPTURE_STA|=0x80;//最高位置1认为已经捕获
					TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);
					TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
				}else{//如果本来没有捕获到高电平,此时进入中断,则证明捕获到上升沿
					TIM5CH1_CAPTURE_STA=0;			//清空
					TIM5CH1_CAPTURE_VAL=0;
					TIM_SetCounter(TIM5,0);
					TIM5CH1_CAPTURE_STA|=0X40;		//标记捕获到了上升沿
					TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);		//CC1P=1 设置为下降沿捕获
			
					}
			}

		}
   TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
}

主函数功能:

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "beep.h"
#include "key.h"
#include "exti.h"
#include "sys.h"
#include "usart.h"
#include "timer.h"
extern u8  TIM5CH1_CAPTURE_STA;		//输入捕获状态		    				
extern u16	TIM5CH1_CAPTURE_VAL;	//输入捕获值	
int main(){
	delay_init();
	uart_init(115200);	 //串口初始化为115200
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	LED_Init();
	KEY_Init();
	EXTIX_Init();
	delay_ms(200);
	LED1=1;
	LED0=0;
	TIM3_PWM_Init(899,0);//不分频,PWM频率为72M/900=80kHz
	u8 dir=1;
	u16 led0pwm=0;
	TIM5_Cap_Init(0XFFFF,72-1);	//以1Mhz的频率计数 按照预定最长可以捕获高电平时间为4.2秒
	u32 temp=0; 
	while(1){
		delay_ms(20);
		if(dir) led0pwm++;
		else led0pwm--;
		if(led0pwm>300) dir=0;
		if(led0pwm==0)  dir=1;
		TIM_SetCompare2(TIM3,led0pwm);//改变比较值,从而改变占空比
		if(TIM5CH1_CAPTURE_STA&0X80)//成功捕获到了一次上升沿
		{
			temp=TIM5CH1_CAPTURE_STA&0X3F;
			temp*=65536;//溢出时间总和
			temp+=TIM5CH1_CAPTURE_VAL;//得到总的高电平时间
			printf("HIGH:%d s\r\n",temp/1000000);//打印总的高点平时间
			TIM5CH1_CAPTURE_STA=0;//开启下一次捕获
		}
	}
}
  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值