当前位置: 首页 > news >正文

STM32单片机LED灯的闪烁及流水效果

注意:

本文章默认您已经将STM32单片机的启动项以及库函数等前期工作准备就绪。

一、材料清单

1.STM32F103C8T6

2.面包板

3.面包板跳线若干

4.STLINK(usb款)

5.LED灯若干

6.keil5软件

二、接线

1.STLINK连接STM32开发板示意图

图片来源:bilibili江协科技

2.LED闪烁接线示意图

图片来源:bilibili江协科技

3.LED流水灯接线示意图

图片来源:bilibili江协科技

三、程序编程

打开keil5创建新项目:

先编写延时函数Delay,这里我们选择新增一个文件夹的形式。

添加一个System文件夹并添加源文件Delay.c以及头文件Delay.h:

Delay.c代码如下:

#include "stm32f10x.h" void Delay_us(uint32_t xus) { SysTick->LOAD = 72 * xus; //设置定时器重装值 SysTick->VAL = 0x00; //清空当前计数值 SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器 while(!(SysTick->CTRL & 0x00010000)); //等待计数到0 SysTick->CTRL = 0x00000004; //关闭定时器 } void Delay_ms(uint32_t xms) { while(xms--) { Delay_us(1000); } } void Delay_s(uint32_t xs) { while(xs--) { Delay_ms(1000); } }

Delay.h代码如下:

#ifndef __DELAY_H #define __DELAY_H void Delay_us(uint32_t us); void Delay_ms(uint32_t ms); void Delay_s(uint32_t s); #endif

写好之后不要忘记在编译器中添加该文件夹,以防编译运行时无法调用该文件中的延时函数

代码说明:在STM32单片机中有几种模式可以写入,这里我们使用标准库函数调用GPIO输出数据。

3.1LED闪烁

RCC_APB2PeriphClockCmd,是STM32 标准库(StdPeriph_Library)中用于使能 / 失能 APB2 外设时钟的核心函数,所有挂载在 APB2 总线上的外设(如 GPIO、USART1、SPI1、ADC 等),必须先通过该函数开启时钟才能正常使用。

我们在keil中右键该函数

在这里我们可以看到该函数的说明及参数如何使用:

我们要利用GPIOA端控制输出,所以参数为RCC_APB2Periph_GPIOA,第二个参数选ENABLE。

第二行代码则是决定GPIO的模式,包括输出模式、输出端口、输出速度。

GPIO_InitTypeDef Typedefname(自定义结构体名)

GPIO_InitTypeDef GPIO_InitStructure;//定义结构体决定GPIO的模式、端口、及速度
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

端口输出模式有以下8种我们跳到定义:

枚举常量十六进制值中文含义典型使用场景
GPIO_Mode_AIN0x0模拟输入接 ADC 采样、模拟传感器(如温敏)
GPIO_Mode_IN_FLOATING0x04浮空输入按键检测、USART 接收引脚
GPIO_Mode_IPD0x28下拉输入按键检测(默认低电平,按下为高)
GPIO_Mode_IPU0x48上拉输入按键检测(默认高电平,按下为低)
GPIO_Mode_Out_OD0x14开漏输出I2C 通信、多设备共用总线
GPIO_Mode_Out_PP0x10推挽输出LED 灯、继电器、普通数字输出
GPIO_Mode_AF_OD0x1C复用开漏输出复用外设(如 USART、SPI)开漏模式
GPIO_Mode_AF_PP0x18复用推挽输出复用外设(如 USART、SPI)推挽模式

我们一般选推挽输出模式,在该模式下高低电平都能够驱动
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;我们选择A0口
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;速度选择50Mhz即可。
GPIO_Init(GPIOA, &GPIO_InitStructure);//所有参数一次性传给初始化函数,无需多次调用函数传递单个参数。

我们写为实现功能的部份:

我们LED灯点亮的方式是低电平点亮的,在这里我们需要先将A0口置为低电平,这里我们需要用到一个函数:GPIO_ResetBits, 该函数的作用是将指定端口置为低电平。

我们查看该函数说明,因为我们用的是GPIOA口,所以第一个参数为GPIOA,端口为A0口,所以第二个参数是GPIOA_Pin_0;

要实现闪烁效果的花需要高低电平依次交替,我们还需要一个将端口置为高电平的函数:GPIO_SetBits,该函数的作用是将指定端口置为高电平。用法与上述效果一致。

所以该部分代码为:

while (1) { GPIO_ResetBits(GPIOA,GPIO_Pin_0); Delay_ms(1000); GPIO_SetBits(GPIOA,GPIO_Pin_0); Delay_ms(1000); }

我们将代码进行整合得到完整代码如下:

#include "stm32f10x.h" // Device header #include "Delay.h" int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//STM32 标准库中开启 GPIOA 外设时钟的核心语句 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//点亮Led灯为低电平点亮,推挽输出模式,推挽输出模式下高低电平都有驱动能力 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//因为点亮的端口为A0,故为GPIO_Pin_0 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度选为50Mhz GPIO_Init(GPIOA, &GPIO_InitStructure);//形参要传递,指针传地址 while (1) { //LED闪烁: GPIO_ResetBits(GPIOA,GPIO_Pin_0); Delay_ms(1000); GPIO_SetBits(GPIOA,GPIO_Pin_0); Delay_ms(1000); } }

3.2LED流水灯

接下来我们实现LED流水灯效果;

我们知道了LED灯闪烁的效果便可以知道流水灯是如何实现,唯一的区别就是,LED闪烁只定义了一个口,而LED流水灯需要定义8个口。A0~A7,那么我们该如何定义呢?

我们跳转到GPIO_Pin的定义查看一下:

这里会出现在下面,GPIO_Pin有多个,我们选择member这一项,双击打开。

然后选择,按住Ctrl+F

点击Find Next

可以看到:

下列就是各个端口对应的16进制的值。

首先我们需要将A0-A7端口全部启用,这里有两种方法:

第一种:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;

这种方法是一个一个端口来定义,从A0-A7;

第二种:

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

这种方法就是将A0-A15的全部端口都启用,比较省时间。

启用端口后,我们完成功能实现部份的代码:

while (1) { GPIO_Write(GPIOA, ~0x0001);//16进制0x0001对应二进制为0000 0000 0000 0001;最后一位1对应A0口倒数第二位对应A1口,依次往上; Delay_ms(500); //因为我们是低电平点亮,所以要加取反,反之则不用加; GPIO_Write(GPIOA, ~0x0002);//16进制0x0002对应二进制为0000 0000 0000 0010; Delay_ms(500); GPIO_Write(GPIOA, ~0x0004);//16进制0x0001对应二进制为0000 0000 0000 0100; Delay_ms(500); GPIO_Write(GPIOA, ~0x0008);//16进制0x0001对应二进制为0000 0000 0001 0000; Delay_ms(500); GPIO_Write(GPIOA, ~0x0010);//16进制0x0001对应二进制为0000 0000 0010 0000; Delay_ms(500); GPIO_Write(GPIOA, ~0x0020);//16进制0x0001对应二进制为0000 0000 0100 0000; Delay_ms(500); GPIO_Write(GPIOA, ~0x0040);//16进制0x0001对应二进制为0000 0000 1000 0000; Delay_ms(500); GPIO_Write(GPIOA, ~0x0080);//16进制0x0001对应二进制为0000 0001 0000 000; Delay_ms(500); }

将代码整合后得到完整代码如下:

#include "stm32f10x.h" // Device header #include "Delay.h" int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); while (1) { GPIO_Write(GPIOA, ~0x0001);//16进制0x0001对应二进制为0000 0000 0000 0001;最后一位1对应A0口倒数第二位对应A1口,依次往上; Delay_ms(500); //因为我们是低电平点亮,所以要加取反,反之则不用加; GPIO_Write(GPIOA, ~0x0002);//16进制0x0002对应二进制为0000 0000 0000 0010; Delay_ms(500); GPIO_Write(GPIOA, ~0x0004);//16进制0x0001对应二进制为0000 0000 0000 0100; Delay_ms(500); GPIO_Write(GPIOA, ~0x0008);//16进制0x0001对应二进制为0000 0000 0001 0000; Delay_ms(500); GPIO_Write(GPIOA, ~0x0010);//16进制0x0001对应二进制为0000 0000 0010 0000; Delay_ms(500); GPIO_Write(GPIOA, ~0x0020);//16进制0x0001对应二进制为0000 0000 0100 0000; Delay_ms(500); GPIO_Write(GPIOA, ~0x0040);//16进制0x0001对应二进制为0000 0000 1000 0000; Delay_ms(500); GPIO_Write(GPIOA, ~0x0080);//16进制0x0001对应二进制为0000 0001 0000 000; Delay_ms(500); } }

3.3蜂鸣器发声

这个部分和LED闪烁类似,仅是将A0换为B12,这里不做过多赘述。

完整代码:

#include "stm32f10x.h" // Device header #include "Delay.h" int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//STM32 标准库中开启 GPIOB 外设时钟的核心语句 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出模式下高低电平都可驱动 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;//启用B12口 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度选为50Mhz GPIO_Init(GPIOB, &GPIO_InitStructure);//形参要传递,指针传地址 while (1) { GPIO_ResetBits(GPIOB,GPIO_Pin_12); Delay_ms(100); GPIO_SetBits(GPIOB,GPIO_Pin_12); Delay_ms(100); GPIO_ResetBits(GPIOB,GPIO_Pin_12); Delay_ms(100); GPIO_SetBits(GPIOB,GPIO_Pin_12); Delay_ms(500); } }

四、结语

谢谢观看,如果对您有帮助请留个免费的赞和收藏,谢谢啦!

http://www.jsqmd.com/news/492935/

相关文章:

  • 基于Mirage Flow的个性化学习推荐系统构建
  • 每天了解几个MCP SERVER:极速分析神器!亿级数据秒级查询,ClickHouse 让大数据分析飞起
  • 免费降ai的正确姿势:避开这些坑少走弯路
  • 【Java生产级避坑指南】15. 事务隔离级别幻读实锤:PostgreSQL与MySQL差异化防御实战(含完整实验+代码)
  • 第六篇:安全认证与中间件(超详细版)
  • 社区分享 | 从零开始学习 TinyML(三)
  • 知网/维普/万方AI检测怎么免费查?方法都在这了
  • 每天了解几个MCP SERVER:云端媒体库!AI 自动处理图片视频,Cloudinary 让媒体管理更简单
  • 【解刊】IEEE Trans系列新宠:中科院1区TOP期刊,国人作者占比近八成领跑全球!
  • 毕业前一周紧急降AI率:免费+低成本方案全攻略
  • 第七篇:FastAPI集成SQLAlchemy数据库
  • 线性回归代码
  • 告别数据孤岛:基于WebDAV的Zotero与InfiniCLOUD跨平台同步实战
  • Linux操作系统(一)
  • 免费降AI率工具横评:嘎嘎vs比话vs率零谁更值
  • 深入分代 GC:新生代内存不足时的对象晋升规则
  • 用XGO Rider教孩子学编程:从Scratch到Python的AI机器人实战教程
  • Linux apt commands All In One
  • 游戏原画师福音:Kook Zimage真实幻想Turbo保姆级入门教程
  • 《道德经》第三章
  • 草莓成熟度目标检测数据集(2000张图片已标注)| YOLO训练数据集 AI视觉检测
  • 【已解决】xFormers安装报错:CPATH环境变量缺失导致cuda_runtime.h找不到
  • 【YOLOv11工业级实战】32. 超轻量分割模型实战:YOLOv11-seg剪枝+蒸馏压缩至2MB(精度仅降2%)
  • 解锁Edge内置Copilot:无需插件,一键直达GPT-4 Turbo智能助手
  • Z-Image Turbo性能评测:不同硬件下的生成速度对比
  • ESP32智慧时钟:嵌入式物联网教学硬件平台设计
  • 如何在MacBook上安装部署原生openclaw
  • 嘉立创EDA专业版多账号管理技巧:如何避免激活文件冲突
  • 一篇文章掌握PyQt5高级表格开发:从零复现工业级加工步骤设置界面
  • wan2.1-vae惊艳效果展示:人物写实度对比——发丝/皮肤纹理/瞳孔反光细节放大