STM32学习笔记|LED 闪烁、流水灯与蜂鸣器驱动

前言

本节是 STM32 入门体系中第一个完整的硬件实操章节,承接工程搭建、GPIO 基础原理的前置内容,通过三个最经典的外设案例 ------LED 单灯闪烁、多灯流水灯、有源蜂鸣器驱动,完整掌握 STM32 通用 IO 口配置为推挽输出模式 的全流程,建立库函数配置硬件 → 代码控制电平 → 外设执行动作的嵌入式开发核心思维。

本节学习目标

  1. 掌握GPIO_Init标准库函数的参数含义与调用流程
  2. 理解延时函数在 IO 时序控制中的作用
  3. 独立完成 LED 闪烁、流水灯、蜂鸣器发声三个基础实验
  4. 建立嵌入式程序「初始化 + 死循环」的架构认知

一、GPIO 初始化通用模板

scss 复制代码
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟									
                                            //使用各个外设前必须开启时钟,否则对外设的操作无效
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;		//定义结构体变量
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	//GPIO模式,赋值为推挽输出模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		//GPIO引脚,赋值为第0号引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//GPIO速度,赋值为50MHz
	
	GPIO_Init(GPIOA, &GPIO_InitStructure);		//将赋值后的构体变量传递给GPIO_Init函数
						 //函数内部会自动根据结构体的参数配置相应寄存器
							//实现GPIOA的初始化
  • 浮空输入 IN_FLOATING
  • 上拉输入 IPU
  • 下拉输入 IPD
  • 模拟输入 AIN
  • 推挽输出 Out_PP
  • 开漏输出 Out_OD
  • 复用推挽输出 AF_PP
  • 复用开漏输出 AF_OD

GPIO 推挽输出模式

STM32 的 GPIO 配置为输出时,最常用的是推挽输出(GPIO_Mode_Out_PP)

  • 推挽输出模式下 IO 口可直接输出高低电平,驱动能力强,适配 LED、蜂鸣器这类小功率外设

  • 固定配置三步法:开启对应端口时钟 → 填充 GPIO 初始化结构体 → 调用GPIO_Init完成硬件配置

  • 核心输出控制函数:

    • GPIO_SetBits:指定引脚输出高电平
    • GPIO_ResetBits:指定引脚输出低电平
    • GPIO_WriteBit:直接写入引脚电平状态

二、LED闪烁实验

1.实验原理

LED 亮灭由引脚电平直接控制:当 LED 阴极接 GPIO、阳极通过电阻接电源时,引脚输出低电平 LED 点亮,输出高电平 LED 熄灭。闪烁的核心逻辑是电平翻转 + 延时保持:设置引脚电平 → 延时维持状态 → 翻转电平 → 再次延时,在死循环中往复执行。

未剪裁的LED灯长脚位阳极,短脚为阴极

接线图如下图所示

2.LED闪烁核心逻辑

while 复制代码
	{
		/*点亮LED持续一段时间,熄灭LED持续一段时间*/
		GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_RESET);//点亮LED
		Delay_ms(500);
		GPIO_WriteBit(GPIOA,GPIO_Pin_0,Bit_SET);//熄灭LED
		Delay_ms(500);
		
		GPIO_ResetBits(GPIOA,GPIO_Pin_0);
		Delay_ms(500);
		GPIO_SetBits(GPIOA,GPIO_Pin_0);
		Delay_ms(500);
		
		GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)0);
		Delay_ms(500);
		GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)1);
		Delay_ms(500);//如果直接使0为低电平,1为高电平会导致警告:"枚举类型出现其他变量"321
		//所以需要加上进行强制类型转换,把他们转换为Bitaction枚举类型
		
	}

注意:使用已准备好的延时函数Delay模块需要在主函数开头加入头文件❗❗❗同时一定要学会如何在工程中加入函数模块

三、LED 流水灯

1.LED 流水灯实现原理

在单灯闪烁的基础上扩展,将多个 LED 分别接入不同 GPIO 引脚,常见两种实现思路:

  • 顺序点亮法:依次点亮第 1 个灯、延时、熄灭,再点亮第 2 个灯...... 循环执行,逻辑直观易懂。
  • 移位遍历法:通过位运算批量控制端口电平,代码更简洁,适合多引脚场景流水灯重点锻炼多 IO 口的批量管理能力,帮助理解端口寄存器与引脚的对应关系。

本次只考虑第一种方法

接线图如下图所示

2.LED流水灯核心逻辑

scss 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"

int main(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
															//使用各个外设前必须开启时钟,否则对外设的操作无效
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;					//定义结构体变量
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//GPIO模式,赋值为推挽输出模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;				//GPIO引脚,赋值为所有引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//GPIO速度,赋值为50MHz
	
	GPIO_Init(GPIOA, &GPIO_InitStructure);					//将赋值后的构体变量传递给GPIO_Init函数
															//函数内部会自动根据结构体的参数配置相应寄存器
															//实现GPIOA的初始化
	
	/*主循环,循环体内的代码会一直循环执行*/
	while (1)
	{
		/*使用GPIO_Write,同时设置GPIOA所有引脚的高低电平,实现LED流水灯*/
		GPIO_Write(GPIOA, ~0x0001);	//0000 0000 0000 0001,PA0引脚为低电平,其他引脚均为高电平,注意数据有按位取反
		Delay_ms(100);				//延时100ms
		GPIO_Write(GPIOA, ~0x0002);	//0000 0000 0000 0010,PA1引脚为低电平,其他引脚均为高电平
		Delay_ms(100);				//延时100ms
		GPIO_Write(GPIOA, ~0x0004);	//0000 0000 0000 0100,PA2引脚为低电平,其他引脚均为高电平
		Delay_ms(100);				//延时100ms
		GPIO_Write(GPIOA, ~0x0008);	//0000 0000 0000 1000,PA3引脚为低电平,其他引脚均为高电平
		Delay_ms(100);				//延时100ms
		GPIO_Write(GPIOA, ~0x0010);	//0000 0000 0001 0000,PA4引脚为低电平,其他引脚均为高电平
		Delay_ms(100);				//延时100ms
		GPIO_Write(GPIOA, ~0x0020);	//0000 0000 0010 0000,PA5引脚为低电平,其他引脚均为高电平
		Delay_ms(100);				//延时100ms
		GPIO_Write(GPIOA, ~0x0040);	//0000 0000 0100 0000,PA6引脚为低电平,其他引脚均为高电平
		Delay_ms(100);				//延时100ms
		GPIO_Write(GPIOA, ~0x0080);	//0000 0000 1000 0000,PA7引脚为低电平,其他引脚均为高电平
		Delay_ms(100);				//延时100ms
	}
}

流水灯用到GPIOA的0到7号端口,需要加一些端口。加入端口方式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|......; //一直到7号端口 使用按位或操作逻辑

或者直接使用GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;//将16个端口全部配置为推挽输出模式

四、蜂鸣器驱动

1.蜂鸣器驱动原理

有源蜂鸣器内部自带振荡源,通电即发出固定频率声音,驱动逻辑与 LED 完全一致: 输出对应电平使蜂鸣器通电发声,翻转电平则停止 通过「发声 + 延时 + 停止 + 延时」的循环,可实现间歇报警效果 注意有源蜂鸣器区分正负极,接线错误会导致无声音输出

接线图如下图所示

VCC正极接入正极供电孔,GND负极接到负极供电孔,I/O控制极选择一个IO口接入

注意:IO口选择中A15,B3,B4请勿选择,从STM32引脚定义图可知这三个口默认是JTAG调试端口,如果用作普通端口还需要进行一定的配置。

2.蜂鸣器驱动核心逻辑

scss 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"

int main(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	//开启GPIOB的时钟
															//使用各个外设前必须开启时钟,否则对外设的操作无效
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;					//定义结构体变量
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//GPIO模式,赋值为推挽输出模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;				//GPIO引脚,赋值为第12号引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//GPIO速度,赋值为50MHz
	
	GPIO_Init(GPIOB, &GPIO_InitStructure);					//将赋值后的构体变量传递给GPIO_Init函数
															//函数内部会自动根据结构体的参数配置相应寄存器
															//实现GPIOB的初始化
	
	/*主循环,循环体内的代码会一直循环执行*/
	while (1)
	{
		GPIO_ResetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为低电平,蜂鸣器鸣叫
		Delay_ms(300);							//延时100ms
		GPIO_SetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为高电平,蜂鸣器停止
		Delay_ms(500);							//延时100ms
		GPIO_ResetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为低电平,蜂鸣器鸣叫
		Delay_ms(300);							//延时100ms
		GPIO_SetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为高电平,蜂鸣器停止
		Delay_ms(500);							//延时700ms
	}
}

注意时钟为GPIOB,端口为Pin12

五、本小节问题与总结

1.按位或操作逻辑

2,推挽输出、开漏输出驱动问题

3.本节课实体接线图

相关推荐
Dr.kangder1 小时前
嵌入式软件单元测试:从理论到实践
架构·单元测试·嵌入式·测试覆盖率
K成长日志2 小时前
BLE链路层空口包--数据物理信道PDU
网络·物联网·网络协议·嵌入式·蓝牙·iot·ble
pie_thn2 天前
基于端侧大模型的嵌入式 Skill 调度引擎实现智能业务生成的尝试
大模型·嵌入式·skill
Freak嵌入式3 天前
从慢到快:MicroPython 性能优化的完整步骤与实战案例
嵌入式
大辉狼_音频架构4 天前
AudioReach Plugin 机制问题解答
嵌入式·音视频开发
大辉狼_音频架构4 天前
AudioReach:Tinyalsa PCM Plugin 机制
嵌入式·音视频开发
feasibility.4 天前
从数字智能到物理智能体:深度解构具身智能时代的边缘计算、嵌入式实时系统与多形态智能体
人工智能·机器人·自动驾驶·嵌入式·无人机·具身智能·智能体
ajassi20005 天前
AI语音智能体开发日记(一)如何为“小智”服务器启用并调试 License 功能
笔记·ai·嵌入式·ai编程
ARM+FPGA+AI工业主板定制专家6 天前
国产化RK3576+FPGA架构|晶圆传输机器人高速定位+AI瑕疵检测一体化方案
fpga开发·架构·机器人·嵌入式·fpga·工控·机器人运控