STM32物联网实战开发(6)——PWM驱动LED灯

news2024/11/28 14:38:49

PWM驱动LED灯

        之前是使用标准库函数配置引脚输出PWM控制呼吸灯,因为开发板上的蜂鸣器是有源的,所以这次还是用来确定LED灯,这次使用的是HAL库,用CubeMX软件初始化PWM功能

PWM输出原理

Period:周期,单位是秒

Duty:占空比

CubeMX配置
        因为PB0引脚是定时器3的通道3,定时器3是通用定时器,也有PWM输出功能,所以在软件中对TIM3进行初始化

        主要就是要设定定时器时钟的分频值PSC,自动重载值ARR,因为定时器时钟确定后,每计数一次的时间也定了,从0向上计数到ARR的值,就是一个PWM周期

在PB0引脚选择TIM3_CH3
 

开启通用定时器3的时钟源,选择内部时钟,通道3的PWM功能 

 配置时基单元和PWM输出通道

        预分频系数PSC设置为71,也可以写为72000000/1000000-1,设置定时器的时钟为1MHz,因为72MHz的晶振振72次是1us(72分频),1/1us = 1/0.000001s = 1000000Hz = 1Mz

        自动重载值ARR为999,也就是从0计数到999,每计数一次是1us,共1000次,所以1000 * 1us = 1ms,所以PWM信号的周期就是1ms,换算成频率就是1KHz

        配置PWM输出通道时,Pulse设置的就是CCR的值,当CNT计数值小于CRR时,会输出一个有效电平,是高电平有效还是低电平有效要看CH Polarity(CH通道极性)选择,如果选择为高电平,则该有效电平就是高电平,如果选择低电平则该有效电平就是低电平;(一定要看你的硬件电路是高电平有效,还是低电平有效,这里我使用的小灯是低电平有效,但是我和UP配置的极性高电平,所以占空比是相反的,这点大家一定要注意

        Pulse的值也就是占空比的值,因为PWM周期已经在设置自动重载值ARR时确定了,为1000,所以Pulse设置为500的话,表示PWM信号的占空比就为50%,如果Pulse为250,则占空比就是25%

        ARR的值控制的是PWM信号的周期,CCR的值控制的是PWM信号的占空比;ARR不变,改变CCR的值,则会改变占空比;CCR不变,改变ARR,则会改变PWM的周期

注意:在大多数情况下,选择开启CCR寄存器的预装载功能,让占空比的变化在下一个PWM信号周期才生效

         打开定时器3中断和机械按键1的外部中断,定时器回调函数中可以改变定时器3输出PWM的频率,达到输出不同的LED频闪效果,机械按键可以开启和关闭LED灯。

代码1

实现功能:机械按键1可以打开或关闭LED灯,开发板上电后LED灯会发出不同频率的光

Led.c

主要是编写LED的开启和关闭函数

/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/

/* Private variables----------------------------------------------------------*/
static void Led_ON(void);
static void Led_OFF(void);
/* Public variables-----------------------------------------------------------*/
Led_t Led = 
{
    OFF_Status,
    Led_ON,
    Led_OFF
};
/* Private function prototypes------------------------------------------------*/

/*
* @name   Led_ON
* @brief  打开Led
* @param  None
* @retval None   
*/
static void Led_ON()
{
    //只需开启PWM输出功能,即可让Led亮
    HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
    Led.Status = ON_Status;
}

/*
* @name   Led_OFF
* @brief  关闭Led
* @param  None
* @retval None   
*/
static void Led_OFF()
{
    //关闭PWM输出,即关闭Led
    HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_1);
    Led.Status = OFF_Status;
}

MyInit.c

要在初始化函数中打开LED,上电后才会亮

/*
* @name   Peripheral_Set
* @brief  外设设置
* @param  None
* @retval None   
*/
static void Peripheral_Set()
{
  Timer6.Timer6_Start_IT();   //启动定时器6
  Led.ON();                //打开Led
}

CallBack.c

外部中断回调函数中,机械按键1按下翻转LED2灯电平,同时控制LED1的开关

定时器6中断回调函数中,用LED2显示定时器运行状态,改变定时器3ARR的值,不断改变PWM信号的频率

/*
* @name   HAL_GPIO_EXTI_Callback
* @brief  外部中断回调函数
* @param  GPIO_Pin:触发中断的GPIO引脚
* @retval None   
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == KEY1_Pin)    //如果触摸按键1被按下
  {
    LED.LED_Fun(LED1,LED_Flip);
    //控制Led开关
    if(Led.Status == ON_Status)
    {
      Led.Led_OFF();  //关闭Led
    }
    else
    {
      Led.Led_ON();   //打开Led
    }
  }
}
/*
* @name   HAL_TIM_PeriodElapsedCallback
* @brief  定时器中断回调函数
* @param  *htim:处理定时器的结构体指针
* @retval None   
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  static uint8_t Fre_Cnt = 0;
  if(htim->Instance == htim6.Instance)
  {
    //定时器6每隔5ms进入一次中断,usMCU_Run_Timer就加1,当计时时间达到1s时,翻转LED灯的状态
    if(++Timer6.usMCU_Run_Timer >= TIMER_1s)
    {
      Timer6.usMCU_Run_Timer = 0;
      LED.LED_Fun(LED2,LED_Flip);
    }

    //控制PWM的频率长度与大小
    if(Fre_Cnt++ >= 3)  //0,1,2不执行
    {
      Fre_Cnt = 0;

      //定时器1时钟:1MHz
      //PWM周期:(1/1000000Hz) * ARR
      //PWM频率:1/(1/1000000Hz)*ARR = 1000000/ARR
      //ARR = 250,PWM周期为:250us = 0.25ms = 0.00025s,PWM频率为:1/0.00025s = 4000Hz = 4KHz
      //ARR = 500,PWM周期为:500us = 0.5ms = 0.0005s,PWM频率为:1/0.0005s = 2000Hz = 2KHz
      //ARR = 1000,PWM周期为:1000us = 1ms = 0.001s,PWM频率为:1/0.001s = 1000Hz = 1KHz
      //ARR = 2000,PWM周期为:2000us = 2ms = 0.002s,PWM频率为:1/0.002s = 500Hz = 0.5KHz
      
      /*定时器6每隔5ms执行一次回调函数,在Fre_Cnt为0,1,2时,不改变ARR的值,所以PWM周期不会变,维持15ms
      当Fre_Cnt为3时,进行一次改变ARR值的操作,把ARR的值减少,当减到500时再让ARR的值为2000,
      如此反复改变ARR的值,改变PWM的频率,但占空比始终是50%*/
      TIM1->ARR -= 10;
      if(TIM1->ARR < 500)
      {
        TIM1->ARR = 2000;
      }
      //设置占空比为50%
      TIM1->CCR1 = TIM1->ARR/2; 
    }
  }
}

因为前面配置的代码是用来控制蜂鸣器的,所以对LED灯的闪烁来说,频率太快,我们人眼根本无法看出来,所以我们需要将周期变大,频率更小,才能看出来

注意——HAL_Delay函数中断优先级的问题

        在LED发出不同频率光的函数中可以看到,使用了HAL库的延时函数HAL_Delay(),而频率的函数又在外部中断的回调函数中被调用,同时在定时器回调函数也有调用HAL_Delay函数;

        因为HAL_Delay延时函数是使用到了System tick time(系统滴答定时器),也是通过中断定时,所以这三个中断就要考虑中断优先级的关系了

        因为外部中断或者定时器中断都是在中断处理过程中被HAL_Delay的中断打断的,说明HAL_Delay的中断优先级是比这两者高的,不然HAL_Delay的延时中断打断不了外部中断或者定时器中断,就没有延时的作用

        打开CubeMX的NVIC配置界面可以看到,System tick timer的默认抢占优先级是0,自己配置的外部中断是1,定时器6中断是2,数字越小则优先级越大,所以HAL_Delay延时函数在外部中断或定时器中断中能起作用

 拓展

 

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

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

相关文章

10个最流行的向量数据库【AI】

矢量数据库是一种将数据存储为高维向量的数据库&#xff0c;高维向量是特征或属性的数学表示。 每个向量都有一定数量的维度&#xff0c;范围从几十到几千不等&#xff0c;具体取决于数据的复杂性和粒度。 推荐&#xff1a;用 NSDT场景设计器 快速搭建3D场景。 矢量数据库&…

手机短信验证码登录功能的开发实录(机器识别码、短信限流、错误提示、发送验证码倒计时60秒)

短信验证码登录功能 项目分析核心代码1.外部js库调用2.HTML容器构建3.javaScript业务逻辑验证4.后端验证逻辑 总结 短信验证码是通过发送验证码到手机的一种有效的验证码系统&#xff0c;作为比较准确和安全地保证购物的安全性&#xff0c;验证用户的正确性的一种手段&#xff…

Redux的基本使用,从入门到入土

目录 一、初步使用Redux 1.安装Redux 2.配置状态机 二、Redux的核心概念 1.工作流程 2.工作流程 三、优化Redux 1.对action进行优化 2.type常量 3.reducer优化 四、react-redux使用 1.安装react-redux 2.全局注入store仓库 3.组件关联仓库 五、状态机的Hook 1.u…

Day958.代码的分层重构 -遗留系统现代化实战

代码的分层重构 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于代码的分层重构的内容。 来看看如何重构整体的代码&#xff0c;也就是如何对代码分层。 一、遗留系统中常见的模式 一个学校图书馆的借书系统。当时的做法十分“朴素”&#xff0c;在点击“借阅”按钮…

如何使用osquery在Windows上实时监控文件?

导语&#xff1a;Osquery是一个SQL驱动操作系统检测和分析工具&#xff0c;它由Facebook创建&#xff0c;支持像SQL语句一样查询系统的各项指标&#xff0c;可以用于OSX和Linux操作系统。 Osquery是一个SQL驱动操作系统检测和分析工具&#xff0c;它由Facebook创建&#xff0c;…

不得不说的行为型模式-责任链模式

目录 责任链模式&#xff1a; 底层原理&#xff1a; 代码案例&#xff1a; 下面是面试中可能遇到的问题&#xff1a; 责任链模式&#xff1a; 责任链模式是一种行为型设计模式&#xff0c;它允许多个对象在一个请求序列中依次处理该请求&#xff0c;直到其中一个对象能够…

【VM服务管家】VM4.0平台SDK_2.5 全局工具类

目录 2.5.1 全局相机&#xff1a;全局相机设置参数的方法2.5.2 全局相机&#xff1a;获取全局相机列表的方法2.5.3 全局通信&#xff1a;通信管理中设备开启状态管理2.5.4 全局通信&#xff1a;接收和发送数据的方法2.5.5 全局变量获取和设置全局变量的方法 2.5.1 全局相机&…

经典重装上阵,更好用的中小手游戏鼠标,雷柏V300W上手

日常办公、玩游戏都需要用到鼠标&#xff0c;特别是对于游戏玩家来说&#xff0c;一款手感好、易定制的鼠标&#xff0c;绝对是游戏上分的利器。早先雷柏出过一款V300鼠标&#xff0c;距今已有10年历史&#xff0c;当时是很受欢迎&#xff0c;最近南卡又出了一款复刻版的V300W&…

为什么不要相信AI机器人提供的健康信息?

自从OpenAI、微软和谷歌推出了AI聊天机器人&#xff0c;许多人开始尝试一种新的互联网搜索方式&#xff1a;与一个模型进行对话&#xff0c;而它从整个网络上学到的知识。 专家表示&#xff0c;鉴于之前我们倾向于通过搜索引擎查询健康问题&#xff0c;我们也不可避免地会向Ch…

linux下的权限管理

1.shell概念 当我们在进入正文前先给大家普及一些基础概念。 广义上来讲&#xff0c;linux 发行版 linux内核 外壳程序&#xff08;这个外壳程序就相当于 windows gui&#xff08;窗口图形&#xff09;&#xff0c;linux 常用的shell 是 bash&#xff09; 所以&#xff0c…

vue基本语法

目录 一、模板语法 &#xff08;1&#xff09;文本 &#xff08;2&#xff09;原始HTML &#xff08;3&#xff09;属性Attribute &#xff08;4&#xff09;使用JavaScript表达式 二、条件渲染 &#xff08;1&#xff09;v-if&#xff0c;v-else &#xff08;2&#x…

nodejs+vue+elementui学生毕业生离校系统

学生毕业离校系统的开发过程中。该学生毕业离校系统包括管理员、学生和教师。其主要功能包括管理员&#xff1a;首页、个人中心、学生管理、教师管理、离校信息管理、费用结算管理、论文审核管理、管理员管理、留言板管理、系统管理等&#xff0c;前台首页&#xff1b;首页、离…

stm32 CubeMx 实现SD卡/sd nand FATFS读写测试

stm32 CubeMx 实现SD卡/SD nand FATFS读写测试 文章目录 stm32 CubeMx 实现SD卡/SD nand FATFS读写测试1. 前言2. 环境介绍2.1 软硬件说明2.2 外设原理图 3. 工程搭建3.1 CubeMx 配置3.2 SDIO时钟配置说明3.2 读写测试3.2.1 添加读写测试代码 3.3 FATFS文件操作3.3.1 修改读写测…

云计算:数字化转型的利器

随着数字化转型的加速&#xff0c;企业对于信息技术应用的需求越来越大&#xff0c;而云计算作为一种新的基础设施&#xff0c;也逐渐成为了许多企业的首选。那么&#xff0c;云计算究竟有哪些优势&#xff1f;未来发展趋势又是怎样的呢&#xff1f;下面就让我们一起来探讨一下…

深入理解try...catch(字节码层面)

我们工作中常用try...catch来解决程序中出现的异常情况&#xff0c;但是你真的了解它的实现原理吗&#xff1f;今天我就带着大家从字节码层面理解try...catch 一、准备工作 我们首先需要准备好异常类和对应的测试类方便我们观察。 异常类&#xff1a; public class DivideB…

1.软件测试

目录 一、面试重点 1.什么是软件测试&#xff1f; 2.软件测试和软件开发的区别 3.你为什么选择软件测试&#xff1f; 4.什么是需求&#xff1f; 5.软件测试人员如何深入了解需求&#xff1f; 6.什么是内存泄露&#xff1f; 7.什么是测试用例&#xff1f; 8.测试用例有…

【23】linux进阶——linux的软链接和硬链接

大家好&#xff0c;这里是天亮之前ict&#xff0c;本人网络工程大三在读小学生&#xff0c;拥有锐捷的ie和红帽的ce认证。每天更新一个linux进阶的小知识&#xff0c;希望能提高自己的技术的同时&#xff0c;也可以帮助到大家 另外其它专栏请关注&#xff1a; 锐捷数通实验&…

终于成功了,CCED2000后,中文编程软件再次脱颖而出,系出金山

WPS抗衡微软&#xff0c;CCEDE却被淹没&#xff1f; DOS代&#xff0c;我们用WPS来进行文字编辑&#xff0c;CCED来做表格&#xff0c;两者在那个时代可以称得上是国产办公领域的“必装软件”。 如今&#xff0c;30年过去了&#xff0c;WPS一步一步成长为抗衡微软office的国产…

electron入门 | 手把手带electron项目初始化

Electron是一个基于Chromium和 Node.js&#xff0c;可以使用 HTML、CSS和JavaScript构建跨平台应用的技术框架&#xff0c;兼容 Mac、Windows 和 Linux。 目录 1.了解electron 2.开发环境 3.初始化 采坑插曲&#xff1a; 1.了解electron Electron 可以让你使用纯 JavaScrip…

easyexcel读取excel合并单元格数据

普通的excel列表&#xff0c;easyexcel读取是没有什么问题的。但是&#xff0c;如果有合并单元格&#xff0c;那么它读取的时候&#xff0c;能获取数据&#xff0c;但是数据是不完整的。如下所示的单元格数据&#xff1a; 我们通过简单的异步读取&#xff0c;最后查看数据内容&…