环境配好、接线踩坑之后,接下来就是让外设动起来。这组实验全部围绕 GPIO 输出:先点亮一颗 LED,再扩展成八路流水灯,最后用同样的思路驱动蜂鸣器。三个实验的代码都在工程的 User\main.c 里(如 3-1点亮LED灯、3-2流水灯、3-3蜂鸣器)。
一、点亮第一颗 LED
之前两天都在跟接线较劲,怀疑人生;当 LED 终于亮起来的时候,成就感爆棚。核心教训:嵌入式开发,硬件接线和软件一样重要。
// PA0 配置为推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 低电平点亮 LED
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
关键理解:
- GPIO 配置:推挽输出模式,速度 50MHz
- LED 驱动:低电平有效,
GPIO_ResetBits拉低点亮 - 当前状态:常亮,
while(1)为空
二、流水灯:PA0-PA7 八个 LED
在单颗 LED 的基础上,实现 PA0-PA7 八个 LED 流水灯效果。
// 配置 GPIOA 所有引脚为推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; // 一次性配置所有引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 流水灯核心:GPIO_Write 一次写入 16 位数据
while(1)
{
GPIO_Write(GPIOA, ~0x0001); // 0x0001取反=0xFFFE,PA0低电平点亮
Delay_ms(300);
GPIO_Write(GPIOA, ~0x0002); // PA1点亮
Delay_ms(300);
GPIO_Write(GPIOA, ~0x0004); // PA2点亮
// ... 依次类推到 PA7
}
GPIO 操作函数对比
| 函数 | 作用 | 使用场景 |
|---|---|---|
GPIO_ResetBits | 单引脚拉低 | 单个LED控制 |
GPIO_SetBits | 单引脚拉高 | 单个LED控制 |
GPIO_WriteBit | 按位设置 | 单引脚精确控制 |
GPIO_Write | 16位整体写入 | 多引脚同时控制 |
位操作技巧
~0x0001=0xFFFE→ PA0 低电平(点亮),其余高电平(熄灭)~0x0002=0xFFFD→ PA1 低电平(点亮)- 位左移:
0x0001 << n可以简化代码
优化思路
当前代码是 8 行重复,可以用循环 + 移位简化:
uint16_t led = 0x0001;
while(1)
{
GPIO_Write(GPIOA, ~led);
Delay_ms(300);
led <<= 1;
if(led > 0x0080) led = 0x0001; // 从PA7回到PA0
}
三、蜂鸣器控制
与 LED 完全同构的实验:PA9 推挽输出,低电平响。
// 配置 PA9 为推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 蜂鸣器控制:低电平响,高电平停
while(1)
{
GPIO_ResetBits(GPIOA, GPIO_Pin_9); // PA9拉低→蜂鸣器响
Delay_ms(300);
GPIO_SetBits(GPIOA, GPIO_Pin_9); // PA9拉高→蜂鸣器停
Delay_ms(300);
}
关键理解:
- 蜂鸣器是低电平触发:
ResetBits响,SetBits停 - 与 LED 控制逻辑一致:低电平有效
- 频率决定音调:
Delay_us越短,声音越尖锐(音调段用微秒级延时翻转 IO 产生音频频率;鸣停节奏才用Delay_ms)
扩展:音调控制
// 不同频率对应不同音调
// Do: Delay_us(956) Re: Delay_us(852) Mi: Delay_us(758)
// Fa: Delay_us(716) Sol: Delay_us(638) La: Delay_us(568)
// 简单旋律示例
int melody[] = {956, 852, 758, 716, 638, 568, 506, 478};
for(int i = 0; i < 8; i++)
{
for(int j = 0; j < 50; j++) // 每个音持续一段时间
{
GPIO_ResetBits(GPIOA, GPIO_Pin_9);
Delay_us(melody[i]);
GPIO_SetBits(GPIOA, GPIO_Pin_9);
Delay_us(melody[i]);
}
}
四、小结
三个实验的共同套路:
- 配置 GPIO 为推挽输出(
GPIO_Mode_Out_PP,50MHz); - 外设基本都是低电平有效——拉低动作(点亮/响),拉高停止;
- 单引脚控制用
SetBits/ResetBits,多引脚批量控制用GPIO_Write+ 位操作; - 后续方向:加延时函数做闪烁、学定时器配置、尝试按键中断控制。
豫公网安备41108202000982号