stm32下常用函数~中断定时器

这篇具有很好参考价值的文章主要介绍了stm32下常用函数~中断定时器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

学习江协科技stm32基于库函数开发记录一下
代码压缩包地址:code
文章来源地址https://www.toymoban.com/news/detail-826107.html

8.对射式红外传感器(中断)

中断流程

中断初始化
1.开启时钟
2.GPIO初始化
3.AFIO选择引脚
4.EXTI初始化
5.NVIC分组
6.NVIC配置   

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启afio时钟

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);//将外部中断的14号线映射到GPIOB

EXTI_Init(&EXTI_InitStruct);//中断初始化

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置nvic分组

NVIC_Init(&NVIC_InitStruct);//nvic初始化

EXTI_GetITStatus(EXTI_Line14)//获取标志位

EXTI_ClearITPendingBit(EXTI_Line14)//清除标志位

EXTI15_10_IRQHandler(void)//中断服务函数(启动文件)

CountSensor.h

#ifndef __COUNTSENSOR_H
#define __COUNTSENSOR_H

void CountSeneor_Init(void);//中断初始化
uint16_t CountSensor_Get(void);//次数获取
#endif

CountSensor.c

#include "stm32f10x.h"                  // Device header
uint16_t CountSensor_Count;
/*
	中断初始化
	1.开启时钟
	2.GPIO初始化
	3.AFIO选择引脚
	4.EXTI初始化
	5.NVIC分组
	6.NVIC配置
*/
void CountSeneor_Init(void)
{
	//开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启gpiob时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启afio时钟,外部中断必须开启afio时钟
	//GPIO初始化
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);//将PB14脚初始化为上拉输入  
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);//选择用作EXTI线的GPIO引脚
	//中断线选择,将外部中断的14号线映射到GPIOB,即选择PB14为外部中断引脚
	
	EXTI_InitTypeDef EXTI_InitStruct;
	EXTI_InitStruct.EXTI_Line = EXTI_Line14;//配置外部中断线
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;//外部中断线使能
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//指定外部中断线为中断模式
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;//外部中断线上升沿触发
	EXTI_Init(&EXTI_InitStruct);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置nvic分组,目前为分组2,抢占优先级与响应优先级均为0~3
	
	//nvic配置	
	NVIC_InitTypeDef NVIC_InitStruct;//结构体定义
	NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;//选择配置nvic的EXTI15_10
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;//响应优先级
	NVIC_Init(&NVIC_InitStruct);
}
void EXTI15_10_IRQHandler(void)//服务中断函数
{
	if(EXTI_GetITStatus(EXTI_Line14)== SET)
	{
		if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14) == 0)
		{
			CountSensor_Count ++;
		}
		EXTI_ClearITPendingBit(EXTI_Line14);//结束清除标志位
	}
}

uint16_t CountSensor_Get(void)
{
	return CountSensor_Count;
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "oled.h"
#include "countsensor.h"

int main()
{
	OLED_Init();//oled初始化
	CountSeneor_Init();
	OLED_ShowString(1,1,"count:");//第一行第一列展示字符串count:
	while(1)
	{
		OLED_ShowNum(1,7,CountSensor_Get(),5);
	}
}

9.旋转编码器(中断)

Encoder.h

#ifndef __ENCODER_H
#define __ENCODER_H

void Encoder_Init(void);
int16_t Encoder_Get(void);
#endif

Encoder.c

#include "stm32f10x.h"                  // Device header
uint16_t Encoder_Count;
/*
	中断初始化
	1.开启时钟
	2.GPIO初始化
	3.AFIO选择引脚
	4.EXTI初始化
	5.NVIC分组
	6.NVIC配置
*/
void Encoder_Init(void)
{
	//开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启gpiob时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启afio时钟,外部中断必须开启afio时钟
	//GPIO初始化
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);//将PB14脚初始化为上拉输入  
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);//选择用作EXTI线的GPIO引脚
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
	
	EXTI_InitTypeDef EXTI_InitStruct;
	EXTI_InitStruct.EXTI_Line = EXTI_Line0 | EXTI_Line1;//配置外部中断线
	EXTI_InitStruct.EXTI_LineCmd = ENABLE;//外部中断线使能
	EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//指定外部中断线为中断模式
	EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;//外部中断线下降沿触发
	EXTI_Init(&EXTI_InitStruct);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置nvic分组,目前为分组2,抢占优先级与响应优先级均为0~3
	
	//nvic配置	
	NVIC_InitTypeDef NVIC_InitStruct;//结构体定义
	NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;//选择配置nvic的EXTI0
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;//响应优先级
	NVIC_Init(&NVIC_InitStruct);
	
	NVIC_InitStruct.NVIC_IRQChannel = EXTI1_IRQn;//选择配置nvic的EXTI0
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//使能
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;//响应优先级
	NVIC_Init(&NVIC_InitStruct);
}
void EXTI0_IRQHandler(void)//服务中断函数
{
	if(EXTI_GetITStatus(EXTI_Line0)== SET)
	{
		if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)
		{
			if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
			{
				Encoder_Count ++;
			} 
		}
		EXTI_ClearITPendingBit(EXTI_Line0);//结束清除标志位
	}
}
void EXTI1_IRQHandler(void)//服务中断函数
{
	if(EXTI_GetITStatus(EXTI_Line1)== SET)
	{
		if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
		{
			if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
			{
				Encoder_Count --;
			}
		}
		EXTI_ClearITPendingBit(EXTI_Line1);//结束清除标志位
	}
}

int16_t Encoder_Get(void)
{
	int16_t Temp;
	Temp = Encoder_Count;
	Encoder_Count = 0;
	return Temp;
}//返回后数据清零

10.定时器内部时钟

定时器初始化流程

1.开启时钟
2.配置时钟源
3.时基单元初始化
4.中断输出配置
5.nvic中断分组
6.nvic配置
7.tim使能

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//开启tim2时钟位于apb1总线

TIM_InternalClockConfig(TIM2);//选择时钟(内部时钟tim2)

TIM_TimeBaseInit();//配置时基单元

TIM_ITConfig();//中断输出配置

TIM_Cmd()//定时器使能

Timer.h

#ifndef __TIMER_H
#define __TIMER_H

void Timer_Init(void);

#endif

Timer.c

#include "stm32f10x.h"                  // Device header
/*
	1.开启时钟
	2.配置时钟源
	3.时基单元初始化
	4.中断输出配置
	5.nvic中断分组
	6.nvic配置
	7.tim使能
*/

/*
51
32   usart/iic/spi/freertos ~ 通信+系统
树莓派 ~linux编程
*/
void Timer_Init(void)
{
	//开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	//选择时钟源~~选择tim2为内部时钟
	TIM_InternalClockConfig(TIM2);
	//配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//计数模式~向上计数
	TIM_TimeBaseInitStruct.TIM_Period = 10000 - 1;//计数周期
	TIM_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1;//预分频器72M = 7200 0000 /10000 /7200 = 1
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
	
	//中断输出配置
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//开启nvic中断
	
	//nvic中断分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ncic中断分组2
	//nvic初始化
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStruct);
	//定时器使能
	TIM_Cmd(TIM2, ENABLE);
}
//void TIM2_IRQHandler(void)
//{
//	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
//	{
//		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除标志位
//	}
//}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "oled.h"
#include "Timer.h"//.h文件多打了一个空格

int16_t Num;

int main()
{
	OLED_Init();//oled初始化
	Timer_Init();
	OLED_ShowString(1,1,"Num:");
	while(1)
	{
		OLED_ShowNum(1,5,Num,5);
	}
}

void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
	{
		Num ++ ;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除标志位
	}
}

11.定时器外部时钟

定时器流程

1.开启时钟
2.配置时钟源
3.时基单元初始化
4.中断输出配置
5.nvic中断分组
6.nvic配置
7.tim使能 

TIM_ETRClockMode2Config();//配置外部时钟模式2

TIM_GetCounter(TIM2);//返回tim2的cnt值

Timer.h

#ifndef __TIMER_H
#define __TIMER_H

void Timer_Init(void);
uint16_t Timer_GetCount(void);
#endif

Timer.c

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
	//开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
//
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启gpioa时钟
//
	
//
	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);//gpioa初始化~上拉输入
//

//
	TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x0f);
	//配置外部时钟模式2,外设tim2,外部触发关闭,外部触发极性上升沿,滤波最大~0x0f
//
//	//选择时钟源~~选择tim2为内部时钟
//	TIM_InternalClockConfig(TIM2);
	//配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//计数模式~向上计数
	TIM_TimeBaseInitStruct.TIM_Period = 10 - 1;//计数周期 arr
	TIM_TimeBaseInitStruct.TIM_Prescaler = 1 - 1;//预分频器psc
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;//重复计数器
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除中断触发标志位
	//中断输出配置
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//开启nvic中断
	//启用或禁用指定中断,tim2,tim更新中断源,使能
	//nvic中断分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ncic中断分组2
	//nvic初始化
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStruct);
	//定时器使能
	TIM_Cmd(TIM2, ENABLE);
}
uint16_t Timer_GetCount(void)
{
	return TIM_GetCounter(TIM2);//返回tim2的cnt值
}
//void TIM2_IRQHandler(void)
//{
//	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
//	{
//		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除标志位
//	}
//}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "oled.h"
#include "Timer.h"//.h文件多打了一个空格

int16_t Num;

int main()
{
	OLED_Init();//oled初始化
	Timer_Init();
	OLED_ShowString(1,1,"Num:");
	OLED_ShowString(2,1,"CNT:");
	while(1)
	{
		OLED_ShowNum(1,5,Num,5);
		OLED_ShowNum(2,5,Timer_GetCount(),5);
	}
}

void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
	{
		Num ++ ;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除标志位
	}
}

12.PWM控制LED

输出比较流程

1.rcc开启时钟(tim/gpio)
2.配置时基单元
3.配置输出比较单元(ccr/输出比较模式/极性选择/输出使能)
4.配置GPIO口为复用推挽
5.启动计数器

TIM_InternalClockConfig(TIM2); //内部时钟源选择

TIM_TimeBaseInit();//时基单元初始化

TIM_OC1Init();//输出比较初始化

TIM_OCStructInit();//结构体赋值

TIM_Cmd();//定时器使能

TIM_SetCompare1();//设置ccr1的值

pwm.h

#ifndef __PWM_H
#define __PWM_H
void PWM_Init(void);//pwm初始化
void PWM_SetComparel(uint16_t Compare);//设置ccr1的值用于调节占空比
#endif

pwm.c

#include "stm32f10x.h"                  // Device header
/*
1.rcc开启时钟(tim/gpio)
2.配置时基单元
3.配置输出比较单元(ccr/输出比较模式/极性选择/输出使能)
4.配置GPIO口为复用推挽
5.启动计数器
*/
void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);							//tim2时钟开启
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);             //gpioa初始化
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);																//gpio_a0脚初始化
	
	TIM_InternalClockConfig(TIM2);																	//内部时钟源选择
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 100 - 1;//计数周期
	TIM_TimeBaseInitStruct.TIM_Prescaler = 720 - 1;//预分频器
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;//重复计数器
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);                //时基单元初始化
	
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct);//结构体初始化,结构体未完全赋值先进行初始化赋值
	
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;//输出比较模式
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;//输出比较极性~high原样输出/low反向输出
	TIM_OCInitStruct.TIM_OutputState = ENABLE;//使能
	TIM_OCInitStruct.TIM_Pulse = 0;//CCR初始值
	TIM_OC1Init(TIM2,&TIM_OCInitStruct);                            //输出比较初始化
	
	TIM_Cmd(TIM2, ENABLE);//使能,定时器开始运行
}
void PWM_SetComparel(uint16_t Compare)
{
	TIM_SetCompare1(TIM2, Compare);//设置ccr1的值
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "oled.h"
#include "pwm.h"

uint8_t i;

int main()
{
	OLED_Init();//oled初始化
	PWM_Init();//pwm初始化
	while(1)
	{
		for(i = 0;i<=100;i++)
		{
			PWM_SetComparel(i);
			Delay_ms(10);
		}
		for(i = 0;i<=100;i++)
		{
			PWM_SetComparel(100 - i);
			Delay_ms(10);
		}
	}
}

13.PWM控制舵机

Servo.h

#ifndef __SERVO_H
#define __SERVO_H
void Servo_Init(void);
void Servo_SetAngle(float Angle);
#endif 

Servo.c

#include "stm32f10x.h"                  // Device header
#include "stm32f10x.h"                  // Device header
#include "pwm.h"
void Servo_Init(void)
{
	PWM_Init();//初始化舵机底层pwm
}
void Servo_SetAngle(float Angle)
{
	PWM_SetCompare2(Angle / 180 * 2000 + 500);//设置占空比
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "oled.h"
#include "Servo.h"
#include "Key.h"

uint8_t KeyNum;
float Angle;

int main()
{
	OLED_Init();//oled初始化
	Servo_Init();//舵机初始化
	Key_Init();//按键初始化
	
	OLED_ShowString(1,1,"Angle:");//显示静态字符"Angle:"
	
	while(1)
	{
		KeyNum = Key_GetNum();//得到键码返回值
		if(KeyNum == 1)
		{
			Angle += 30;//角度增加30
			if(Angle > 180)
			{
				Angle = 0;
			}
		}
		Servo_SetAngle(Angle);
		OLED_ShowNum(1,7,Angle,3);
	}
}

14.pwm驱动直流电机

Motor.h

#ifndef __MOTOR_H
#define __MOTOR_H
void Motor_Init(void);//舵机初始化
void Motor_SetSpeed(int8_t Speed);//速度设置
#endif

Motor.c

#include "stm32f10x.h"                  // Device header
#include "pwm.h"
void Motor_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA ,&GPIO_InitStruct);//PA4与PA5脚进行初始化,用作控制脚
	
	PWM_Init();//PA2脚用作输出pwm
}
void Motor_SetSpeed(int8_t Speed)
{
	if(Speed >= 0)
	{
		GPIO_SetBits(GPIOA, GPIO_Pin_4);
		GPIO_ResetBits(GPIOA, GPIO_Pin_5);
		PWM_SetCompare3(Speed);
	}
	else
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_4);
		GPIO_SetBits(GPIOA,GPIO_Pin_5);
		PWM_SetCompare3(-Speed);//反向旋转
	}
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "oled.h"
#include "Motor.h"
#include "Key.h"

uint8_t KeyNum;
int8_t Speed;

int main()
{
	OLED_Init();//oled初始化
	Motor_Init();//舵机初始化
	Key_Init();//按键初始化
	
	OLED_ShowString(1,1,"speed:");
	
	while(1)
	{
		KeyNum = Key_GetNum();
		if(KeyNum == 1)
		{
			Speed += 20;
			if(Speed > 100)
			{
				Speed = -100;
			}
		}
		Motor_SetSpeed(Speed);//占空比传递
		OLED_ShowSignedNum(1,7,Speed,3);
	}
}

15.定时器输入捕获

TIM_ICInit(TIM3,&TIM_ICInitStruct);//输入捕获初始化

TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//触发源选择~TI1FP1

TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//从模式选择

输入捕获流程

1.rcc开启时钟(gpio/tim)
2.gpio初始化(gpio~输入模式)~上拉 or 浮空  
3.配置时基单元,让cnt计数器在内部时钟的驱动下自增
4.配置输入捕获单元(滤波器、极性、直连通道 or 交叉通道、分频器) 
5.选择从模式的触发源ti1fp1
6.选择触发后进行的操作reset
7.tim开启定时器

ic.h

#ifndef __IC_H
#define __IC_H
void Ic_Init(void);//输入捕获初始化
uint32_t Ic_GetFreq(void);//获取频率
#endif

ic.c

#include "stm32f10x.h"                  // Device header
/*
1.rcc开启时钟(gpio/tim)
2.gpio初始化(gpio~输入模式)~上拉 or 浮空  
3.配置时基单元,让cnt计数器在内部时钟的驱动下自增
4.配置输入捕获单元(滤波器、极性、直连通道 or 交叉通道、分频器)  
5.选择从模式的触发源ti1fp1
6.选择触发后进行的操作reset
7.tim开启定时器
*/
void Ic_Init(void)
{
	//rcc开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);							//tim2时钟开启
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);             //gpioa初始化
	//gpio初始化
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//复用推挽输出
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);																//gpio_a0脚初始化
	//时钟源选择
	TIM_InternalClockConfig(TIM3);																	//内部时钟源选择
	//时基单元初始化
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 65536 - 1;//计数周期
	TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1;//预分频器
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;//重复计数器
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);  
	//输入捕获初始化
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;//模式3通道1
	TIM_ICInitStruct.TIM_ICFilter = 0xF;//滤波
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;//极性,不反转
	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;//预分频,不分频
	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;//直接选择
	TIM_ICInit(TIM3,&TIM_ICInitStruct);                                  //<=====================
	//选择触发源及从模式
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//触发源选择~TI1FP1       //<=====================
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//选择从模式					 //<=====================
	
	TIM_Cmd(TIM3,ENABLE);//使能tim3,定时器开始运行
}
uint32_t Ic_GetFreq(void)
{
	return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "oled.h"
#include "pwm.h"
#include "ic.h"
int main()
{
	OLED_Init();//oled初始化
	PWM_Init();//pwm初始化
	Ic_Init();//输入捕获初始化
	OLED_ShowString(1,1,"Freq:00000Hz");
	PWM_SetPrescaler(720 - 1);//设置频率 freq = 72M / (psc + 1)/100
	PWM_SetCompare3(50);//设置占空比 duty = ccr / 100
	while(1)
	{
		OLED_ShowNum(1,6,Ic_GetFreq(),5);//频率展示
	}
}

16.输入捕获~频率与占空比

TIM_PWMIConfig();//传入通道及结构体变量将自动配置另一个通道

ic.h

#ifndef __IC_H
#define __IC_H
void Ic_Init(void);//输入捕获初始化
uint32_t Ic_GetFreq(void);//获取频率
uint32_t Ic_GetDuty(void);//获取占空比
#endif

ic.c

#include "stm32f10x.h"                  // Device header
/*
1.rcc开启时钟(gpio/tim)
2.gpio初始化(gpio~输入模式)~上拉 or 浮空  
3.配置时基单元,让cnt计数器在内部时钟的驱动下自增
4.配置输入捕获单元(滤波器、极性、直连通道 or 交叉通道、分频器)  
5.选择从模式的触发源ti1fp1
6.选择触发后进行的操作reset
7.tim开启定时器
*/
void Ic_Init(void)
{
	//rcc开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);							//tim2时钟开启
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);             //gpioa初始化
	//gpio初始化
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//复用推挽输出
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);																//gpio_a0脚初始化
	//时钟源选择
	TIM_InternalClockConfig(TIM3);																	//内部时钟源选择
	//时基单元初始化
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 65536 - 1;//计数周期
	TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1;//预分频器
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;//重复计数器
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);  
	//输入捕获初始化(pwmi)
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;//模式3通道1
	TIM_ICInitStruct.TIM_ICFilter = 0xF;//滤波
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;//极性,不反转
	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;//预分频,不分频
	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;//直接选择
	//TIM_ICInit(TIM3,&TIM_ICInitStruct);                                  
	TIM_PWMIConfig(TIM3,&TIM_ICInitStruct);//将结构体变量交给TIM_PWMIConfig,配置tim3的输入捕获通道
																				 //同时此函数会把另一个通道配置为相反模式//<=====================
	//选择触发源及从模式
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//触发源选择~TI1FP1       
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//选择从模式					 
	
	TIM_Cmd(TIM3,ENABLE);//使能tim3,定时器开始运行
}
uint32_t Ic_GetFreq(void)
{
	return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}
uint32_t Ic_GetDuty(void)
{
	return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1);//计算占空比
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "oled.h"
#include "pwm.h"
#include "ic.h"
int main()
{
	OLED_Init();//oled初始化
	PWM_Init();//pwm初始化
	Ic_Init();//输入捕获初始化
	OLED_ShowString(1,1,"Freq:00000Hz");
	OLED_ShowString(2,1,"Duty:00%");
	PWM_SetPrescaler(720 - 1);//设置频率 freq = 72M / (psc + 1)/100
	PWM_SetCompare3(50);//设置占空比 duty = ccr / 100
	while(1)
	{
		OLED_ShowNum(1,6,Ic_GetFreq(),5);//频率展示
		OLED_ShowNum(2,6,Ic_GetDuty(),2);//占空比显示
	}
}

17.编码器测速

TIM_EncoderInterfaceConfig();//配置编码器以及两个通道是否反相

EncoderTwo.h

#ifndef __ENCODERTWO_H
#define __ENCODERTWO_H
void EncoderTwo_Init(void);//编码器测速初始化
int16_t Encoder_Get(void);//获取编码器测速值
#endif

EncoderTwo.c

#include "stm32f10x.h"                  // Device header

void EncoderTwo_Init(void)
{
	/*开启时钟*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);			//开启TIM3的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//开启GPIOA的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);							//将PA6和PA7引脚初始化为上拉输入
	
	/*时基单元初始化*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定义结构体变量
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1;               //计数周期,即ARR的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;                //预分频器,即PSC的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            //重复计数器,高级定时器才会用到
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);             //将结构体变量交给TIM_TimeBaseInit,配置TIM3的时基单元
	
	//输入捕获初始化
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICStructInit(&TIM_ICInitStruct);//不完全赋值先进行初始化//<======================
	
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;//选择定时器通道
	TIM_ICInitStruct.TIM_ICFilter = 0xf;//滤波器
	TIM_ICInit(TIM3,&TIM_ICInitStruct);
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;//选择定时器通道
	TIM_ICInitStruct.TIM_ICFilter = 0xf;//滤波器
	TIM_ICInit(TIM3,&TIM_ICInitStruct);

	TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
	//配置编码器模式以及两个输入通道是否反相
	TIM_Cmd(TIM3, ENABLE);
}
int16_t Encoder_Get(void)
{
	int16_t Temp;
	Temp = TIM_GetCounter(TIM3);//获取计数器计数值
	TIM_SetCounter(TIM3 , 0);//设置计数器值
	return Temp;
}

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "oled.h"
#include "timer.h"
#include "encodertwo.h"

int16_t Speed;

int main()
{
	OLED_Init();//oled初始化
	Timer_Init();//定时器初始化
	EncoderTwo_Init();//编码器接口初始化
	OLED_ShowString(1,1,"Speed:");
	while(1)
	{
		OLED_ShowSignedNum(1,7,Speed,5);
	}
}
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
	{
		Speed = Encoder_Get();//将寄存器中数值保存到中间变量Speed中
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除标志位
	}
}

到了这里,关于stm32下常用函数~中断定时器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 51 单片机【外部中断、定时器中断、回调函数】

    ​这里的外部中断类似监听器,时时刻刻监视某引脚的电平变化;这里的定时器中断类似于定时任务,可以定时执行某函数;这里将回调函数和中断结合起来,案例里有点设计模式的味道(忘了哪个了,也可能就是感觉,关于高层不能调用低层的解决),也有点函数式编程的

    2024年02月04日
    浏览(69)
  • STM-32:TIM定时中断—定时器定时中断/定时器外部时钟

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

    2024年02月09日
    浏览(57)
  • 【STM32】STM32学习笔记-定时器定时中断 定时器外部时钟(14)

    1.1 TIM_InternalClockConfig 1.2 TIM_TimeBaseInit 1.3 TIM_TimeBaseInitTypeDef 1.4 TIM_ClearFlag 1.5 TIM_ITConfig 1.6 TIM_Cmd 1.7 中断服务函数 参考程序 1.8 TIM_ETRClockMode2Config timer.h timer.c main.c timer.h timer.c main.c 09-定时器定时中断.rar 10-定时器外部时钟.rar 参考: 【STM32】江科大STM32学习笔记汇总

    2024年02月03日
    浏览(55)
  • STM32——定时器——定时中断

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 本节先只讲解定时器的定时中断,内外中断源选择。 TIM(Timer)定时器 定时器可以 对输入的时钟进行计数 ,并在计数值达到设定值时触发中断。 16位计数器、预分频器、自动重装寄存器的时基单元 ,

    2024年04月10日
    浏览(49)
  • STM32定时器-定时器中断功能详解

    STM32的众多定时器中我们使用最多的是高级定时器和通用定时器,而高级定时器一般也是用作通用定时器的功能,下面我们就以通用定时器为例进行讲解,其功能和特点包括: 通用与基本定时器(2~7)位于低速的APB1总线上 高级定时器(1、8)位于高速的APB2总线上 自动装载计

    2024年02月08日
    浏览(55)
  • stm32 定时器部分(定时中断)

    一.定时中断(概念部分) 定时中断主要包含两种中断一种是更新中断还有一种是输入捕获中断 更新中断 :更新中断通常用于定时器的基本定时功能。当定时器计数器溢出并重新从零开始计数时,会触发更新中断。你可以配置定时器的计数周期和预分频器来控制定时器的计时

    2024年03月15日
    浏览(59)
  • 定时器详解 -- 定时器中断、PWM输出 --stm32

    STM32F103系列芯片拥有多种定时器,包括基本定时器、通用定时器和高级定时器,每种定时器都具有一些特定的功能。 向上计数:计数器从0计数到自动重装载值(ARR),然后重新从0开始计数并且产生一个计数器溢出事件。 向下计数:计数器从自动重装载值(ARR)开始向下计数

    2024年02月11日
    浏览(62)
  • 【STM32笔记】STM32的定时器开发基础(二)(基于STM32CubeMX实现定时器中断)

      传统STM32外部中断 的设计步骤:  (1)将GPIO初始化为输入端口。  (2)配置相关I/O引脚与中断线的映射关系。  (3)设置该I/O引脚对印的中断触发条件。  (4)配置NVIC,并使能中断。  (5)编写中断服务函数。   基于STM32CubeMX的外部中断 设计步骤  (1)在STM3

    2024年02月20日
    浏览(62)
  • STM32基本定时器中断

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 提示:这里可以添加本文要记录的大概内容: 定时器有什么用?精准延时,PWM,做一个时钟:年月日,时分秒。时钟最基本的就是1s怎么来? 提示:以下是本篇文章正文内容,下面案例可供参考 1.1如何实

    2024年02月06日
    浏览(48)
  • STM32学习--定时器中断

    目录  概述 一、STM32 通用定时器简介 1.1 STM32定时器定时原理  1.2 STM32 通用定时器相关寄存器简介 1.3 定时器功能描述 1.4计数器模式 二、定时器中断库函数 2.1 步骤总结 2.2 库函数讲解 总结:         这一章,我们将向大家介绍如何使用 STM32F1 系列 的通用定时器。 TIM

    2024年02月02日
    浏览(49)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包