STM32F103单片机驱动继电器模块(附OLED状态显示)完整教程
前言
在单片机项目开发中,我们经常需要用单片机弱电信号去控制水泵、电磁阀、LED 灯等外部负载。但是 STM32 单片机 GPIO 引脚输出电流很小,不能直接驱动大功率设备,继电器就完美解决这个问题:用微弱的单片机控制信号,通过电磁机构去通断另一路功率电路,实现弱电控制强电。
本篇基于 STM32F103C8T6,使用 PA6 引脚控制继电器模块,搭配 OLED 屏幕实时显示 GPIO 电平与继电器工作状态,完整讲解硬件电路、工作原理、实物演示、源码使用、避坑要点,适合单片机入门学习。
⚠️安全提醒:本教程实验建议只使用低压直流负载做演示,严禁在裸板、面包板直接接入 220V 市电;市电相关实验需要专业人员操作,做好绝缘防护。
一、整体实现思路
STM32 单片机输出高低电平给到继电器模块的控制引脚,模块内部三极管驱动继电器线圈,线圈通电产生磁力切换机械触点,以此控制外部负载通断;同时单片机读取当前输出电平,把引脚状态、继电器开关状态输出到 OLED 屏幕上。
简单流程: STM32 修改 PA6 引脚输出电平 → 继电器模块接收控制信号 → 线圈得电 / 失电 → 继电器机械触点切换通断 → OLED 屏幕同步显示当前工作状态。

本项目使用高电平触发:
- PA6 输出高电平:继电器线圈得电,触点吸合
- PA6 输出低电平:继电器线圈失电,触点释放
二、硬件电路原理讲解
2.1 裸继电器驱动电路原理
如果不是成品继电器模块,自己搭电路驱动裸继电器,电路分为:单片机控制输入、三极管驱动、继电器线圈、续流保护二极管、状态指示灯、负载输出部分。
- 控制输入:STM32 的 PA6 作为 GPIO 输出引脚,输出高低电平信号,PA6 和三极管基极之间需要串联 1kΩ 限流电阻,保护单片机引脚。
- 驱动三极管 S8050(NPN):充当电子开关。基极接收 PA6 信号,发射极接地,集电极接继电器线圈。
- PA6 高电平:三极管饱和导通;
- PA6 低电平:三极管截止断开。
- 继电器线圈:属于感性器件,一端接模块供电 VCC,另一端接三极管集电极。线圈通电产生磁场,带动内部衔铁完成触点切换。继电器触点分为公共端 COM、常开端 NO、常闭端 NC。

触点 线圈未通电(常态) 线圈通电吸合后 COM 公共端 公共接线点 公共接线点 NO 常开端 和 COM 断开 和 COM 接通 NC 常闭端 和 COM 接通 和 COM 断开
想负载在继电器打开之后才通电,使用 COM + NO;想要负载默认通电,继电器吸合断电,使用 COM + NC。常态指线圈不通电的状态,不是单片机上电瞬间状态。
- 续流二极管 1N4148:并联在继电器线圈两端,阴极接 VCC,阳极接三极管集电极。 继电器线圈是感性负载,三极管关断瞬间线圈会产生很高反向感应电动势,很容易击穿三极管。二极管给线圈残余电流提供泄放回路,钳位电压,保护驱动器件。
❗重点:二极管千万不能接反,接反通电直接电源短路烧毁电路。
- 状态指示 LED:串联 1K 限流电阻,用来直观观察继电器线圈是否通电。
重要提醒:STM32 的 GPIO 引脚绝对不能直接接继电器线圈!线圈工作电流远大于 GPIO 引脚输出能力,必须经过三极管 / MOS 管驱动。
2.2 硬件接线表(成品继电器模块 + OLED)
| 器件引脚 | 连接 STM32 引脚 | 说明 |
|---|---|---|
| 继电器模块 IN 控制脚 | PA6 | 高电平触发,控制继电器吸合释放 |
| 继电器模块 VCC | 模块额定供电(5V) | 给继电器线圈、驱动电路供电 |
| 继电器模块 GND | STM32 GND | 必须共地,否则控制信号失效 |
| OLED SCL | PB8 | I2C 时钟线 |
| OLED SDA | PB9 | I2C 数据线 |
| OLED VCC | 3.3V | OLED 供电,不要接 5V 容易烧坏屏幕 |
| OLED GND | STM32 GND | 共地 |
注意:继电器模块供电电压 和 输入触发电平是两回事!STM32 输出是 3.3V,要确认继电器模块输入端兼容 3.3V 高电平;部分带光耦隔离继电器模块有跳帽,需要按照模块手册处理。
三、工作过程详解
- PA6 输出低电平(继电器关闭) 三极管驱动管截止,继电器线圈没有电流,继电器处于释放状态。COM 公共端和 NC 常闭端接通,COM 与 NO 断开;此时状态指示灯熄灭,OLED 屏幕显示
LEVEL: LOW,RELAY:OFF,外接负载(接 COM‑NO 回路)断电不工作。 - PA6 输出高电平(继电器打开) 三极管饱和导通,电流流过继电器线圈,线圈产生电磁力吸合衔铁。COM 断开 NC,切换连接 NO;指示灯点亮,OLED 屏幕显示
LEVEL:HIGH,RELAY:ON,外接负载通电开始工作。 - 断电瞬间保护 当 PA6 由高变低,三极管快速关断,线圈产生反向高压,续流二极管导通消耗电感能量,保护三极管不被高压击穿。
补充知识点:机械继电器动作速度很慢,不能用来做高频 PWM 控制,频繁快速切换会造成触点磨损、烧蚀,缩短继电器使用寿命。
四、源代码相关章节
📌本章节用于粘贴工程源码,工程文件分为
JDQ.c、JDQ.h、main.c。还有 OLED I2C 驱动文件。
main.c代码
/* Active-high relay and OLED teaching demonstration for STM32F103C8T6. */
#include "delay.h"
#include "oled.h"
#include "JDQ.h"
#define JDQ_STATE_TIME_MS 1000U
static void JDQ_ShowState(uint8_t is_on);
int main(void)
{
delay_init();
JDQ_Init();
OLED_Init();
OLED_ColorTurn(0);
OLED_DisplayTurn(0);
while(1)
{
JDQ_On();
JDQ_ShowState(JDQ_IsOn());
delay_ms(JDQ_STATE_TIME_MS);
JDQ_Off();
JDQ_ShowState(JDQ_IsOn());
delay_ms(JDQ_STATE_TIME_MS);
}
}
static void JDQ_ShowState(uint8_t is_on)
{
OLED_Clear();
OLED_ShowString(0, 0, (u8 *)"RELAY DEMO", 16);
OLED_ShowString(0, 18, (u8 *)"PIN: PA6", 16);
if(is_on != 0U)
{
OLED_ShowString(0, 36, (u8 *)"LEVEL: HIGH", 16);
OLED_ShowString(0, 52, (u8 *)"RELAY: ON", 12);
}
else
{
OLED_ShowString(0, 36, (u8 *)"LEVEL: LOW", 16);
OLED_ShowString(0, 52, (u8 *)"RELAY: OFF", 12);
}
OLED_Refresh();
}
JDQ.c代码
#include "JDQ.h"
/*
* 函数名称:JDQ_Init
* 功 能:初始化 PA6 为推挽输出,并使继电器保持断开。
* 说 明:先将输出数据寄存器置低,再配置 GPIO,可避免初始化时误导通。
*/
void JDQ_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 使能 GPIOA 外设时钟。 */
RCC_APB2PeriphClockCmd(JDQ_GPIO_CLK, ENABLE);
/* 预先输出低电平,确保 GPIO 配置期间继电器不会误导通。 */
GPIO_ResetBits(JDQ_GPIO_PORT, JDQ_GPIO_PIN);
/* 将 PA6 配置为 50 MHz 通用推挽输出。 */
GPIO_InitStructure.GPIO_Pin = JDQ_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(JDQ_GPIO_PORT, &GPIO_InitStructure);
}
/* 输出高电平,使继电器导通。 */
void JDQ_On(void)
{
GPIO_SetBits(JDQ_GPIO_PORT, JDQ_GPIO_PIN);
}
/* 输出低电平,使继电器断开。 */
void JDQ_Off(void)
{
GPIO_ResetBits(JDQ_GPIO_PORT, JDQ_GPIO_PIN);
}
/* 使用一个状态参数统一控制继电器,便于上层程序调用。 */
void JDQ_SetState(uint8_t is_on)
{
if(is_on != 0U)
{
JDQ_On();
}
else
{
JDQ_Off();
}
}
/* 读取 PA6 输出数据寄存器,并转换为便于判断的 0 或 1。 */
uint8_t JDQ_IsOn(void)
{
return (GPIO_ReadOutputDataBit(JDQ_GPIO_PORT, JDQ_GPIO_PIN) != Bit_RESET) ? 1U : 0U;
}
JDQ.h代码
#ifndef __JDQ_H
#define __JDQ_H
#include "stm32f10x.h"
/*
* 继电器模块引脚配置:
* JDQ 控制端连接 STM32F103C8T6 的 PA6。
* PA6 输出高电平时继电器导通,输出低电平时继电器断开。
*/
#define JDQ_GPIO_PORT GPIOA
#define JDQ_GPIO_PIN GPIO_Pin_6
#define JDQ_GPIO_CLK RCC_APB2Periph_GPIOA
/* 初始化继电器控制引脚,初始化完成后继电器默认断开。 */
void JDQ_Init(void);
/* PA6 输出高电平,使继电器导通。 */
void JDQ_On(void);
/* PA6 输出低电平,使继电器断开。 */
void JDQ_Off(void);
/* 根据 is_on 设置继电器状态:非 0 表示导通,0 表示断开。 */
void JDQ_SetState(uint8_t is_on);
/* 读取 PA6 的输出状态:返回 1 表示导通,返回 0 表示断开。 */
uint8_t JDQ_IsOn(void);
#endif
关键 API 函数说明
| 函数 | 功能 |
|---|---|
| JDQ_Init() | 初始化 PA6 引脚,上电默认继电器关闭 |
| JDQ_On() | PA6 输出高电平,继电器吸合 |
| JDQ_Off() | PA6 输出低电平,继电器释放 |
| JDQ_SetState(uint8_t state) | 传入 1 打开继电器,传入 0 关闭继电器,适合传感器联动场景 |
| JDQ_IsOn() | 读取 GPIO 输出寄存器,获取当前设置的继电器状态 |
| JDQ_ShowState() | 在 OLED 屏幕打印引脚电平、继电器开关状态 |
注意:
JDQ_IsOn()读取的是单片机输出寄存器的状态,代表程序发出的指令,不能检测继电器机械触点有没有真实动作。如果需要确认负载实际通断,需要额外增加硬件检测电路。
五、实物演示章节
5.1 实验器材清单
- STM32F103C8T6 最小系统板 ×1
- 高电平触发继电器模块 ×1
- 0.96 寸 I2C OLED 屏幕 ×1
- 低压直流负载(LED 小灯作为演示负载)
5.2 实物接线步骤
- 按照上面接线表完成接线,确认所有 GND 全部共地,OLED 接 3.3V,不要错接 5V。
- 继电器负载侧:把 LED 小灯串联限流电阻接在继电器 COM 和 NO 引脚两端,给 LED 提供低压供电。
- 检查接线,确认没有短路,下载程序到 STM32 开发板。
5.3 实验现象观察
- 程序下载运行之后,继电器每间隔 1 秒切换一次状态。
- OLED 屏幕交替打印两组内容:
RELAY DEMO PIN: PA6 LEVEL: HIGH RELAY: ON
RELAY DEMO PIN: PA6 LEVEL: LOW RELAY: OFF
- 可以听到继电器 “咔哒、咔哒” 机械吸合释放声音;继电器模块指示灯同步变化;外接 LED 负载跟随继电器同步亮灭。
- 修改代码里面
JDQ_STATE_TIME_MS宏,比如改成 2000U,继电器切换间隔变成 2 秒,可以观察状态变化。
六、常见踩坑点与注意事项
1.触发模式区分:高电平触发 vs 低电平触发 很多继电器模块是低电平触发,此时程序逻辑需要反过来。如果接线之后继电器上电就吸合,大概率模块触发逻辑和代码不匹配,需要修改代码。不要靠外观颜色判断触发模式,要看模块丝印说明。
2.供电问题 继电器线圈供电电压必须匹配模块参数(5V/12V 等)。不要指望单片机 GPIO 输出电流驱动线圈;带光耦隔离模块注意跳帽设置,隔离模式控制电源和继电器电源可以分开。
3.负载额定参数 继电器外壳印刷的电压、电流是最大额定值,不要长期满负载运行;电机、电磁阀这类感性负载,触点侧也需要增加浪涌吸收保护,减少电弧烧蚀触点。
4.上电误动作 GPIO 初始化代码中,先把引脚置低电平,再配置为输出模式,避免配置过程继电器误触发。
5.安全重点 教学实验只用低压直流演示;继电器虽然可以隔离控制回路,但普通学习模块 PCB 绝缘能力不足以支持市电,严禁学生裸板操作 220V 交流电。
七、总结
继电器实现了弱电控制强电,STM32 单片机只输出 3.3V 逻辑电平,不直接输出功率,依靠三极管驱动继电器线圈,电磁力控制机械触点完成负载电路开关,OLED 屏幕可以把控制状态可视化。
本实验可以作为基础框架,后续可以结合温度传感器、人体红外、烟雾传感器,实现检测到条件自动打开继电器控制外设,是单片机做自动控制非常经典的项目。
更多推荐

所有评论(0)