stm32电机控制定时器1_STM32通过PWM控制电机速度

    做STM32智能小车的实验中会用到定时器PWM输出,来改变直流电机的转速。分享本文了解如何通过PWM实现对电机速度的控制。

PWM控制电机速度的基本原理

    PWM(Pulse Width Modulation),也就是脉冲宽度调制。

    PWM中有一个比较重要的概念,占空比:是一个脉冲周期内有效电平在整个周期所占的比例。

    为了实现IO口上电压的持续性变化,可以调节PWM的占空比。这也能够使外设的功率进行持续性变化,最终控制直流电机转速的快慢。如何调节PWM波形的输出就是重点。

d713038a536da20e25ae5bc57b8b20e1.png

    上图中的ARR是我们给定时器的一个预装载值,CCRx的上下变化是产生PWM波的关键。我们假设ARR大于CCRx的部分输出为高电平(即t1-t2、t3-t4、t5-t6),ARR小于CCRx的部分输出为低电平(即0-t1、t2-t3、t4-t5),则改变CCRx的值就能改变输出PWM的占空比。因此,想要控制PWM的输出波形,重要的就是如何设置ARR与CCRx这两个寄存器的值了。

STM32定时器中断

    为了便于理解接下来关于PWM应用的内容,先插一段定时器中断的知识。

    产生定时中断是定时器的用法之一,与定时器用来进行PWM输出和输入捕获相比,定时器中断更容易理解、掌握。原理简介
    使用通用定时器进行中断的原理,其实和开发板Systick定时器进行中断延时很相似(Stm32入门——Systick定时器),即:用psc(预分频系数)设置好定时器时钟后,arr(预装载值)在每个时钟周期内减1,当arr减为0时触发中断然后进入中断处理程序进行中断处理。以下代码为例:

void TIM3_Int_Init(u16 arr,u16 psc){  RCC->APB1ENR|=1<<1;  //TIM3时钟使能       TIM3->ARR=arr;    //设定计数器自动重装值   TIM3->PSC=psc;    //预分频器设置  TIM3->DIER|=1<<0;   //允许更新中断          TIM3->CR1|=0x01;    //使能定时器3    MY_NVIC_Init(1,3,TIM3_IRQn,2);//抢占1,子优先级3,组2                   }
RCC->APB1ENR|=1<<1

    解释一下上面这行代码,由于定时器3(TIM3)是挂在APB1上的外设,所以要打开APB1,这里的预分频器值psc是来设置TIM3的时钟频率的,如果系统时钟(SYSTICK)频率为72MHz、psc为7199,则TIM3的时钟频率就为:

72MHz/(7199+1)Hz = 10KHz    //这里的“+1”是手册中规定的。

    10KHz是什 么意思呢?就是一秒钟会产生10K个周期,那么一个周期的时间长度就是1/10KHz,如果你想将定时器中断的时间间隔设置为0.5秒,那么你将arr设置为5000即可,因为arr每减1就需要一个周期的时间,减5000次就经过了5000*(1/10KHz)=0.5秒。

TIM3->DIER|=1<<0

    再解释下上面这一行,设置允许更新中断,即arr减到0以后可以触发更新中断,还有其他类型的中断。

MY_NVIC_Init(1,3,TIM3_IRQn,2);//抢占1,子优先级3,组2

    看上面这行代码,中断优先级有抢占优先级和响应(即子优先级)优先级两种,抢占优先级即:若程序1正在使用CPU,这时如果程序2要求使用CPU,并且程序2的抢占优先级高,则CPU被程序2抢占;若两者抢占优先级相同,则就算程序2的响应优先级高于程序1,CPU也不能被抢占;若程序1正在使用CPU,程序2和程序3的抢占优先级等于或低于程序1,且程序2的响应优先级高于程序三,则待CPU空出后,程序2先运行,程序3最后运行。TIM3_IRQn是指定将要运行的中断处理程序号。“组2”是设置中断优先级分组的,这是因为寄存器提供了四位来设置优先级,组2代表的是前两位给抢占优先级,后两位给响应优先级。

PWM模式、有效电平

    前面介绍完中断,再说一下PWM工作原理。

    假设上图中ARR大于CCRx时输出为高电平,ARR小于CCRx时输出为低电平,但在实际运用中可能并非如此,有可能是相反的情况——ARR大于CCRx时输出为低电平,ARR小于CCRx时输出为高电平,至于到底是哪种情况,还要看PWM是哪种模式、有效电平又设置的是何种极性了。

  • 模式1:ARR小于CCRx时输出为“有效”电平,ARR大于CCRx时输出为“无效”电平。

  • 模式2:ARR小于CCRx时输出为“无效”电平,ARR大于CCRx时输出为“有效”电平。

    这里说的是“有效”和“无效”,而不是“高”和“低”,也就是说有效电平可高可低,并非一定就是高电平。PWM模式、效电平极性,需要程序员自己配置相关的寄存器来实现。通过下面的代码来讲解。

TIM1_PWM_Init(899,0);//不分频。PWM频率=72000/(899+1)=80Khz

    上一小节讲过关于定时器参数的设置。使用定时器1的通道1来输出一路PWM波,这里的899设置的就是ARR的值,至于那个0是用来设置TIM1的频率的,不分频就代表TIM1的时钟频率和系统时钟相同,这里假设为72MHz。

void TIM1_PWM_Init(u16 arr,u16 psc){                  //此部分需手动修改IO口设置  RCC->APB2ENR|=1<<11;   //TIM1时钟使能      GPIOA->CRH&=0XFFFFFFF0;  //PA8清除之前的设置  GPIOA->CRH|=0X0000000B;  //复用功能输出     TIM1->ARR=arr;      //设定计数器自动重装值   TIM1->PSC=psc;      //预分频器设置    TIM1->CCMR1|=7<<4;    //CH1 PWM2模式       TIM1->CCMR1|=1<<3;     //CH1预装载使能      TIM1->CCER|=0<<1;     //OC1 输出使能       //TIM1->CCER|=1<<1;      TIM1->BDTR|=1<<15;     //MOE 主输出使能       TIM1->CR1=0x0080;     //ARPE使能   TIM1->CR1|=0x01;      //使能定时器1                       }

    下文具体分析上面的代码。

    前面4-6行是用来配置GPIO口的。

TIM1->ARR=arr; //设定计数器自动重装值TIM1->PSC=psc; //预分频器设置

    这两行就是我上门提到的设置定时器的频率和重装载值。

TIM1->CCMR1|=7<<4; //CH1 PWM2模式TIM1->CCMR1|=1<<3; //CH1预装载使能TIM1->CCER|=0<<1; //OC1 输出使能

    这三行是用来设置PWM输出模式和设置通道的,通道是什么呢?简单地讲就是输出PWM波的GPIO口,代码一开始不是设置了PA8这个GPIO口嘛,这个PA8就是通道1。使用通道的话要先进行输入输出方向、通道使能的设置。

TIM1->CCER|=1<<1;

    这行代码是用来设置“有效电平”极性的,根据手册,当TIM1->CCER[1]这位置1时,有效电平为低电平,置0时有效电平为高电平,而默认情况下置0。

TIM1->BDTR|=1<<15; //MOE 主输出使能

    这行代码只要对高级定时器进行设置,普通定时器无需设置。

TIM1->CR1=0x0080; //ARPE使能

    这行代码是用来使能ARPE,ARPE是什么呢,就是当它被置1时,你自己设置的CCRx会立即生效,如果它被置为0,那么你自己设置的CCRx值不会立即生效(可能之前ARPE已经有值了),而是当之前设置的CCRx生效后才会使用你最新设置的CCRx值。

上面的代码里没有对CCRx进行设置,这是因为CCRx常常是一个变化的值,你可以在主函数中用一个for循环+if判断语句对它进行++或–的操作,从而达到连续改变CCRx值得目的,例如:

for(i=0;i<300;i++){  TIM1->CCR1=i;  if(i==300){    i=0;  }}

    PWM波的周期是由定时器时钟频率和预装载值两者决定的,预装载值就是ARR。

    预装载值PSC设置为899,那么,当定时器的当前值val从0增加到899时,一共经过了900个时钟周期,这900个时钟周期会产生一个PWM波形,也就是说900个定时器时钟周期才相当于一个PWM周期,那么PWM的频率就为72MHz/900=80KHz,周期为1/80KHz。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283198.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

走向无后端的系统开发实践:CRUD自动化与强约定的REST接口

2019独角兽企业重金招聘Python工程师标准>>> ttp://mp.weixin.qq.com/s?__bizMzAwMDU1MTE1OQ&idx1&mid2653548079&sn2377b625db58b2ea93c3ef2d87e4c395 转载于:https://my.oschina.net/yunjie/blog/806130

jsp连接数据库

有关web开发……其中的关键步骤&#xff1a; request.setCharacterEncoding("utf-8"); //获取用户名 String uNamerequest.getParameter("username"); //获取密码 String pwrequest.getParameter("password"); //编写sql语句 String sql"se…

C# 二十年语法变迁之 C#9参考

C# 二十年语法变迁之 C# 9参考自从 C# 于 2000 年推出以来&#xff0c;该语言的规模已经大大增加&#xff0c;我不确定任何人是否有可能在任何时候都对每一种语言特性都有深入的了解。因此&#xff0c;我想写一系列快速参考文章&#xff0c;总结自 C# 2.0 以来所有主要的新语言…

mysql char varchar 性能_Mysql小细节:varchar与char在性能上的特点

varchar与char的一个主要区别是存储方式的不同varchar 是变长存储占用的存储空间 存储内容实际大小 长度记录位char 是定长存储占用的存储空间 字段声明的宽度存储方式对性能是有影响的例如分别使用 varchar(10) 与 varchar(255) 定义一个字段&#xff0c;实际存储的字符串为…

Dubbo源码解析之Zookeeper连接

2019独角兽企业重金招聘Python工程师标准>>> 注&#xff1a;Dubbo的版本是2.5.7。 图1 RegistryProtocol的export时序图 注册中心有Zookeeper、Redis、Dubbo&#xff0c;分别对应ZookeeperRegistry、RedisRegistry、MulticastRegistry。 连接Dubbo的客户端有俩种&am…

推翻自己和过往,重学自定义View

http://blog.csdn.net/lfdfhl/article/details/51671038 深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架&#xff08;1&#xff09;— 核心基础 Android多分辨率适配框架&#xff08;2&#xff09;— 原理剖析 Android多分辨率…

SHELL 脚本小技巧

脚本很简单&#xff0c;直接上功能介绍及脚本&#xff0c;可以做模板使用&#xff1a; 记录日志,记录脚本开始执行时间、结束时间usage 函数&#xff0c;脚本需接参数执行&#xff0c;避免误执行&#xff0c;告诉用户&#xff0c;这个脚本的使用方法加锁&#xff0c;创建锁文件…

WinForm(十)项目框架结构

看到下面的项目结构&#xff0c;是否曾经相识&#xff1f;不要笑&#xff0c;这也是一种项目结构&#xff0c;极简主义。项目结构没有对错&#xff0c;合适就好&#xff0c;但也要有几个要求&#xff0c;至少要做到结构明确&#xff0c;清晰&#xff0c;当然上图的结构清晰&…

mysql索引有哪些了解_Mysql索引(简单了解)

Mysql的存储引擎&#xff0c;可以针对不同的表使用不同的存储引擎MyISAM&#xff1a;插入&#xff0c;查血速度快&#xff0c;但是不支持事物&#xff0c;所以适用于数据仓库&#xff0c;Web等InnoDB&#xff1a;支持事物&#xff0c;所以适合于事物型数据库Memory&#xff1a;…

Elasticsearch5.X的java配置

pom: <properties><elasticsearch.version>5.4.1</elasticsearch.version><transport.version>5.4.1</transport.version></properties><!--elasticsearch相关依赖--><dependency><groupId>org.elasticsearch</group…

使用Spring发送带附件的电子邮件(站内和站外传送)

1.使用Spring发送带附件的电子邮件 <?xml version"1.0" encoding"UTF-8"?> <beansxmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:p"http://www.spr…

vmware 克隆后Linux没有eth网卡只有lo

想试着在虚拟机上搭下主从&#xff0c;&#xff0c;&#xff0c;结果&#xff0c;克隆出来的虚拟机没有网卡。。。只有lo 于是跟着别人的来添加一个网卡 第一步&#xff1a;打开克隆的虚拟机 第二步&#xff1a; 第三步 第四步&#xff1a; 最后&#xff1a; 之后执行reboot重启…

聊一聊 C++ 中的 namespace

一&#xff1a;背景 相信大家在分析 dump 时&#xff0c;经常会看到 WKS 和 SRV 这样的字眼&#xff0c;如下代码所示&#xff1a;00007ffa778a07b8 coreclr!WKS::gc_heap::segment_standby_list 0x0000000000000000 00007ffa778a3870 coreclr!WKS::qpf 0x989680 00007ffa778…

mysql模糊查询后分页_jsp模糊查询后的数据进行分页,但点击下一页后就查询全部的了...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼String path request.getContextPath();String basePath request.getScheme() "://" request.getServerName() ":" request.getServerPort() path "/";%>信息表#container {width: 500px;}…

会议会展活动从业技能之会销流程的16个环节

会议营销是透过相对大型活动来实现销售。会议营销是细节营销&#xff0c;一般操作流程有会前、会中、会后三个阶段共计16个环节&#xff0c;每个环节都做到位了&#xff0c;衔接好了&#xff0c;会议营销的最终效果就会得到保证。一般而言&#xff0c;会议营销分为会前营销、会…

haproxy详细介绍

Haproxy是既可以工作在7层也能工作在4层的反代工具.Haproxy的功能:路由HTTP请求到后端服务器,基于cookie作会话绑定.能够将多个请求反代至后端主机完成负载均衡的效果.主服务器失败时能自动切换到备服务器上.接受特殊的端口连接完成服务监控拒绝新连接时不会关闭已经连接的请求…

SQL JOIN连接分类[转]

1、内联接&#xff08;典型的联接运算&#xff0c;使用像 或 <> 之类的比较运算符&#xff09;&#xff1b;包括相等联接和自然联接&#xff1b; 内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行&#xff1b; 2、外联接。外联接可以是左向外联接、右向…

《ASP.NET Core 6框架揭秘》实例演示[17]:利用IHttpClientFactory工厂来创建HttpClient

在一个采用依赖注入框架的应用中&#xff0c;我们一般不太推荐利用手工创建的HttpClient对象来进行HTTP调用&#xff0c;使用的HttpClient对象最好利用注入的IHttpClientFactory工厂来创建。前者引起的问题&#xff0c;以及后者带来的好处&#xff0c;将通过如下这几个演示程序…

Hadoop部署方式-高可用集群部署(High Availability)

Hadoop部署方式-高可用集群部署(High Availability) 作者&#xff1a;尹正杰 版权声明&#xff1a;原创作品&#xff0c;谢绝转载&#xff01;否则将追究法律责任。 本篇博客的高可用集群是建立在完全分布式基础之上的&#xff0c;详情请参考&#xff1a;https://www.cnblogs.c…

sybase 连接mysql_如何连接到Sybase SQL Anywhere数据库

Sybase SQL Anywhere数据库具有许多非常有用的功能&#xff0c;与竞争对手相比&#xff0c;它具有很高的竞争力。首先&#xff0c;它允许您处理大量数据。其次&#xff0c;它具有很高的生产率&#xff0c;也就是说&#xff0c;可以快速提供大量数据。第三&#xff0c;它需要最少…