STM32 LED呼吸灯

接线图:

这里将正极接到PA0引脚上,负极接到GND,这样就高电平点亮LED,低电平熄灭。

占空比越大,LED越亮,占空比越小,LED越暗

PWM初始化配置

输出比较函数介绍:

用这四个函数配置输出比较模式,四个函数对应四个输出比较单元,这个函数使用结构体初始化输出比较单元的,这四个函数很重要需要掌握

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%是一样的,输出低电平与占空比设置0%是一样的。

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);

这四个函数是用来配置CCR寄存器的预装功能的,预装功能就是影子寄存器,就是写入的值不会立即生效,而是在更新事件才会生效(一般不用这些函数)

void TIM_OC1PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC3PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_OC4PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);

这四个函数是用来配置快速使能的(用的也不多)

void TIM_OC1FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC2FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC3FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);
void TIM_OC4FastConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCFast);

在手册里,外部事件时清除REF信号有介绍。

void TIM_ClearOC1Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC2Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC3Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);
void TIM_ClearOC4Ref(TIM_TypeDef* TIMx, uint16_t TIM_OCClear);

 这些是单独设置输出比较的极性的,这里带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);

根据结构图配置:

1.定义结构体变量

定义GPIO与TIM所需的结构体变量

//-----------------------------定义结构体变量------------------------------
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//定义TIMBase结构体变量
  TIM_OCInitTypeDef TIM_OCInitStructure;		    //定义TIMOC结构体变量
  GPIO_InitTypeDef GPIO_InitStructure;			    //定义GPIO结构体变量
//-----------------------------定义结构体变量------------------------------

2.RCC开启时钟

把我们要用到的TIM外设和GPIO外设的时钟打开

3.配置时基单元

包括前面的时钟源选择、PSC预分频器、CNT计数器、ARR自动重装器

//-----------------------------配置时基单元---------------------------------
	 
   TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;		 //时钟分频
   TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式  这里选择向上计数
   TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;	     //周期 就是ARR自动重装器的值
   TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;		 //是PSC预分频器的值
   TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;	 //重复计数器的值(这个是高级寄存器才有的,这里不需要用直接给0)
   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);	 //TIM初始化
	
//-----------------------------配置时基单元---------------------------------

4.配置输出比较单元

里面CCR的值、输出比较模式、极性选择、输出使能这些参数(用结构体统一配置)

//-----------------------------配置输出比较单元-----------------------------
	 
  TIM_OCStructInit(&TIM_OCInitStructure); //给结构体赋一个初始值,因为我们还有其他的变量没有赋值
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;		//设置输出比较模式,这里选择PWM模式1
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //设置输出比较的极性,这里选择高极性,有效电平是高电平时输出高电平	 
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //设置输出使能
  TIM_OCInitStructure.TIM_Pulse = 50;					        //设置CCR值
  TIM_OC1Init(TIM2, &TIM_OCInitStructure);
	
//-----------------------------配置输出比较单元-----------------------------

5.配置GPIO

把PWM对应的GPIO口,初始化为复用推挽输出的配置

//-----------------------------配置GPIO初始化------------------------------
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		 //配置引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度
	GPIO_Init(GPIOA,&GPIO_InitStructure);//GPIO初始化
	
//-----------------------------配置GPIO初始化------------------------------

6.运行控制

启动计数器,输出PWM

TIM_Cmd(TIM2,ENABLE);//启动定时器

配置一个频率为 1KHz,占空比为50%的PWM波形

这里的ARR、PSC与CCR决定占空比

公式:

CK_PSC为72MHz,因为系统时钟频率为72MHz.

功能实现:

实现呼吸灯效果需要不断改变占空比的值,需要调用

void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);

函数,在运行时不断改变占空比的值。

功能函数:

void PWM_SetComPer(uint16_t Compare)
{	
	 TIM_SetCompare1(TIM2,Compare);

}

主函数:

#include "PWM.h"
int main(void)
{
	LED_Init();
	OLED_Init();
	PWM_Init();
	uint16_t i = 0;
	while(1)
	{
		for(i = 0; i <= 100; i++)
		{
			PWM_SetComPer(i);
			Delay_ms(10);
		}
		for(i = 0; i <= 100; i++)
		{
			PWM_SetComPer(100-i);
			Delay_ms(10);
		}

	}	
	
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

记录一次-Rancher通过UI-Create Custom- RKE2的BUG

一、下游集群 当你的下游集群使用Mysql外部数据库时&#xff0c;会报错&#xff1a; **他会检查ETCD。 但因为用的是Mysql外部数据库&#xff0c;这个就太奇怪了&#xff0c;而且这个检测不过&#xff0c;集群是咩办法被管理的。 二、如果不选择etcd,就选择控制面。 在rke2-…

数据库物理备份:保障数据完整性和业务连续性的关键策略

title: 数据库物理备份:保障数据完整性和业务连续性的关键策略 date: 2025/1/29 updated: 2025/1/29 author: cmdragon excerpt: 在现代企业中,数据被视为最重要的资产之一。因此,确保数据的安全性、完整性和可用性是每个数据库管理员(DBA)的首要任务。在数据管理的过程…

【3分钟极速部署】在本地快速部署deepseek

第一步&#xff0c;找到网站&#xff0c;下载&#xff1a; 首先找到Ollama &#xff0c; 根据自己的电脑下载对应的版本 。 我个人用的是Windows 我就先尝试用Windows版本了 &#xff0c;文件不是很大&#xff0c;下载也比较的快 第二部就是安装了 &#xff1a; 安装完成后提示…

Deepseek v3R1 学习笔记

o1 o1 模型在训练过程中混合了多种奖励函数的设计方法&#xff0c;并且尝试从结果监督转向过程监督&#xff0c;在中间过程进行打分 使用的搜索策略&#xff1a;基于树的搜索和基于顺序修改的搜索 R1 R1-Zero 是从基础模型开始&#xff0c;完全由强化学习驱动&#xff0c;不…

4.PPT:日月潭景点介绍【18】

目录 NO1、2、3、4​ NO5、6、7、8 ​ ​NO9、10、11、12 ​ 表居中或者水平/垂直居中单元格内容居中或者水平/垂直居中 NO1、2、3、4 新建一个空白演示文稿&#xff0c;命名为“PPT.pptx”&#xff08;“.pptx”为扩展名&#xff09;新建幻灯片 开始→版式“PPT_素材.doc…

国防科大:双目标优化防止LLM灾难性遗忘

&#x1f4d6;标题&#xff1a;How to Complete Domain Tuning while Keeping General Ability in LLM: Adaptive Layer-wise and Element-wise Regularization &#x1f310;来源&#xff1a;arXiv, 2501.13669 &#x1f31f;摘要 &#x1f538;大型语言模型&#xff08;LLM…

【C++】多态详细讲解

本篇来聊聊C面向对象的第三大特性-多态。 1.多态的概念 多态通俗来说就是多种形态。多态分为编译时多态(静态多态)和运⾏时多态(动态多态)。 编译时多态&#xff1a;主要就是我们前⾯讲的函数重载和函数模板&#xff0c;他们传不同类型的参数就可以调⽤不同的函数&#xff0c;通…

java进阶1——JVM

java进阶——JVM 1、JVM概述 作用 Java 虚拟机就是二进制字节码的运行环境&#xff0c;负责装载字节码到其内部&#xff0c;解释/编译为对 应平台上的机器码指令行&#xff0c;每一条 java 指令&#xff0c;java 虚拟机中都有详细定义&#xff0c;如怎么取操 作数&#xff0c…

DeepSeek各版本说明与优缺点分析

DeepSeek各版本说明与优缺点分析 DeepSeek是最近人工智能领域备受瞩目的一个语言模型系列&#xff0c;其在不同版本的发布过程中&#xff0c;逐步加强了对多种任务的处理能力。本文将详细介绍DeepSeek的各版本&#xff0c;从版本的发布时间、特点、优势以及不足之处&#xff0…

视频融合平台EasyCVR无人机场景视频压缩及录像方案

安防监控视频汇聚EasyCVR平台在无人机场景中发挥着重要的作用&#xff0c;通过高效整合视频流接入、处理与分发等功能&#xff0c;为无人机视频数据的实时监控、存储与分析提供了全面支持&#xff0c;广泛应用于安防监控、应急救援、电力巡检、交通管理等领域。 EasyCVR支持GB…

【力扣】240.搜索二维矩阵 II

题目 我的代码 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {for(int i0;i<matrix.size();i){for(int j0;j<matrix[0].size();j){if(targetmatrix[i][j]){return true;}else if(target<matrix[i][j]){brea…

数据库备份、主从、集群等配置

数据库备份、主从、集群等配置 1 MySQL1.1 docker安装MySQL1.2 主从复制1.2.1 主节点配置1.2.2 从节点配置1.2.3 创建用于主从同步的用户1.2.4 开启主从同步1.2.4 主从同步验证 1.3 主从切换1.3.1 主节点设置只读&#xff08;在192.168.1.151上操作&#xff09;1.3.2 检查主从数…

intra-mart实现简易登录页面笔记

一、前言 最近在学习intra-mart框架&#xff0c;在此总结下笔记。 intra-mart是一个前后端不分离的框架&#xff0c;开发时主要用的就是xml、html、js这几个文件&#xff1b; xml文件当做配置文件&#xff0c;html当做前端页面文件&#xff0c;js当做后端文件&#xff08;js里…

Beans模块之工厂模块注解模块CustomAutowireConfigurer

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

javaEE-8.JVM(八股文系列)

目录 一.简介 二.JVM中的内存划分 JVM的内存划分图: 堆区:​编辑 栈区:​编辑 程序计数器&#xff1a;​编辑 元数据区&#xff1a;​编辑 经典笔试题&#xff1a; 三,JVM的类加载机制 1.加载: 2.验证: 3.准备: 4.解析: 5.初始化: 双亲委派模型 概念: JVM的类加…

【多线程】线程池核心数到底如何配置?

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. 前置回顾2. 动态线程池2.1 JMX 的介绍2.1.1 MBeans 介绍 2.2 使用 JMX jconsole 实现动态修改线程池2.2.…

js-对象-JSON

JavaScript自定义对象 JSON 概念: JavaScript Object Notation&#xff0c;JavaScript对象标记法. JSON 是通过JavaScript 对象标记法书写的文本。 由于其语法简单&#xff0c;层次结构鲜明&#xff0c;现多用于作为数据载体&#xff0c;在网络中进行数据传输. json中属性名(k…

基于 SpringBoot3 的 SpringSecurity6 + OAuth2 自定义框架模板

&#x1f516;Gitee 项目地址&#xff1a; 基于SpringBoot3的 SpringSecurity6 OAuth2 自定义框架https://gitee.com/MIMIDeK/MySpringSecurityhttps://gitee.com/MIMIDeK/MySpringSecurityhttps://gitee.com/MIMIDeK/MySpringSecurity

大模型综述一镜到底(全文八万字) ——《Large Language Models: A Survey》

论文链接&#xff1a;https://arxiv.org/abs/2402.06196 摘要&#xff1a;自2022年11月ChatGPT发布以来&#xff0c;大语言模型&#xff08;LLMs&#xff09;因其在广泛的自然语言任务上的强大性能而备受关注。正如缩放定律所预测的那样&#xff0c;大语言模型通过在大量文本数…

Django视图与URLs路由详解

在Django Web框架中&#xff0c;视图&#xff08;Views&#xff09;和URLs路由&#xff08;URL routing&#xff09;是Web应用开发的核心概念。它们共同负责将用户的请求映射到相应的Python函数&#xff0c;并返回适当的响应。本篇博客将深入探讨Django的视图和URLs路由系统&am…