【STM32单片机】----实现LED灯闪烁实战

34889d2e7fec4a02bb0ae3a22b011a2a.png

🎩 欢迎来到技术探索的奇幻世界👨‍💻

📜 个人主页:@一伦明悦-CSDN博客

✍🏻 作者简介: C++软件开发、Python机器学习爱好者

🗣️ 互动与支持💬评论      👍🏻点赞      📂收藏     👀关注+

如果文章有所帮助,欢迎留下您宝贵的评论,

点赞加收藏支持我,点击关注,一起进步!

前言

       STM32是一系列由STMicroelectronics开发的32位ARM Cortex-M微控制器系列,广泛应用于嵌入式系统中。它们提供了丰富的外设和性能,适用于各种应用领域,包括工业控制、汽车、消费电子等。STM32系列有多个产品系列,每个系列针对不同的应用需求提供了多种型号和配置选项。要对STM32有一个全面的总结,可以涵盖其主要特点、产品系列、应用领域、开发工具和生态系统等方面的信息。

        代码实现资源链接

【免费】STM32实现LED灯闪烁资源-CSDN文库icon-default.png?t=N7T8https://download.csdn.net/download/m0_59951855/89359786?spm=1001.2014.3001.5503

正文

01-LED灯1实现

       当想要在STM32单片机上实现LED灯的闪烁时,可以遵循以下步骤:

  1. 初始化GPIO引脚:首先,需要初始化用于连接LED的GPIO引脚。这包括设置引脚的模式(输入/输出)、速度、上拉/下拉等。

  2. 配置定时器(Timer):使用一个定时器来生成定期的中断,以便控制LED的闪烁频率。可以选择适当的定时器和预分频器来生成适当的时钟频率。

  3. 编写中断服务程序(ISR):在定时器中断服务程序中,可以切换LED的状态,从而使其闪烁。可以在每次中断时切换LED的状态,或者根据需要计算适当的间隔。

  4. 编写主程序:在主程序中初始化所有必要的硬件和变量,并启动定时器。然后,可以让主程序进入一个无限循环,在循环中等待定时器中断。

  5. 编译和下载程序:最后,将程序编译为可执行文件,并通过调试器将其下载到STM32单片机中进行测试。

        LED灯1实现

        LED1.h文件:

        这段.h文件是LED模块的头文件,用于声明LED相关的函数和变量。让我解释一下:

  1. #ifndef __LED_H 和 #define __LED_H:这是头文件保护措施,确保在同一编译单元中只包含一次该头文件内容,防止重复定义。

  2. void LED1_Init(void);:这是LED1初始化函数的声明,告诉编译器该函数的存在和接口。

  3. #endif:结束头文件的定义。

        这个头文件的作用是在其他源文件中包含它后,可以调用LED1_Init函数进行LED的初始化。

#ifndef __LED_H
#define __LED_Hvoid LED1_Init(void);#endif

        LED1.cpp文件:这段代码是用于在STM32F10x系列单片机上初始化一个LED(Light Emitting Diode)的函数。详细解释如下:

  1. #include "stm32f10x.h":这行代码包含了STM32F10x系列的设备头文件,其中包含了该系列单片机的寄存器定义和常量声明等信息。

  2. void LED1_Init(void):这是一个无返回值的函数,用于初始化LED。

  3. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);:这行代码用于使能GPIOA的时钟。在STM32中,访问GPIO需要先使能相应的时钟。

  4. GPIO_InitTypeDef GPIO_InitStructure;:定义了一个结构体变量GPIO_InitStructure,用于配置GPIO初始化参数。

  5. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;:将GPIOA的引脚1配置为推挽输出模式。在这种模式下,GPIO引脚可以提供高电平和低电平输出。

  6. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;:选择了GPIOA的引脚1作为LED连接的引脚。

  7. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;:配置了GPIO的输出速度为50MHz。

  8. GPIO_Init(GPIOA, &GPIO_InitStructure);:根据上述配置初始化GPIOA的引脚1。

  9. 在注释中提到了两种驱动方式:

    • GPIO_ResetBits(GPIOA, GPIO_Pin_1);:将GPIOA的引脚1输出低电平,LED熄灭。
    • GPIO_SetBits(GPIOA, GPIO_Pin_1);:将GPIOA的引脚1输出高电平,LED点亮。

        这段代码的作用是初始化一个LED连接的GPIO引脚,配置为推挽输出模式,并设置输出速度为50MHz。

#include "stm32f10x.h"                  // Device headervoid LED1_Init(void)
{// 1、开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);// 2、调用Init函数// 2-1、需要先进行结构体的定义GPIO_InitTypeDef GPIO_InitStructure;// 数据信号的推挽输出,这个时候STM32对高低电平拥有绝对的控制权,此时LED灯长脚插在PA0口,短脚插在负极,高电平驱动也可以闪烁GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 变成了OD就成了开漏模式,就无法高电平驱动了GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;  // 选择Pin_0是因为用的是GPIOA的0号引脚GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  // 输出速度GPIO_Init(GPIOA,&GPIO_InitStructure);// 3、设置高电平,LED灯熄灭//GPIO_ResetBits(GPIOA,GPIO_Pin_1);//GPIO_SetBits(GPIOA,GPIO_Pin_2);
}

02-LED灯2实现

       LED灯2的实现如下:

        LED2.h文件

        这段.h文件是LED2模块的头文件,用于声明LED2相关的函数和变量。解释如下:

  1. #ifndef __LED2_H 和 #define __LED2_H:这是头文件保护措施,确保在同一编译单元中只包含一次该头文件内容,防止重复定义。

  2. void LED2_Init(void);:这是LED2初始化函数的声明,告诉编译器该函数的存在和接口。

  3. #endif:结束头文件的定义。

        这个头文件的作用是在其他源文件中包含它后,可以调用LED2_Init函数进行LED2的初始化。

#ifndef __LED2_H
#define __LED2_Hvoid LED2_Init(void);#endif

        LED2.cpp文件:这段代码是用于在STM32F10x系列单片机上初始化另一个LED的函数。解释如下:

  1. #include "stm32f10x.h":同样是包含了STM32F10x系列的设备头文件,以便使用相关的寄存器定义和常量声明。

  2. void LED2_Init(void):这是另一个无返回值的函数,用于初始化第二个LED。

  3. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);:这行代码用于使能GPIOB的时钟,因为第二个LED连接在GPIOB上。

  4. GPIO_InitTypeDef GPIO_InitStructure;:定义了一个新的结构体变量GPIO_InitStructure,用于配置GPIOB的初始化参数。

  5. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;:同样将GPIOB的引脚1配置为推挽输出模式。

  6. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;:选择了GPIOB的引脚1作为第二个LED连接的引脚。

  7. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;:配置了GPIO的输出速度为50MHz。

  8. GPIO_Init(GPIOB, &GPIO_InitStructure);:根据上述配置初始化GPIOB的引脚1。

        这段代码的作用与之前的LED1初始化函数类似,是初始化另一个LED连接的GPIO引脚,配置为推挽输出模式,并设置输出速度为50MHz。

#include "stm32f10x.h"                  // Device headervoid LED2_Init(void)
{// 1、开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);// 2、调用Init函数// 2-1、需要先进行结构体的定义GPIO_InitTypeDef GPIO_InitStructure;// 数据信号的推挽输出,这个时候STM32对高低电平拥有绝对的控制权,此时LED灯长脚插在PA0口,短脚插在负极,高电平驱动也可以闪烁GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 变成了OD就成了开漏模式,就无法高电平驱动了GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;  // 选择Pin_0是因为用的是GPIOA的0号引脚GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  // 输出速度GPIO_Init(GPIOB,&GPIO_InitStructure);
}

03-延时函数实现

       Delay的实现如下:

        Delay.h文件

        这个.h文件定义了三个延时函数的声明,分别是Delay_usDelay_msDelay_s,用于提供微秒级、毫秒级和秒级的延时功能。这些声明可以让其他源文件包含这个头文件后直接调用这些函数,而不需要知道函数的具体实现细节。同时,文件开头使用了#ifndef#define宏,以及#endif来实现头文件保护,确保在同一编译单元中只包含一次该头文件内容,防止重复定义。

#ifndef __DELAY_H
#define __DELAY_Hvoid Delay_us(uint32_t us);  // 微秒延时
void Delay_ms(uint32_t ms);  // 毫秒延时
void Delay_s(uint32_t s);    // 秒延时#endif

        Delay.cpp文件:这段代码提供了三个延时函数:Delay_usDelay_msDelay_s,分别用于提供微秒级、毫秒级和秒级的延时。下面分别解释这三个函数:

  1. void Delay_us(uint32_t xus):这个函数用于提供微秒级的延时。它使用了STM32的系统滴答(SysTick)定时器来实现延时。xus参数是要延时的微秒数,通过乘以72(STM32的系统时钟频率,HCLK,假设为72MHz)来计算出SysTick定时器的重装载值。然后设置SysTick定时器的时钟源为HCLK,启动定时器,等待定时器计数到0,最后关闭定时器。

  2. void Delay_ms(uint32_t xms):这个函数用于提供毫秒级的延时。它通过调用Delay_us函数来实现,每次调用Delay_us函数延时1000微秒,即1毫秒,通过xms参数指定的次数来控制总的延时毫秒数。

  3. void Delay_s(uint32_t xs):这个函数用于提供秒级的延时。它通过调用Delay_ms函数来实现,每次调用Delay_ms函数延时1000毫秒,即1秒,通过xs参数指定的次数来控制总的延时秒数。

        这三个延时函数都可以在STM32的开发中用于控制程序的执行流程,实现特定的延时效果。

#include "stm32f10x.h"/*** @brief  微秒级延时* @param  xus 延时时长,范围:0~233015* @retval 无*/
void Delay_us(uint32_t xus)
{SysTick->LOAD = 72 * xus;				//设置定时器重装值SysTick->VAL = 0x00;					//清空当前计数值SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器while(!(SysTick->CTRL & 0x00010000));	//等待计数到0SysTick->CTRL = 0x00000004;				//关闭定时器
}/*** @brief  毫秒级延时* @param  xms 延时时长,范围:0~4294967295* @retval 无*/
void Delay_ms(uint32_t xms)
{while(xms--){Delay_us(1000);}
}/*** @brief  秒级延时* @param  xs 延时时长,范围:0~4294967295* @retval 无*/
void Delay_s(uint32_t xs)
{while(xs--){Delay_ms(1000);}
} 

04-主函数实现

       主函数实现代码如下:

        这段主函数代码主要完成了以下几个任务:

  1. 包含了必要的头文件,如STM32F10x系列的设备头文件、延时函数头文件、LED1和LED2的头文件。

  2. 在main函数中调用了LED1_Init和LED2_Init函数,分别初始化了两个LED的引脚。

  3. 进入一个无限循环(while(1)),在循环中实现了LED1和LED2的闪烁效果:

    a. 首先点亮LED1,延时1000ms,然后熄灭LED1,延时1000ms,实现LED1每秒闪烁一次的效果。

    b. 接着点亮LED2,延时500ms,然后熄灭LED2,延时500ms,实现LED2每0.5秒闪烁一次的效果。

        这样,主函数完成了对两个LED灯的初始化和控制,使它们交替闪烁。

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "LED2.h"int main(void){LED1_Init();LED2_Init();// 4、设置低电平,LED灯亮起
//	GPIO_ResetBits(GPIOA,GPIO_Pin_1);// 5、也可以GPIO_WriteBit()函数设置高低电平// 前两个参数和Set和Reset一样,第三个参数用于清除端口值,和设置端口值// 如果参数=Bit_RESET,清除端口值,设置为低电平,灯亮;反之参数=Bit_SET,为高电平,灯灭
//	GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);// 6、若是需要实现LED灯闪烁的命令,就需要在While死循环中进行一些设置while(1){// 点亮 两个函数都可以
//		GPIO_ResetBits(GPIOA,GPIO_Pin_0);
//		Delay_ms(500);  // 延时函数直接调用即可
//	    GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);
//		GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)0);  // 0为低电平// 7、这里加延时函数
//		Delay_ms(500);// 熄灭 
//		GPIO_SetBits(GPIOA,GPIO_Pin_0);
//		Delay_ms(500);
//	    GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET); 如果这里想要直接使用自己定义的参数代替第三个参数,
//		GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)1);  // 1为高电平//  (BitAction)0 需要加//	    Delay_ms(500);GPIO_SetBits(GPIOA,GPIO_Pin_1);Delay_ms(1000);GPIO_ResetBits(GPIOA,GPIO_Pin_1);Delay_ms(1000);GPIO_SetBits(GPIOB,GPIO_Pin_1);Delay_ms(500);GPIO_ResetBits(GPIOB,GPIO_Pin_1);Delay_ms(500);}}

总结

       实现LED灯闪烁的核心在于控制GPIO引脚的高低电平状态和添加适当的延时。在STM32上,通过操作寄存器来控制GPIO引脚状态,然后利用延时函数来控制LED的亮灭间隔。

总结如下步骤:

  1. 包含必要的头文件,如STM32的设备头文件和延时函数头文件。

  2. 初始化LED的GPIO引脚,可以通过调用初始化函数实现。

  3. 进入一个无限循环,通常使用while(1)

  4. 在循环中,通过操作GPIO引脚的寄存器,设置LED引脚的状态,从而控制LED的亮灭。

  5. 在LED状态改变后,添加适当的延时,以控制LED的亮灭间隔。

  6. 循环执行步骤4和步骤5,实现LED的闪烁效果。

        这样,通过简单的C语言代码,就可以在STM32上实现LED的闪烁功能。

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

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

相关文章

【机器学习-23】关联规则(Apriori)算法:介绍、应用与实现

在现代数据分析中,经常需要从大规模数据集中挖掘有用的信息。关联规则挖掘是一种强大的技术,可以揭示数据中的隐藏关系和规律。本文将介绍如何使用Python进行关联规则挖掘,以帮助您发现数据中的有趣模式。 一、引言 1. 简要介绍关联规则学习…

动态路由实验—OSPF

动态路由协议实验-------OSPF 链路状态路由选择协议又被称为最短路径优先协议&#xff0c;它基SPF&#xff08;shortest path first &#xff09;算法 实验要求&#xff1a;各个PC之间能够互通 1.四台PC配置如下 PC1 PC2 PC3 PC4 2.配置各个交换机的口子的IP R1 <HUAWE…

spiderfoot一键扫描IP信息(KALI工具系列九)

目录 1、KALI LINUX简介 2、spiderfoot工具简介 3、在KALI中使用spiderfoot 3.1 目标主机IP&#xff08;win&#xff09; 3.2 KALI的IP 4、命令示例 4.1 web访问 4.2 扫描并进行DNS解析 4.3 全面扫描 5、总结 1、KALI LINUX简介 Kali Linux 是一个功能强大、多才多…

基于docxtpl的模板生成Word

docxtpl是一个用于生成Microsoft Word文档的模板引擎库。它结合了docx模块和Jinja2模板引擎&#xff0c;使用户能够使用Microsoft Word模板文件并在其中填充动态数据。这个库提供了一种方便的方式来生成个性化的Word文档&#xff0c;并支持条件语句、循环语句和变量等控制结构&…

如何在 Elasticsearch 中选择精确 kNN 搜索和近似 kNN 搜索

作者&#xff1a;来自 Elastic Carlos Delgado kNN 是什么&#xff1f; 语义搜索&#xff08;semantic search&#xff09;是相关性排名的强大工具。 它使你不仅可以使用关键字&#xff0c;还可以考虑文档和查询的实际含义。 语义搜索基于向量搜索&#xff08;vector search&…

大数据工具之HIVE-参数调优,调度乱码(二)

一、调度乱码 在利用HUE工具,搭建WORKFLOW流程的过程中,如果直接执行hivesql数据正常,不会出现乱码现象,如果利用WORKFLOW搭建的流程,进行数据的拉取,会出现数据中文乱码现象,这些乱码主要是由于select 中的硬编码中文导致出现的现象 具体现象如下: select case when …

TG5032CGN TCXO 超高稳定10pin端子型适用于汽车动力转向控制器

TG5032CGN TCXO / VC-TCXO是一款应用广泛的晶振&#xff0c;具有超高稳定性&#xff0c;CMOS输出和使用晶体基振的削波正弦波输出形式。且有低相位噪声优势&#xff0c;是温补晶体振荡器(TCXO)和压控晶体振荡器(VCXO)结合的产物&#xff0c;具有TCXO和VCXO的共同优点&#xff0…

微信小程序上线必备:SSL证书申请以及安装

一、认识ssl证书 1、ssl证书是什么&#xff1f; SSL证书&#xff0c;全称Secure Socket Layer Certificate&#xff0c;是一种数字证书&#xff0c;它遵循SSL&#xff08;现在通常指TLS&#xff0c;Transport Layer Security&#xff09;协议标准&#xff0c;用于在客户端&…

SpringCloud系列(26)--OpenFeign超时控制

前言&#xff1a;在上一章节中我们简单的介绍了如何使用OprnFeign去调用微服务&#xff0c;因为消费侧和服务侧是两个不同的微服务&#xff0c;这样可能会出现超时的现象&#xff0c;例如服务侧需要3秒处理任何才能返回结果&#xff0c;但消费侧可能2秒就断开连接了&#xff0c…

【深度学习】2.单层感知机

目标&#xff1a; 实现一个简单的二分类模型的训练过程&#xff0c;通过模拟数据集进行训练和优化&#xff0c;训练目标是使模型能够根据输入特征正确分类数据。 演示: 1.通过PyTorch生成了一个模拟的二分类数据集&#xff0c;包括特征矩阵data_x和对应的标签数据data_y。标签…

加密与安全_AES RSA 密钥对生成及PEM格式的代码实现

文章目录 RSA&#xff08;非对称&#xff09;和AES&#xff08;对称&#xff09;加密算法一、RSA&#xff08;Rivest-Shamir-Adleman&#xff09;二、AES&#xff08;Advanced Encryption Standard&#xff09; RSA加密三种填充模式一、RSA填充模式二、常见的RSA填充模式组合三…

新业务 新市场 | 灵途科技新品亮相马来西亚亚洲防务展

5月6日&#xff0c;灵途科技携新品模组与武汉长盈通光电&#xff08;股票代码&#xff1a;688143&#xff09;携手参加第18届马来西亚亚洲防务展。首次亮相海外&#xff0c;灵途科技便收获全球客户的广泛关注&#xff0c;为公司海外市场开拓打下坚实基础。 灵途科技与长盈通共同…

Dbs封装_连接池

1.Dbs封装 每一个数据库都对应着一个dao 每个dao势必存在公共部分 我们需要将公共部分抽取出来 封装成一个工具类 保留个性化代码即可 我们的工具类一般命名为xxxs 比如Strings 就是字符串相关的工具类 而工具类 我们将其放置于util包中我们以是否有<T>区分泛型方法和非泛…

Python并发编程学习记录

1、初识并发编程 1.1、串行&#xff0c;并行&#xff0c;并发 串行(serial)&#xff1a;一个cpu上按顺序完成多个任务&#xff1b; 并行(parallelism)&#xff1a;任务数小于或等于cup核数&#xff0c;多个任务是同时执行的&#xff1b; 并发(concurrency)&#xff1a;一个…

计算机SCI期刊,IF=8+,专业性强,潜力新刊!

一、期刊名称 Journal of Big data 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;计算机科学 影响因子&#xff1a;8.1 中科院分区&#xff1a;2区 出版方式&#xff1a;开放出版 版面费&#xff1a;$1990 三、期刊征稿范围 《大数据杂志》发表了关于…

2024年【T电梯修理】考试内容及T电梯修理新版试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【T电梯修理】考试内容及T电梯修理新版试题&#xff0c;包含T电梯修理考试内容答案和解析及T电梯修理新版试题练习。安全生产模拟考试一点通结合国家T电梯修理考试最新大纲及T电梯修理考试真题汇总&#xff0c;…

(2024,SDE,对抗薛定谔桥匹配,离散时间迭代马尔可夫拟合,去噪扩散 GAN)

Adversarial Schrdinger Bridge Matching 公众号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 1. 简介 4. 实验 0. 摘要 薛定谔桥&#xff08;Schrdinger Bridge&#xff0c;SB&…

浮点型比较大小

浮点数的存储形式 浮点数按照在内存中所占字节数和数值范围&#xff0c;可以分为浮点型&#xff0c;双精度浮点型和长双浮点型数。 代码&#xff1a; printf("lgn:%e \n", pow(exp(1), 100));printf("lgn:%f ", pow(exp(1), 100));输出结果&#xff1a; …

CLIP 论文的关键内容

CLIP 论文整体架构 该论文总共有 48 页&#xff0c;除去最后的补充材料十页去掉&#xff0c;正文也还有三十多页&#xff0c;其中大部分篇幅都留给了实验和响应的一些分析。 从头开始的话&#xff0c;第一页就是摘要&#xff0c;接下来一页多是引言&#xff0c;接下来的两页就…

python文件IO基础知识

目录 1.open函数打开文件 2.文件对象读写数据和关闭 3.文本文件和二进制文件的区别 4.编码和解码 读写文本文件时 读写二进制文件时 5.文件指针位置 6.文件缓存区与flush()方法 1.open函数打开文件 使用 open 函数创建一个文件对象&#xff0c;read 方法来读取数据&…