STM32入门学习之定时器PWM输出

news2024/11/24 19:52:39

1.脉冲宽度调制PWM(Pulse Width Modulation)是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。PWM可以理解为高低电平的占空比,即输出高电平时间与低电平时间的比值。PWM的应用是否广泛,比如在步进电机的控制中,可以通过PWM来控制电机的速度。PWM的原理图如下所示。

 如图中所示,当CNT的值小于ARR时,I/O输出低电平;当CNT的值大于等于ARR时,I/O输出高电平。当CNT的值等于ARR时,CNT的值归零,然后重新向上计数(向上或向下计数可以自行设置)。CNT(TIMx_CNT寄存器是定时器的计数器,该寄存器存储了当前定时器的计数值。)。因此,通过修改自动装载寄存器ARR的值,就可以改变PWM的输出频率。

简单来说,就是设置了自动装载寄存器ARR的值,然后定时器计数CNT,根据CNT与ARR的大小关系,使I/O输出不同的电平。

2.相关寄存器介绍:(寄存器TIMx_CR1、TIMx_PSC、TIMx_ARR、TIMx_SR的介绍请查看:CSDN)

(1)捕获比较模式寄存器(TIMx_CCR1/2):TIMx_CCR1、TIMx_CCR2。

如图所示,第一行为输出时的设置,第二行是输入时的配置。

OCxM是模式设置位,由3位组成,可以控制7种模式。使用PWM模式时,必须设置为110/111。这两种模式的区别是输出的电平极性相反。

CCxS是通道方向的设置位(输入/输出),默认为0,即作为输出使用。

(2)捕获比较使能寄存器(TIMx_CCER):该寄存器控制着各个输入输出通道的开关。

本次实验中只使用到了CC1E位(输入/输出使能位),需要设置为1。

(3)捕获/比较寄存器(TIMx_CCR1~4):TIMx_CCR1、TIMx_CCR2、TIMx_CCR3、TIMx_CCR4。

 在输出模式下,该寄存器的值与定时器的计数值CNT比较,并根据结果使I/O输出高低电平。

(4)刹车和死区寄存器(TIMx_BDTR):该寄存器只有高级定时器需要配置,普通定时器不需要配置此寄存器。本次实验中,实验的普通定时器TIM1,不需要配置此定时器。

如果想要高级定时器正常输出PWM,MOR为必须设置为1。

3.设计思路:首先,使能相应的时钟。然后,配置PA8为复用输出(TIM1_CH1的是和PA8复用的。同时,PA8外接了LED)。其次,设置TIM1的ARR和PSC。最后设置TIM1_CH1的PWM模式和通道方向,使能TIM1的CH1输出。

4.代码:

(1)delay:

#ifndef __DELAY_H
#define __DELAY_H

#include "stm32f10x.h"

void delay_us(uint32_t us);									//ÑÓʱ΢Ãë
void delay_ms(uint32_t ms);									//ÑÓʱºÁÃë

#endif
#include "delay.h"

void delay_us(uint32_t us)
{
	uint32_t i;
	
	//1.Ñ¡ÔñHCLKʱÖÓ£¬²¢ÉèÖõδðʱÖÓ¼ÆÊýÖµ
	SysTick_Config(72);
	
	for(i = 0;i < us;i++)
	{
		while(!((SysTick->CTRL) & (1 << 16)));		//µÈ´ý¼ÆÊýÍê³É
	}
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;	//Ñ¡ÔñSTCLKʱÖÓÔ´£¬²¢Ê§Äܶ¨Ê±Æ÷
}

void delay_ms(uint32_t ms)
{
	uint32_t i;
	//1.Ñ¡ÔñHCLKʱÖÓÔ´£¬²¢ÉèÖõδðʱÖÓ¼ÆÊýÖµ
	SysTick_Config(72000);
	
	for(i = 0;i < ms;i++)
	{
		while(!((SysTick->CTRL) & (1 << 16)));		//µÈ´ý¼ÆÊýÍê³É
	}
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;	//Ñ¡ÔñSTCLKʱÖÓÔ´£¬²¢Ê§Äܶ¨Ê±Æ÷
}

(2)led:

#ifndef __LED_H
#define	__LED_H

#include "stm32f10x.h"

void LED_Init(void);

#endif

#include "led.h"

	void LED_Init(void)
{
	//¶¨Òå¶Ë¿ÚµÄ½á¹¹Ìå:
	GPIO_InitTypeDef GPIO_InitStruct;
	
	//1.ʹÄÜʱÖÓ£º
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOA,ENABLE);
	
	//2.ÅäÖö˿ڽṹÌåµÄÏà¹ØÐÅÏ¢£º£¨LED1£©
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOD,&GPIO_InitStruct);
	
	//ÅäÖÃLED0£º
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//³õʼʱ½«LEDµÄ¶Ë¿Ú¶¼ÖÃΪ1£¬¼´Ï¨Ãð
	GPIO_SetBits(GPIOA,GPIO_Pin_8);
	GPIO_SetBits(GPIOD,GPIO_Pin_2);
}

(3)pwm:

#ifndef __PWM_H
#define __PWM_H

#include "stm32f10x.h"

void PWM_Init(u16 arr,u16 psc);

#endif

#include "pwm.h"

/*±¾´ÎʵÑéÖÐÊÇʹÓÃTIM1Êä³öPWM£¬TIM1ʹÓÃÐèÒª¸´ÓÃPA8ΪÊä³ö*/
void PWM_Init(u16 arr,u16 psc)
{	
	//¶¨ÒåÏà¹ØµÄ½á¹¹Ì壺
	GPIO_InitTypeDef GPIO_InitStrcture;
	TIM_TimeBaseInitTypeDef TIM_InitStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	
	//1.ʹÄÜʱÖÓ£º
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA,ENABLE);

	//2.ÅäÖÃGPIOA.8½á¹¹ÌåÐÅÏ¢£º
	GPIO_InitStrcture.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStrcture.GPIO_Pin = GPIO_Pin_8;
	GPIO_InitStrcture.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA,&GPIO_InitStrcture);
	
	//3.ÅäÖÃTIM1½á¹¹ÌåÐÅÏ¢£º
	TIM_InitStructure.TIM_Period = arr;
	TIM_InitStructure.TIM_Prescaler = psc;
	TIM_InitStructure.TIM_ClockDivision = 0;
	TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Down;
	
	TIM_TimeBaseInit(TIM1,&TIM_InitStructure);
	
	//4.ÅäÖÃTIM1_CH1µÄPWMģʽºÍͨµÀ·½Ïò£º
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	
	TIM_OC1Init(TIM1,&TIM_OCInitStructure);
	
	//5.ʹÄÜÏà¹Ø¼Ä´æÆ÷£º
	TIM_CtrlPWMOutputs(TIM1,ENABLE);			//ʹÄÜÖ÷Êä³ö
	TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);	//CH1ԤװÔØʹÄÜ
	TIM_ARRPreloadConfig(TIM1,ENABLE);		//ʹÄÜTIMxµÄARRµÄԤװÔؼĴæÆ÷
	TIM_Cmd(TIM1,ENABLE);									//ʹÄÜTIM1
}

(4)main:
 

#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "pwm.h"

int main(void)
{
	u8 flag = 1;
	u16 pwm_value = 0;
	
	LED_Init();
	PWM_Init(899,0);
	
	while(1)
	{
		delay_ms(20);
		if(flag)
		{
			pwm_value ++;
		}
		else
		{
			pwm_value --;
		}
		if(pwm_value > 300)
		{
			//pwm_value = 0;
			flag = !flag;
		}
		if(pwm_value == 0)
		{
			flag = !flag;
		}
		
		//ÉèÖÃTIM1±È½Ï/²¶»ñͨµÀ¼Ä´æÆ÷µÄÖµ£¬Í¨¹ýÐ޸ĴËÖµ¸Ä±äPWMµÄÕ¼¿Õ±È
		TIM_SetCompare1(TIM1,pwm_value);
	}
}


5.运行结果:可以看到LED的亮度在自动变化。

 

 6.总结:PWM是通过微控制器的数字输出,控制模拟输出。通常可以利用定时器实现PWM。PWM可以控制I/O输出高低电平的时间,通过I/O输出高低电平的时间,就可以控制外部器件工作/不工作的时间,从而控制其速度或者亮度等。

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

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

相关文章

WebRTC本地视频通话使用ossrs服务搭建

iOS开发-ossrs服务WebRTC本地视频通话服务搭建 之前开发中使用到了ossrs&#xff0c;这里记录一下ossrs支持的WebRTC本地服务搭建。 一、ossrs是什么&#xff1f; ossrs是什么呢&#xff1f; SRS(Simple Realtime Server)是一个简单高效的实时视频服务器&#xff0c;支持RTM…

【佳佳怪文献分享】通过引导学会行走: 动态环境中的感知四足运动

标题&#xff1a;Learning to Walk by Steering: Perceptive Quadrupedal Locomotion in Dynamic Environments 作者&#xff1a;Mingyo Seo , Ryan Gupta , Yifeng Zhu , Alexy Skoutnev , Luis Sentis , and Yuke Zhu 来源&#xff1a;2023 IEEE International Conference …

Titanic--细节记录二

merge、join以及concat的方法的不同以及相同 相同之处&#xff1a;都用于合并数据。 不同之处&#xff1a; merge主要是基于列的合并。join主要是基于索引&#xff08;行标签&#xff09;的合并。concat可以沿任意轴合并&#xff0c;更灵活。 import pandas as pddf1 pd.Da…

Linux 查看内存使用情况的几种方法

在运行 Linux 系统的过程中为了让电脑或者服务器以最佳水平运行&#xff0c;常常需要监控内存统计信息。 那么今天我们就来看看有哪些方法可以访问所有相关信息并帮助管理员监控内存统计信息。 查看或者获取 Linux 中的内存使用情况既可以通过命令的方式&#xff0c;也可以通…

OptaPlanner笔记6 N皇后

N 个皇后 问题描述 将n个皇后放在n大小的棋盘上&#xff0c;没有两个皇后可以互相攻击。 最常见的 n 个皇后谜题是八个皇后谜题&#xff0c;n 8&#xff1a; 约束&#xff1a; 使用 n 列和 n 行的棋盘。在棋盘上放置n个皇后。没有两个女王可以互相攻击。女王可以攻击同一水…

Python语言基础---选择判断循环结构详解

文章目录 &#x1f340;引言&#x1f340;if语句&#x1f340;if-else语句&#x1f340;if-elif-else语句&#x1f340;for循环&#x1f340;while循环 &#x1f340;引言 在Python编程语言中&#xff0c;选择判断和循环是两个非常重要的概念。它们可以让我们根据条件执行不同的…

分布式应用:Zabbix监控Tomcat

目录 一、理论 1.Zabbix监控Tomcat 二、实验 1.Zabbix监控Tomcat 三、问题 1.获取软件包失败 2.tomcat 配置 JMX remote monitor不生效 3.Zabbix客户端日志报错 一、理论 1.Zabbix监控Tomcat &#xff08;1&#xff09;环境 zabbix服务端&#xff1a;192.168.204.214 …

模型性能的主要指标

主要参数 ROC 曲线和混淆矩阵都是用来评估分类模型性能的工具 ROC曲线&#xff08;Receiver Operating Characteristic curve&#xff09;&#xff1a; ROC曲线描述了当阈值变化时&#xff0c;真正类率&#xff08;True Positive Rate, TPR&#xff09;和假正类率&#xff0…

SAP 收藏夹Favorites介绍,收藏夹导入/导出功能

作为SAP用户&#xff0c;经常需要使用一些事务代码T-Code, 很多时候会因为不常用其中的一些遗忘这个功能&#xff0c;所以这时候分类收藏好不同Module的事务代码到收藏夹里是一个不错的选择。 经常面临的一个场景就是需要变换系统环境&#xff0c;比如从Client A01,去到Client…

springcloud 基础

SprinbCloud微服务简介 架构发展历史 SpringBoot由baiPivotal团队在2013年开始研发、2014年4月发布第一个du版本的全新开源的轻量级框架。 它基zhi于Spring4.0设计&#xff0c;不dao仅继承了Spring框架原有的优秀特性&#xff0c;而且还通过简化配置来进一步简化了Spring应用…

QIIME 2教程. 11元数据Metadata(2023.5)

QIIME 2用户文档. 11元数据 Metadata in QIIME 2 https://docs.qiime2.org/2023.5/tutorials/metadata/ 注&#xff1a;此实例需要一些基础知识&#xff0c;要求完成本系列文章前两篇内容&#xff1a;《1简介和安装Introduction&Install》和4《人体各部位微生物组分析Movin…

【硬件突击 电路】

文章目录 1. 电阻&#xff08;Resistor&#xff09;&#xff1a;2. 电容&#xff08;Capacitor&#xff09;&#xff1a;3. 电感&#xff1a;4、 RC、RL、RLC电路结构及工作原理基尔霍夫定律基尔霍夫电流定律&#xff08;KCL&#xff09;基尔霍夫电压定律&#xff08;KVL&#…

【舌尖优省PLUS】美团、饿了么外卖免费领红包,尽情享受美食与省钱!

家人们&#xff01;我昨天刚开发完并上线了一个超棒的外卖免费领红包的小程序&#xff0c;它叫做【舌尖优省PLUS】&#xff01;如果你喜欢美食&#xff0c;还想省下一些钱&#xff0c;那这个小程序绝对不能错过&#xff01; 在【舌尖优省PLUS】上&#xff0c;你可以通过简单的…

react 生命周期方法

组件的生命周期 每个组件都包含 “生命周期方法”&#xff0c;你可以重写这些方法&#xff0c;以便于在运行过程中特定的阶段执行这些方法。你可以使用此生命周期图谱作为速查表。在下述列表中&#xff0c;常用的生命周期方法会被加粗。其余生命周期函数的使用则相对罕见。 挂…

第4章:决策树

停止 当前分支样本均为同一类时&#xff0c;变成该类的叶子节点。当前分支类型不同&#xff0c;但是已经没有可以用来分裂的属性时&#xff0c;变成类别样本更多的那个类别的叶子节点。当前分支为空时&#xff0c;变成父节点类别最多的类的叶子节点。 ID3 C4.5 Cart 过拟合 缺…

springcloud3 sleuth实现链路状态监控

一 slueth的介绍 1.1 slueth的作用 在微服务框架中&#xff0c;一个由客户端发起的请求在后端系统中会经过多个不同的服务节点调用来协同产生最后的请求结果&#xff0c;每一个阶段请求都会形成一条复杂的分布式调用链路&#xff0c;链路中任何一环出现高延时或者错误都会引起…

通讯协议038——全网独有的OPC HDA知识一之聚合(七)最小值

本文简单介绍OPC HDA规范的基本概念&#xff0c;更多通信资源请登录网信智汇(wangxinzhihui.com)。 本节旨在详细说明HDA聚合的要求和性能。其目的是使HDA聚合标准化&#xff0c;以便HDA客户端能够可靠地预测聚合计算的结果并理解其含义。如果用户需要聚合中的自定义功能&…

MySQL环境安装

文章目录 MySQL环境安装1. 卸载1.1 卸载不要的环境1.2 检查卸载系统安装包 2. 安装2.1 获取mysql官方yum源2.2 安装mysql的yum源2.3 安装mysql服务 3. 登录(1)(2)(3) 4. 配置my.cnf MySQL环境安装 说明&#xff1a; 安装与卸载中&#xff0c;用户全部切换成为root&#xff0c…

基于YOLOv8+PyQt5开发的行人过马路危险行为检测告警系统(附数据集和源码下载)

系列文章目录 文章目录 系列文章目录前言欢迎来到我的博客&#xff01;我很高兴能与大家分享关于基于YOLOv8的行人过马路危险行为检测告警系统的内容。 一、系统特点1. 采用最新最优秀的目标检测算法YOLOv82. 系统分别基于PyQt5开发了两种GUI图形界面&#xff0c;供大家学习使用…

ruoyi-vue-pro yudao 项目bpm模块启用及相关SQL脚本

目前ruoyi-vue-pro 项目虽然开源&#xff0c;但是bpm模块被屏蔽了&#xff0c;查看文档却要收费 199元&#xff08;知识星球&#xff09;&#xff0c;价格有点太高了吧。 分享下如何启用 bpm 模块&#xff0c;顺便贴上sql相关脚本。 一、启用模块 修改根目录 pom.xml 启用模…