前言

在单片机项目开发中,我们经常需要用单片机弱电信号去控制水泵、电磁阀、LED 灯等外部负载。但是 STM32 单片机 GPIO 引脚输出电流很小,不能直接驱动大功率设备,继电器就完美解决这个问题:用微弱的单片机控制信号,通过电磁机构去通断另一路功率电路,实现弱电控制强电。

本篇基于 STM32F103C8T6,使用 PA6 引脚控制继电器模块,搭配 OLED 屏幕实时显示 GPIO 电平与继电器工作状态,完整讲解硬件电路、工作原理、实物演示、源码使用、避坑要点,适合单片机入门学习。

视频讲解:STM32F103单片机驱动继电器模块(附OLED状态显示)完整教程https://www.bilibili.com/video/BV12z8J6GEi5/?share_source=copy_web&vd_source=91b967b41a17a5686913521545a8c3fb

⚠️安全提醒:本教程实验建议只使用低压直流负载做演示,严禁在裸板、面包板直接接入 220V 市电;市电相关实验需要专业人员操作,做好绝缘防护。

一、整体实现思路

STM32 单片机输出高低电平给到继电器模块的控制引脚,模块内部三极管驱动继电器线圈,线圈通电产生磁力切换机械触点,以此控制外部负载通断;同时单片机读取当前输出电平,把引脚状态、继电器开关状态输出到 OLED 屏幕上。

简单流程: STM32 修改 PA6 引脚输出电平 → 继电器模块接收控制信号 → 线圈得电 / 失电 → 继电器机械触点切换通断 → OLED 屏幕同步显示当前工作状态。

本项目使用高电平触发

  • PA6 输出高电平:继电器线圈得电,触点吸合
  • PA6 输出低电平:继电器线圈失电,触点释放

二、硬件电路原理讲解

2.1 裸继电器驱动电路原理

如果不是成品继电器模块,自己搭电路驱动裸继电器,电路分为:单片机控制输入、三极管驱动、继电器线圈、续流保护二极管、状态指示灯、负载输出部分。

  1. 控制输入:STM32 的 PA6 作为 GPIO 输出引脚,输出高低电平信号,PA6 和三极管基极之间需要串联 1kΩ 限流电阻,保护单片机引脚。
  2. 驱动三极管 S8050(NPN):充当电子开关。基极接收 PA6 信号,发射极接地,集电极接继电器线圈。
    • PA6 高电平:三极管饱和导通;
    • PA6 低电平:三极管截止断开。
  3. 继电器线圈:属于感性器件,一端接模块供电 VCC,另一端接三极管集电极。线圈通电产生磁场,带动内部衔铁完成触点切换。继电器触点分为公共端 COM、常开端 NO、常闭端 NC。

    触点 线圈未通电(常态) 线圈通电吸合后
    COM 公共端 公共接线点 公共接线点
    NO 常开端 和 COM 断开 和 COM 接通
    NC 常闭端 和 COM 接通 和 COM 断开

想负载在继电器打开之后才通电,使用 COM + NO;想要负载默认通电,继电器吸合断电,使用 COM + NC。常态指线圈不通电的状态,不是单片机上电瞬间状态

  1. 续流二极管 1N4148:并联在继电器线圈两端,阴极接 VCC,阳极接三极管集电极。 继电器线圈是感性负载,三极管关断瞬间线圈会产生很高反向感应电动势,很容易击穿三极管。二极管给线圈残余电流提供泄放回路,钳位电压,保护驱动器件。

❗重点:二极管千万不能接反,接反通电直接电源短路烧毁电路。

  1. 状态指示 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 高电平;部分带光耦隔离继电器模块有跳帽,需要按照模块手册处理。

三、工作过程详解

  1. PA6 输出低电平(继电器关闭) 三极管驱动管截止,继电器线圈没有电流,继电器处于释放状态。COM 公共端和 NC 常闭端接通,COM 与 NO 断开;此时状态指示灯熄灭,OLED 屏幕显示LEVEL: LOWRELAY:OFF,外接负载(接 COM‑NO 回路)断电不工作。
  2. PA6 输出高电平(继电器打开) 三极管饱和导通,电流流过继电器线圈,线圈产生电磁力吸合衔铁。COM 断开 NC,切换连接 NO;指示灯点亮,OLED 屏幕显示LEVEL:HIGHRELAY:ON,外接负载通电开始工作。
  3. 断电瞬间保护 当 PA6 由高变低,三极管快速关断,线圈产生反向高压,续流二极管导通消耗电感能量,保护三极管不被高压击穿。

补充知识点:机械继电器动作速度很慢,不能用来做高频 PWM 控制,频繁快速切换会造成触点磨损、烧蚀,缩短继电器使用寿命。

四、源代码相关章节

📌本章节用于粘贴工程源码,工程文件分为JDQ.cJDQ.hmain.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 实验器材清单

  1. STM32F103C8T6 最小系统板 ×1
  2. 高电平触发继电器模块 ×1
  3. 0.96 寸 I2C OLED 屏幕 ×1
  4. 低压直流负载(LED 小灯作为演示负载)

5.2 实物接线步骤

  1. 按照上面接线表完成接线,确认所有 GND 全部共地,OLED 接 3.3V,不要错接 5V。
  2. 继电器负载侧:把 LED 小灯串联限流电阻接在继电器 COM 和 NO 引脚两端,给 LED 提供低压供电。
  3. 检查接线,确认没有短路,下载程序到 STM32 开发板。

5.3 实验现象观察

  1. 程序下载运行之后,继电器每间隔 1 秒切换一次状态。
  2. OLED 屏幕交替打印两组内容:
    RELAY DEMO
    PIN: PA6
    LEVEL: HIGH
    RELAY: ON
    

    RELAY DEMO
    PIN: PA6
    LEVEL: LOW
    RELAY: OFF
    

  3. 可以听到继电器 “咔哒、咔哒” 机械吸合释放声音;继电器模块指示灯同步变化;外接 LED 负载跟随继电器同步亮灭。
  4. 修改代码里面JDQ_STATE_TIME_MS宏,比如改成 2000U,继电器切换间隔变成 2 秒,可以观察状态变化。

六、常见踩坑点与注意事项

1.触发模式区分:高电平触发 vs 低电平触发 很多继电器模块是低电平触发,此时程序逻辑需要反过来。如果接线之后继电器上电就吸合,大概率模块触发逻辑和代码不匹配,需要修改代码。不要靠外观颜色判断触发模式,要看模块丝印说明。

2.供电问题 继电器线圈供电电压必须匹配模块参数(5V/12V 等)。不要指望单片机 GPIO 输出电流驱动线圈;带光耦隔离模块注意跳帽设置,隔离模式控制电源和继电器电源可以分开。

3.负载额定参数 继电器外壳印刷的电压、电流是最大额定值,不要长期满负载运行;电机、电磁阀这类感性负载,触点侧也需要增加浪涌吸收保护,减少电弧烧蚀触点。

4.上电误动作 GPIO 初始化代码中,先把引脚置低电平,再配置为输出模式,避免配置过程继电器误触发。

5.安全重点 教学实验只用低压直流演示;继电器虽然可以隔离控制回路,但普通学习模块 PCB 绝缘能力不足以支持市电,严禁学生裸板操作 220V 交流电。

七、总结

继电器实现了弱电控制强电,STM32 单片机只输出 3.3V 逻辑电平,不直接输出功率,依靠三极管驱动继电器线圈,电磁力控制机械触点完成负载电路开关,OLED 屏幕可以把控制状态可视化。

本实验可以作为基础框架,后续可以结合温度传感器、人体红外、烟雾传感器,实现检测到条件自动打开继电器控制外设,是单片机做自动控制非常经典的项目。

    Logo

    智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

    更多推荐