当前位置: 首页 > news >正文

STM32-第六节-TIM定时器-2(输出比较)

 一、输出比较:

1.介绍:

名称:OC(Output Compare),输出比较

电路来源:上一篇文章的通用定时器部分的下半模块。

工作寄存器:CNT计数器,CCR输入捕获/输出比较寄存器(这两功能共用这一个寄存器),此次输出比较功能,是比较这两个寄存器的值的大小,从而使输出实现 置0/1 或,反转 的功能。

功能图输出模式控制器跟据CNT与CCR的值大小,改变oc1REF信号的电平,信号来到CCER模块,CCER通过置0/1来决定是否将输入反转(这个功能称为极性控制),最后信号通过oc1输出。

输出模式
冻结:当CNT=CCR时,REF保持原状态
电平反转:当CNT=CCR时,REF反转
PWM模式:当CNT<CCR时,REF置1,CNT>=CCR,REF置0

 2.PWM:

PWM脉冲宽度调制,在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常用于电机控速,开关电源等。

原理:通过使电机工作一会,停一会,调节工作和停止的比例(即占空比),来控制转速。

参数:频率 = 1/Ts    ;  占空比 = Ton/Ts     ;   精度 = 占空比变化步距

注:一般保证一个周期频率相同,即使占空比不同。

二、实战:PWM驱动呼吸灯

1.硬件介绍:

a.舵机,直流电机

舵机:一个输入IO口,输入PWM信号,根据占空比来决定输出角度。
直流电机:有两个输入电极,电极正接,电机正转,反之反转,即如果输入PWM,会根据占空比                    调节转速(与舵机不同)。

b.TB6612:电机驱动芯片

由于电机为大功率器件,不能由GPIO口直接驱动,故需要驱动电路,此芯片就是集成好的一种。

2.代码:PWM.c

注:GPIO的模式:当由片上外设控制IO时,必须配置为复用模式,本节则为复用推挽输出。

#include "stm32f10x.h"                  // Device header/*** 函    数:PWM初始化* 参    数:无* 返 回 值:无*/
void PWM_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			//开启TIM2的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		//GPIO_Pin_15;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);							//将PA0引脚初始化为复用推挽输出	//受外设控制的引脚,均需要配置为复用模式		/*配置时钟源*/TIM_InternalClockConfig(TIM2);		//选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;					//计数周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;				//预分频器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);             //将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元/*输出比较初始化*/TIM_OCInitTypeDef TIM_OCInitStructure;							//定义结构体变量TIM_OCStructInit(&TIM_OCInitStructure);							//结构体初始化,若结构体没有完整赋值//则最好执行此函数,给结构体所有成员都赋一个默认值//避免结构体初值不确定的问题,然后再更改自己想设置的值TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;				//输出比较模式,选择PWM模式1TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;		//输出极性,选择为高,若选择极性为低,则输出高低电平取反TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	//输出使能TIM_OCInitStructure.TIM_Pulse = 0;								//初始的CCR值TIM_OC1Init(TIM2, &TIM_OCInitStructure);						//将结构体变量交给TIM_OC1Init,配置TIM2的输出比较通道1/*TIM使能*/TIM_Cmd(TIM2, ENABLE);			//使能TIM2,定时器开始运行
}/*** 函    数:PWM设置CCR* 参    数:Compare 要写入的CCR的值,范围:0~100* 返 回 值:无* 注意事项:CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比*           占空比Duty = CCR / (ARR + 1)*/
void PWM_SetCompare1(uint16_t Compare)
{TIM_SetCompare1(TIM2, Compare);		//设置CCR1的值
}

三、实战:PWM驱动舵机

1.接线图:

2.代码:Servo.c

PWM.c修改以下部分

使用通道2的PA1引脚,在GPIO初始化改为GPIO_Pin_1,在输出比较初始化改为TIM_OC2Init,PWM_SetCompare1中改为TIM_SetCompare2,函数名也改成2。

由于舵机角度与PWM信号对应如下,故修改ARR与CCR的值,以满足要求。

最后集成的代码如下:

PWM.c

#include "stm32f10x.h"                  // Device header/*** 函    数:PWM初始化* 参    数:无* 返 回 值:无*/
void PWM_Init(void)
{/*开启时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			//开启TIM2的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);							//将PA1引脚初始化为复用推挽输出	//受外设控制的引脚,均需要配置为复用模式/*配置时钟源*/TIM_InternalClockConfig(TIM2);		//选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟/*时基单元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;				//定义结构体变量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数TIM_TimeBaseInitStructure.TIM_Period = 20000 - 1;				//计数周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;				//预分频器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);             //将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元/*输出比较初始化*/ TIM_OCInitTypeDef TIM_OCInitStructure;							//定义结构体变量TIM_OCStructInit(&TIM_OCInitStructure);                         //结构体初始化,若结构体没有完整赋值//则最好执行此函数,给结构体所有成员都赋一个默认值//避免结构体初值不确定的问题TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;               //输出比较模式,选择PWM模式1TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;       //输出极性,选择为高,若选择极性为低,则输出高低电平取反TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   //输出使能TIM_OCInitStructure.TIM_Pulse = 0;								//初始的CCR值TIM_OC2Init(TIM2, &TIM_OCInitStructure);                        //将结构体变量交给TIM_OC2Init,配置TIM2的输出比较通道2/*TIM使能*/TIM_Cmd(TIM2, ENABLE);			//使能TIM2,定时器开始运行
}/*** 函    数:PWM设置CCR* 参    数:Compare 要写入的CCR的值,范围:0~100* 返 回 值:无* 注意事项:CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比*           占空比Duty = CCR / (ARR + 1)*/
void PWM_SetCompare2(uint16_t Compare)
{TIM_SetCompare2(TIM2, Compare);		//设置CCR2的值
}

Servo.c:根据新的PWM.c封装以下功能

#include "stm32f10x.h"                  // Device header
#include "PWM.h"/*** 函    数:舵机初始化* 参    数:无* 返 回 值:无*/
void Servo_Init(void)
{PWM_Init();									//初始化舵机的底层PWM
}/*** 函    数:舵机设置角度* 参    数:Angle 要设置的舵机角度,范围:0~180* 返 回 值:无*/
void Servo_SetAngle(float Angle)
{PWM_SetCompare2(Angle / 180 * 2000 + 500);	//设置占空比//将角度线性变换,对应到舵机要求的占空比范围上
}

四、实战:驱动直流电机

1.接线图:

2.代码:Motor.c

这里用的是TIM2的CH3对应的PA2引脚,也需要按需求修改PWM.c,这里不再演示,只给出Motor的代码。

#include "stm32f10x.h"                  // Device header
#include "PWM.h"/*** 函    数:直流电机初始化* 参    数:无* 返 回 值:无*/
void Motor_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);		//开启GPIOA的时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);						//将PA4和PA5引脚初始化为推挽输出	PWM_Init();													//初始化直流电机的底层PWM
}/*** 函    数:直流电机设置速度* 参    数:Speed 要设置的速度,范围:-100~100* 返 回 值:无*/
void Motor_SetSpeed(int8_t Speed)
{if (Speed >= 0)							//如果设置正转的速度值{GPIO_SetBits(GPIOA, GPIO_Pin_4);	//PA4置高电平GPIO_ResetBits(GPIOA, GPIO_Pin_5);	//PA5置低电平,设置方向为正转PWM_SetCompare3(Speed);				//PWM设置为速度值}else									//否则,即设置反转的速度值{GPIO_ResetBits(GPIOA, GPIO_Pin_4);	//PA4置低电平GPIO_SetBits(GPIOA, GPIO_Pin_5);	//PA5置高电平,设置方向为反转PWM_SetCompare3(-Speed);			//PWM设置为负的速度值,因为此时速度值为负数,而PWM只能给正数}
}

五、stm32f103c8t6引脚图:

这里放一下引脚图,可以看到之前的PA0复用了TIM2_CH1,等等。

http://www.dtcms.com/a/277565.html

相关文章:

  • DNS协议解析过程
  • 【OpenGL ES】手撕一个mini版的Android native渲染框架
  • Linux系统移植19:根文件系统的构建
  • ReAct论文解读(1)—什么是ReAct?
  • (懒人救星版)CNN_Kriging_NSGA2_Topsis(多模型融合典范)深度学习+SCI热点模型+多目标+熵权法 全网首例,完全原创,早用早发SCI
  • C语言关键字---枚举
  • LeetCode|Day8|1047. 删除字符串中的所有相邻重复项|Python刷题笔记
  • 基于YOLOv3-Tiny 的智能门铃的人体检测模型的实现(中)
  • PS2025最新稳定版下载安装详细图文教程(附安装包)
  • STM32 | HC-SR04 超声波传感器测距
  • 万丈高楼平地起:开发环境搭建与“Hello, World”
  • STM32中EXTI(外部中断)详解
  • Vue中的render()函数
  • word中多行合一功能实现
  • python基础知识pip配置pip.conf文件
  • Tableau破解安装
  • ROS2---NodeOptions
  • 数据预处理
  • 基于requests_html的爬虫实战
  • UE5多人MOBA+GAS 20、添加眩晕
  • 基于Flink的实时开发平台-Dinky
  • 基于Leaflet调用天地图在线API的多层级地名检索实战
  • LeetCode第 458 场周赛题解
  • 复习笔记 35
  • PHP语法高级篇(二):文件处理
  • c++ thread_local
  • Java求职面试:从Spring到微服务的全面挑战
  • 牛客周赛 Round 100
  • Android事件分发机制完整总结
  • CMSIS(Cortex Microcontroller Software Interface Standard)ARM公司为 Cortex-M 系列处理器