【江科大】STM32:(超级详细)定时器输出比较
文章目录
- 输出比较单元
- 特点
- 高级定时器:均有4个通道
- PWM简介
- PWM(Pulse Width Modulation)脉冲宽度调制
- 输出比较通道
- PWM基本结构
- 基本定时器
- 参数计算
- 捕获/比较通道的输出部分
- 详细介绍如下:
- 舵机介绍
- 硬件电路
- 直流电机介绍:
- 直流电机驱动代码
- 输出比较(库函数)
输出比较单元
- 名词解释
IC input capture 输入捕获
OC outpucompare 输出比较
CC capture compare 输入捕获和输出比较的单元
OC(Output Compare)输出比较 :用来输出PWM波形
特点
-
输出比较可以通过比较CNT(计数器)与CCR(捕获/比较)寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。
-
每个高级定时器和通用定时器都拥有4个输出比较通道
-
高级定时器的前3个通道额外拥有死区生成和互补输出的功能(用于驱动三相无刷电机)
通用定时器:均有4个通道
高级定时器:均有4个通道
PWM简介
PWM(Pulse Width Modulation)脉冲宽度调制
- 必须是在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域
PWM参数:
频率 = 1 / TS
占空比 = TON / TS
分辨率 = 占空比变化步距
(PWM的频率在几千到几十KHZ就已经很快了)(分辨率 表示占空比的精细程度)
- TON:高电平的时间
- TS:一个周期的时间
(频率 = 1 / TS 可以看出周期越大,那么频率就越小,就越平稳。
占空比 = TON / TS)
TON/TS:高电平相对整个周期的比例
如果TON = 20% 那么低电平就是80%,占空比越大,等效的模拟电压就越接近于高电平。
(PWM调光,通过高频点亮熄灭,点亮熄灭来实现对灯光强弱的控制,只要闪的够快就发现不了是正常的还是没有的)
原因:LED熄灭时,由于人眼的余辉和视觉暂留现象,LED不会立刻熄灭,过一小段才会熄灭,电机也是因为惯性过一会才会停下来
输出比较通道
极性选择:就是选择要不要把高低电平反转一下
PWM基本结构
占空比和CCR值有关
基本定时器
参数计算
- PWM输出的通道口时CH1
- 根据引脚定义表,得出GPIO口时PA0
- 输出模式选用复用推挽输出,原因是采用定时器来进行输出控制
- CCR的值
根据PWM频率
Freq = CK_PSC / (PSC + 1) / (ARR + 1) :
72MHZ/(PSC+1)/(ARR+1) = 1000
PSC+1 =72000000/1000000=720HZ
PWM占空比:
Duty = CCR / (ARR + 1) CCR/(ARR+1) = 50% --》 CCR = 50
PWM分辨率:
Reso = 1 / (ARR + 1) 1/(ARR+1) = 1% --》ARR+1 = 100
分辨率是自己给的
捕获/比较通道的输出部分
对于普通的推挽输出:引脚的控制权来自于输出数据寄存器,来进行输出控制
而想要定时器来控制引脚就需要使用复用开漏推挽输出。(定时器属于片上外设)
- 重复次数计数器:
实现每隔几个周期再更新一次。之前是,每个周期都更新,对更新信号再分频 - DTG:死区生成电路,防止电流直通
- RK刹车输入功能:给电机驱动提供安全保证。如内部时钟失效,控制电路会自动切断电路
- AFIO:端口重映射
如果要重定义某个端口:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//给AFIO使能
GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE); //重映射 把CH1的PA0换到PA15
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable ,ENABLE);//关闭PA15的调试端口的功能
详细介绍如下:
- RCC 把GPIO,TIM外设的时钟打开
- 配置时基单元
- 配置输出比较单元,时钟源选择
- 配置输出比较单元,CCR的值,输出比较模式,极性选择,输出使能
- 配置GPIO ,配置为复用推免
- 运行控制,启动计数器
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//给TIM2使能RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//给GPIO使能GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; //由于定时器属于片上外设,所以采用复用推挽输出,GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; //根据引脚表的出CH_1所在引脚时PA0GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);TIM_InternalClockConfig(TIM2); //选择内部时钟 给时基单元提供时钟//时基单元TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; //每一个时钟后面都会加一个滤波器,//作用就是为是信号更加稳定,使用的采样的方式,//在输入的脉冲中采样,按照n/f,因此采样系数越大,延迟越大TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //计数方式,递增TIM_TimeBaseInitStruct.TIM_Period = 100-1; //ARR =100 TIM_TimeBaseInitStruct.TIM_Prescaler = 720-1; // psc = 720//预分频器,72MHZ进行7200分频 ,//72000/7200 = 10KHZ 1ms = 1KHZ //10KHZ下记10000个数 10000/10000HZ = 1S// f = 1/t 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_OCNIdleState = ; //带N的都是高级定时器才用的//TIM_OCInitStruct.TIM_OCNPolarity = ;TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //输出比较极性//TIM_OCInitStruct.TIM_OutputNState = ;TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; //使能输出状态TIM_OCInitStruct.TIM_Pulse = 50;//CCR的值TIM_OC1Init(TIM2,&TIM_OCInitStruct); //运行控制,所有的模块配置完毕,启动时基单元TIM_Cmd(TIM2,ENABLE);//如果要使用高级定时器,就需要把TIM2改为TIM1,那么结构原来用不到的成员。就需要用到,这些成员又没有赋值,//这个时候就会出现奇怪的问题,如果把初始化函数放在的程序第一行没有问题,初始化函数前面出现了其他的代码,那么4路PWM就会有3路不能输出。这竟然和初始化函数在那一行有关。//原因是,没有给结构体配置完整,也没有给结构体赋初始值。所以要用到structInit()函数,给结构体赋初始值。
舵机介绍
舵机是一种根据输入PWM信号占空比来控制输出角度的装置
输入PWM(可当作一种输出协议)信号要求:周期为20ms,高电平宽度为0.5ms~2.5ms
- PWM输入到控制板,给控制板一个指定的目标角度,然后这个电位器检测当前的输出角度,如果大于目标角度,电机就会反转
硬件电路
void Servo_Init(void)
{PWM_Init();
}void Servo_SetAngle(float Angle)
{//0 500 //180 2500 度数 PWM_SetCompare2(Angle / 180 * 2000 + 500);
}
PWM驱动舵机
直流电机介绍:
直流电机驱动代码
1.RCC使能GPIO
2.选择时钟,给定时器单元使能
3.配置时基单元(也就是计数模块)
4.配置输出比较模块
5.启动时基单元
6.逻辑函数
选用的是通用定时器TIM2,
由于直流电机上的PWMA连接的是PA2口,根据引脚定义表。PA2对应的时钟通道是TIM2_CH3.
所以在选择输出比较通道时,选择初始化3通道。TIM_OC3Init(TIM2,&TIM_OCInitStruct);
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); PWM_Init();
}void Motor_SetSpeed(uint8_t speed)
{if(speed >= 0){GPIO_SetBits(GPIOA,GPIO_Pin_4); //给端口4给高 5给低 正转GPIO_ResetBits(GPIOA,GPIO_Pin_5);PWM_SetCompare3(speed); //给PWM设置CCR的值 捕获比较值,根据不同CCR的值,得到PWM波也不同,输出的速度自然不同} else{GPIO_ResetBits(GPIOA,GPIO_Pin_4); //给端口4给低 5给高 反转GPIO_SetBits(GPIOA,GPIO_Pin_5);PWM_SetCompare3(-speed);}
}
输出比较(库函数)
//配置输出比较单元
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OCStructInit(TIM_OCInitTypeDef* TIM_OCInitStruct);//配置强制输出模式
//如果暂停输出波形并且强制输出高/低电平,强制设置高电平,和设置100%占空比是一样的
void TIM_ForcedOC1Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC2Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC3Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
void TIM_ForcedOC4Config(TIM_TypeDef* TIMx, uint16_t TIM_ForcedAction);
//用来单独设置输出比较的极性,带N的就是高级定时器,互补通道的配置,OC4没有互补通道,所以没有OC4N的函数。
void TIM_OC1PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC1NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC2PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC2NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC3PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
void TIM_OC3NPolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCNPolarity);
void TIM_OC4PolarityConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);
//用来单独修改输出使能函数
void TIM_CCxCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCx);
void TIM_CCxNCmd(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_CCxN);
//单独修改选择输出比较模式
void TIM_SelectOCxM(TIM_TypeDef* TIMx, uint16_t TIM_Channel, uint16_t TIM_OCMode);
//用来单独修改CCR寄存器值的函数 ,更改占空比 (掌握)
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
//这个函数仅再高级定时器使用!!!!!!,在使用高级定时器输出PWM时,需要调用这个函数使能主输出,否则PWM将不再正常输出
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState);
相关文章:

【江科大】STM32:(超级详细)定时器输出比较
文章目录 输出比较单元特点 高级定时器:均有4个通道 PWM简介PWM(Pulse Width Modulation)脉冲宽度调制输出比较通道PWM基本结构基本定时器 参数计算捕获/比较通道的输出部分详细介绍如下: 舵机介绍硬件电路 直流电机介绍ÿ…...
Go 复合数据类型
1. 数组(array)(OK) 数组数组的概念数组是具有固定长度且拥有零个或多个相同数据类型元素的序列 i. 元素的数据类型相同 ii. 长度固定的序列 iii. 零个或多个元素的序列 与 slice 对比 由于数组的长度固定,所以在 G…...

Redis(01)——常用指令
基础指令 select 数字:切换到其他数据库flushdb:清空当前数据库flushall:清空所有数据库dbsize:查看数据库大小exists key1[key2 …]:判断当前的key是否存在keys *:查看所有的keyexpire key 时间ÿ…...

基本语法和 package 与 jar
3.基本语法 1.输入输出 // 导入 java.util 包中的 Scanner 类 import java.util.Scanner;// 定义名为 ScannerExample 的公共类 public class ScannerExample {// 主方法,程序的入口点public static void main(String[] args) {// 创建 Scanner 对象,用…...

本地读取Excel文件并进行数据压缩传递到服务器
在项目开发过程中,读取excel文件,可能存在几百或几百万条数据内容,那么对于大型文件来说,我们应该如何思考对于大型文件的读取操作以及性能的注意事项。 类库:Papa Parse - Powerful CSV Parser for JavaScript 第一步…...

【开源】基于JAVA的停车场收费系统
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 停车位模块2.2 车辆模块2.3 停车收费模块2.4 IC卡模块2.5 IC卡挂失模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 停车场表3.2.2 车辆表3.2.3 停车收费表3.2.4 IC 卡表3.2.5 IC 卡挂失表 四、系统实现五、核心代码…...

基于java+Springboot操作系统教学交流平台详细设计实现
基于javaSpringboot操作系统教学交流平台详细设计实现 🍅 作者主页 央顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各种定制系统…...

Nginx 基础使用
目录结构 进入Nginx的主目录我们可以看到这些文件夹 client_body_temp conf fastcgi_temp html logs proxy_temp sbin scgi_temp uwsgi_temp其中这几个文件夹在刚安装后是没有的,主要用来存放运行过程中的临时文件 client_body_temp fastcgi_temp proxy_temp scg…...

JavaEE:多线程(2):线程状态,线程安全
目录 线程状态 线程安全 线程不安全 加锁 互斥性 可重入 死锁 死锁的解决方法 Java标准库中线程安全类 内存可见性引起的线程安全问题 等待和通知机制 线程饿死 wait notify 线程状态 就绪:线程随时可以去CPU上执行,也包含在CPU上执行的…...

Flutter 自定义AppBar实现滚动渐变
1、使用ListView实现上下滚动。 2、使用Stack:允许将其子部件放在彼此的顶部,第一个子部件将放置在底部。所以AppBar,写在ListView下面。 3、MediaQuery.removePadding:当使用ListView的时候发现,顶部有块默认的Padd…...

编程语言MoonBit新增矩阵函数的语法糖
MoonBit更新 1. 新增矩阵函数的语法糖 新增矩阵函数的语法糖,用于方便地定义局部函数和具有模式匹配的匿名函数: fn init {fn boolean_or { // 带有模式匹配的局部函数true, _ > true_, true > true_, _ > false}fn apply(f, x) {f(x)}le…...

Angular:跨域请求携带 cookie
新建拦截器,设置 XMLHttpRequest:withCredentials 属性 1. 新建文件夹 http-interceptors 该文件夹下可有多个不同用途的拦截器2. 新建拦截器 common.interceptor.ts import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from "an…...

【C++】list容器迭代器的模拟实现
list容器内部基本都是链表形式实现,这里的迭代器实现的逻辑需要注意C语言中指针的转换。 list容器如同数据结构中的队列,通常用链式结构进行存储。在这个容器中,我们可以模仿系统的逻辑,在头结点后设置一个“ 哨兵 ”,…...

Docker镜像操作
镜像名称 镜名称一般分两部分组成:[repository]:[tag]。 在没有指定tag时,默认是latest,代表最新版本的镜像。 这里的mysql就是repository,5.7就是tag,合一起就是镜像名称,代表5.7版本的MySQL镜像。 镜像…...

【Java-框架-SpringSecurity】单点登录(认证和授权)- 随笔
项目文件; 【1】 【2】 【3】 【4】 【5】 【6】 【7】 【8】...

大数据开发之Scala
第 1 章:scala入门 1.1 概述 scala将面向对象和函数式编程结合成一种简洁的高级语言 特点 1、scala和java一样属于jvm语言,使用时都需要先编译为class字节码文件,并且scala能够直接调用java的类库 2、scala支持两种编程范式面向对象和函数式…...

数字时代的大对决
数字时代如今正酝酿着一场大对决,浏览器、艺术品、音乐平台和社交通信的巅峰之战正在发生。Brave、Yuga Labs、Audius和Discord分别对标着Chrome、Disney、Spotify和WhatsApp,这场数字时代的较量不仅涉及浏览器、艺术品、音乐平台和社交通信的竞争&#…...

网络防御保护1
网络防御保护 第一章 网络安全概述 网络安全(Cyber Security)是指网络系统的硬件、软件及其系统中的数据受到保护,不因偶然的或者恶意的原因而遭受到破坏、更改、泄露,系统连续可靠正常地运行,网络服务不中断 随着数…...

解决Windows下Goland的Terminal设置为Git Bash失败
路径不要选错了: 如果还是不行: 把bash路径加进去试试 goland设置Terminal...

x-cmd pkg | jq - 命令行 JSON 处理器
目录 简介首次用户功能特点类似工具进一步探索 简介 jq 是轻量级的 JSON 处理工具,由 Stephen Dolan 于 2012 年使用 C 语言开发。 它的功能极为强大,语法简洁,可以灵活高效地完成从 JSON 数据中提取特定字段、过滤和排序数据、执行复杂的转…...

网络安全笔记
一、简介 网络安全是指通过管理和技术手段保护网络系统免受未经授权的访问、数据泄露、破坏或摧毁。随着互联网的普及,网络安全问题日益突出,对个人和企业信息安全构成了严重威胁。因此,了解和掌握网络安全知识对于保护个人信息和企业数据至…...

php基础学习之代码框架
一,标记 脚本标记(已弃用):<script language"php"> php代码 </script> 标准标记:<?php php代码 ?> 二,基础输出语句 不是函数,…...

LCD-LMD-PSO-ELM的电能质量分类,LCD特征提取,LMD特征提取,粒子群算法优化极限学习机
目录 背影 极限学习机 LCD-LMD-PSO-ELM的电能质量分类,LCD特征提取,LMD特征提取,粒子群算法优化极限学习机 主要参数 MATLAB代码 效果图 结果分析 展望 完整代码下载链接:LCD-LMD-PSO-ELM的电能质量分类,LCD特征提取,LMD特征提取,粒子群算法优化极限学习机资源-CSDN文库…...

【ARMv8M Cortex-M33 系列 7 -- RA4M2 移植 RT-Thread 问题总结】
请阅读【嵌入式开发学习必备专栏 】 文章目录 问题小结栈未对齐 经过几天的调试,成功将rt-thead 移植到 RA4M2(Cortex-M33 核)上,thread 和 shell 命令已经都成功支持。 问题小结 在完成 rt-thread 代码 Makefile 编译系统搭建…...

分享 GitHub 上的敏感词汇工具类:sensitive-word
😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~ 🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Mi…...

洛谷P1319 压缩技术(C语言)
这样一道入门题目,本来可以用for循环直接操作,但作者异想天开(xian de dan teng)地把所有数据登记在一个数组里面,然后再统一按格式输出。也就是定义一个数组Map,大小为n成n,然后按照输入数据,把Map中每一个…...

HQL,SQL刷题简单查询,基础,尚硅谷
今天刷SQL简单查询,大家有兴趣可以刷一下 目录 相关表数据: 题目及思路解析: 总结归纳: 知识补充: 关于LIKE操作符/运算符 LIKE其他使用场景包括 LIKE模糊匹配情况 相关表数据: 1、student_info表 2、sc…...

MSG3D
论文在stgcn与sta-lstm基础上做的。下面讲一下里面的方法: 1.准备工作 符号。这里是对符号进行解释。 一个人体骨骼图被记为G(v,E) 图卷积: 图卷积定义 考虑一种常用于处理图像的标准卷积神经网络 (CNN)。输入是像素网格。每个像素都有一个数据值向…...

kafka(二)——常用命令
常用脚本 kafka执行脚本默认在安装的bin目录下,本文中示例均基于bin目录执行。 #查询topic状态,新建,删除,扩容 kafka-topics.sh #查看,修改kafka配置 kafka-configs.sh #配置,查看kafka集群鉴权信息 kaf…...

使用Flink处理Kafka中的数据
目录 使用Flink处理Kafka中的数据 前提: 一, 使用Flink消费Kafka中ProduceRecord主题的数据 具体代码为(scala) 执行结果 二, 使用Flink消费Kafka中ChangeRecord主题的数据 具体代码(scala) 具体执行代码① 重要逻…...