9.STM32F40x PWM简单介绍

news2024/9/23 7:21:56

一、PWM概念

       脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制,PWM原理如图1所示:

图1:PWM原理示意图

二、配置PWM模式介绍

       脉冲宽度调制模式可以生成一个信号,该信号频率由TIMx_ARR寄存器值决定,其占空比则由TIMx_CCRx寄存器值决定。

       通过向TIMx_CCMRx寄存器中的OCxM位写入110(PWM模式1)或111(PWM模式2),可以独立选择各通道(每个OCx输出对应一个PWM)的PWM模式。必须通过将TIMx_CCMRx寄存器中的OCxPE位置1使能相应预装载寄存器,最后通过将TIMx_CR1寄存器中的ARPE位置1使能自动重载预装载寄存器。

       由于只有在发生更新事件时预装载寄存器才会传送到影子寄存器,因此启动计数器之前,必须通过将TIMx_EGR寄存器中的UG位置1来初始化所有寄存器。

        OCx极性可使用TIMx_CCER寄存器的CCxP位来编程。既可以设为高电平有效,也可以设为低电平有效。OCx输出通过将TIMx_CCER寄存器中的CCxE位置1来使能。详细信息内容,可参见TIMx_CCERx寄存器说明。

三、PWM边沿对齐模式介绍

下面图2展示了PWM边沿对齐模式的相关内容信息。

图2:PWM边沿对齐模式图

四、PWM代码配置步骤

  1. 开启TIM14和GPIO时钟,配置PF9选择复用功能AF9(TIM14)输出
  2. 初始化TIM14,设置TIM14的ARR和PSC等参数
  3. 设置TIM14_CH1的PWM模式,使能TIM14的CH1输出
  4. 使能TIM14
  5. 修改TIM14_CCR1来控制占空比

五、结构体TIM_OCInitTypeDef的定义及相关参数说明

typedef struct{

uint16_t TIM_OCMode;

uint16_t TIM_OutputState;

uint16_t TIM_OutputNState;

uint16_t TIM_Pulse;

uint16_t TIM_OCPolarity;

uint16_t TIM_OCNPolarity;

uint16_t TIM_OCIdleState;

uint16_t TIM_OCNIdleState;

} TIM_OCInitTypeDef;

涉及PWM定时器中所用到的参数要求相关的几个成员变量如下:

参数TIM_OCMode设置模式是PWM还是输出比较,这里我们选择PWM模式。

参数TIM_OutputState用来设置比较输出使能,也就是使能PWM输出到端口。

参数TIM_OCPolarity用来设置极性是高还是低。

而其他的参数TIM_OutputNState,TIM_OCNPolarity,TIM_OCIdleState和TIM_OCNIdleState是高级定时器才会用到。

六、代码示例

       1、tim14.c
//TIM14 PWM部分初始化//PWM输出初始化
//arr:自动重装值psc:时钟预分频数
void TIM14_PWM_Init(u32 arr,u32 psc){

    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);//TIM14时钟使能                
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //使能PORTF时钟

    GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GF9复用为TIM14

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;    //复用功能
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;   //上拉
    GPIO_Init(GPIOF,&GPIO_InitStructure);   //初始化PF9

    TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频    
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式            
    TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//初始化定时器14


    //初始化TIM14 Channel1 PWM模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PWM调制模式1
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//比较输出使能        
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性低
    TIM_OC1Init(TIM14, &TIM_OCInitStructure);  //初始化外设TIM1 4OC1     
    TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);  //使能预装载寄存器    
    TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE使能
    TIM_Cmd(TIM14, ENABLE);  //使能TIM14
}

       2、tim14.h
#ifndef _TIM14_H_
#define _TIM14_H_

#include "stm32f4xx.h"
#include "stdio.h"
#include "led.h"


void TIM14_PWM_Init(u32 arr,u32 psc);



#endif
       3、main.c
int main(void){

    u16 led0pwmval=0;
    u8 dir=1;

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
    SsyTick_Init(168);//初始化延时函数
    usart1_init(115200);//初始化串口波特率为115200
    TIM14_PWM_Init(500-1,84-1);//定时器时钟为84M,分频系数为84,所以计数频率
                              //为84M/84=1Mhz,重装载值500,所以PWM频率为1M/500=2Khz.
    while(1){
        Delay_ms(10);
        if(dir)led0pwmval++;  //dir==1 led0pwmval递增
        else led0pwmval--;   //dir==0 led0pwmval递减
        if(led0pwmval>300)dir=0;//led0pwmval到达300后,方向为递减
        if(led0pwmval==0)dir=1;//led0pwmval递减到0后,方向改为递增

        TIM_SetCompare1(TIM14,led0pwmval);//修改比较值,修改占空比
     }
}

七、下载结果验证说明

         我们将编译好的文件下载到我们的硬件设备上,观看其运行结果是否与我们编写的一致。如若没有错误我们将看DS0不停的由暗变到亮,然后又从亮变到暗。每个过程持续时间大概为3秒钟左右。实际运行结果如下图3所示:

图3:PWM控制DS0亮度

八、总结

1、确定硬件连接,将 DS01 连接到微控制器的一个可用的 GPIO 引脚。

2、初始化并配置 PWM 模块,设置时钟源、预分频器和计数周期等。

3、选择一个 PWM 通道,配置周期和占空比,确定 PWM 信号的频率和亮度级别。

4、启动 PWM 模块和所选择的 PWM 通道,开始生成 PWM 信号。

5、通过调整 PWM 通道的占空比来调整 DS01 的亮度级别,较高的占空比意味着更亮的亮度,较低的占空比意味着更暗的亮度。

6、若要实现自动亮度调节,可以使用传感器或其他输入信号来监测环境亮度,并使用反馈控制算法实时调整 PWM 通道的占空比。

注意:本人所写文章内容均用于记录自己在学习嵌入式的成长过程!!!!!

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

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

相关文章

2859. 计算 K 置位下标对应元素的和

本题的关键在于如何去求一个二进制数中含有多少个1的问题。 如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所…

Redis(秒杀活动、持久化之RDB、AOF)

目录 秒杀活动 一、测压工具jmete的使用 二、java实现秒杀活动 1、myseckillcontroller 2、先启动pos请求添加商品,再启动jmeter进行压测 Redis持久化 一 、Redis持久化之RDB 1.RDB是什么 2. 备份是如何执行的 3.Fork 4. RDB持久化流程 5. dump.rdb文件 6…

Spring Security 之 内存认证

Spring Security的InMemoryUserDetailsManager实现了UserDetailsService,以提供对存储在内存中的基于用户名/密码的身份验证的支持。InMemoryUserDetailsManager通过实现UserDetailsManager接口提供了对UserDetails的管理。当Spring Security配置为接受用户名和密码进行身份验…

HarmonyOS鸿蒙应用开发 (二、应用程序包结构理解及Ability的跳转,与Android的对比)

在进行应用开发前,对程序的目录及包结构的理解是有必要的。如果之前有过android开发经验的,会发现OpenHarmony的应用开发也很简单,有很多概念是相似的。下面对比android分析总结下鸿蒙的应用程序包结构,以及鸿蒙对比android的诸多…

核桃的数量---蓝桥杯

思路&#xff1a; 题目所代表的意思就是a,b,c这三个必须是核桃数量的因子&#xff0c;即a,b,c三个的最小公倍数 #include <iostream> #include <algorithm> using namespace std; // int main() { int a,b,c;cin>>a>>b>>c;int da*b/__gcd(a,b…

水库大坝安全监测的技术手段及方法

水库大坝安全监测是指通过仪器观测和巡视检查对水利水电工程主体结构、地基基础、两岸边坡、相关设施以及周围环境所作的测量及观察。水库大坝安全监测是作为水库大坝安全管理的重要组成部分&#xff0c;是掌握水库大坝安全性态的重要手段&#xff0c;是科学调度、安全运行的前…

【论文+App试玩+图像到视频】2311.Animate-anyone:上传1张图片为任何人制作动画(用于角色动画的一致且可控的图像到视频合成)(暂未开源)

项目主页&#xff1a;https://humanaigc.github.io/animate-anyone/ 论文: Animate Anyone: Consistent and Controllable Image-to-Video Synthesis for Character Animation 摩尔线程复现代码&#xff1a;https://github.com/MooreThreads/Moore-AnimateAnyone 摩尔windows一…

[蓝桥杯]真题讲解:飞机降落(DFS枚举)

[蓝桥杯]真题讲解&#xff1a;飞机降落&#xff08;DFS枚举&#xff09; 一、视频讲解二、暴力代码&#xff08;也是正解代码&#xff09; 一、视频讲解 视频讲解 二、暴力代码&#xff08;也是正解代码&#xff09; //飞机降落&#xff1a; 暴力枚举DFS #include<bits/…

简化java代码:mapstruct + 策略模式

目录 目的 准备 注意 相同类型-属性名不同 实体类 映射 使用 验证-查看实现类 测试 不同类型(策略模式) 实体类 映射 工具类 使用&#xff1a;对象拷贝 验证-查看实现类 测试 使用&#xff1a;集合拷贝 测试 策略模式说明 准备-依赖 目的 简化 BeanUtils.…

如何降低微服务复杂度丨云栖大会微服务主题分享实录

作者&#xff1a;谢吉宝 本文整理自阿里云资深技术专家、中间件负责人谢吉宝在2023云栖大会《极简微服务模式&#xff0c;降低微服务复杂度的最佳实践》的分享 2023 云栖大会现场 当面临复杂的挑战时&#xff0c;"分而治之"的方法往往能取得显著的效果。微服务架构…

室外全彩LED显示屏尺寸与设计考量

在现代城市的建筑景观中&#xff0c;室外全彩LED显示屏以其鲜艳丰富的色彩和强大的视觉冲击力成为一种不可忽视的存在。然而&#xff0c;如何确定室外全彩LED显示屏的尺寸以及常见的尺寸比例是一个需要综合考虑多个因素的问题。 尺寸的确定与内容相关 首先&#xff0c;对于图文…

LabVIEW工业机器人系统

介绍了ABB工业机器人与LabVIEW之间进行数据交互的解决方案。通过使用TCP/IP协议的socket通信&#xff0c;实现了机器人坐标数据的读取&#xff0c;为人机交互提供了一个更便捷、更高效的新思路。 系统主要由ABB工业机器人、基于TCP/IP协议的通信接口和LabVIEW软件组成。工业机…

2023年第十六届中国系统架构师大会(SACC2023):核心内容与学习收获(附大会核心PPT下载)

大会以“数字转型 架构演进”为主题&#xff0c;聚焦系统架构在数字化转型中的演进和应用。 与往届相比&#xff0c;本届大会最大的变化是从原来的大会演讲模式变革为专题研讨会模式。专题研讨会主题内容紧扣行业落地实践痛点与难点&#xff0c;多角度聚焦行业的架构演进之路。…

基于Apache httpd为windows11搭建代理服务器

文章目录 一.概述二.检查电脑系统类型三.下载安装Apache Httpd四.代理服务配置五.代理服务安装六.报错解决方法七.测试是否运行成功7.1 本机测试7.2 局域网代理测试 八.设置特定ip可访问&#xff08;阻止其他ip访问&#xff09;九.参考文档 一.概述 出于某些原因&#xff0c;我…

如何使用phpStudy软件测试本地PHP及环境搭建

各位同学朋友们大家好&#xff01;我是咕噜铁蛋&#xff01;我们经常需要在本地进行PHP代码的开发和测试。而phpStudy作为一个集成了Apache、MySQL和PHP的软件套装&#xff0c;提供了方便快捷的环境搭建和测试工具。今天铁蛋为大家详细介绍如何使用phpStudy来测试本地PHP及环境…

Unity中URP下获取每一个额外灯数据

文章目录 前言一、我们先来看一下 SimpleLit 中的调用二、获取额外灯索引1、非移动平台2、非GLES平台3、大多数平台 三、获取额外灯数据 前言 在上一篇文章中&#xff0c;我们知道了URP下是怎么获取额外灯数量的。 Unity中URP下获取额外灯数量 在这篇文章中&#xff0c;我们…

Geogebra绘制正态分布曲线-学习b站何威老师视频

​ 参考资料 GeoGebra系列教程3——GGB与正态分布密度曲线_哔哩哔哩_bilibili 我要开始学习啦&#xff0c;吼吼~~~ 准备工作 https://www.geogebra.org/download 选择GeoGebra 经典 6 详细步骤 设计思路具体操作设计积分区间【a,b】创建滑动条a∈[-5,5]&#xff0c;增量是…

Linux 下查看端口以及释放端口

目录 一、查看端口是否被占用 1、使用 netstat 命令 2、使用 lsof 命令 二、释放端口 1、使用kill命令 2、使用 fuser 命令 三、netstat 四、lsof 五、fuser 一、查看端口是否被占用 在 Linux 系统上&#xff0c;你可以使用 netstat 或 lsof 命令来查看端口是否被占用。…

Goodbye! Xshell、iTerm2、FinalShell,mobaxterm,新一代开源免费的终端工具真香!

前言 众所周知&#xff0c;在数字化时代&#xff0c;远程连接成为工作和管理中不可或缺的一环。 而在这个领域&#xff0c;SSH&#xff08;Secure Shell&#xff09;一直是最常用的协议之一&#xff0c;为远程管理提供了安全的通信渠道。 然而&#xff0c;伴随着技术的发展和…

flutter tab页面切换练手,手势滑动、禁止滑动、page切换动画,禁止切换动画。

1&#xff1a;AppBar、TabBar、TabBarView实现页面切换&#xff0c;点击tab后tabBarView有左右切换动画&#xff0c;滑动page联动tabBar class DevicePage extends StatefulWidget {const DevicePage({super.key});overrideState<DevicePage> createState() > _Devic…