STM32 继电器驱动——双触发模式的通用控制接口
问题背景继电器模块的触发方式有两种高电平触发常见于低电平驱动型继电器模组和低电平触发常见于光耦隔离型模组。如果业务代码直接操作 GPIO 而不区分触发模式换一个模块就要改代码。本文给出一个简洁的继电器驱动通过active_mode字段封装两种触发模式的差异提供初始化、开关、翻转等标准接口。驱动设计核心思路驱动使用relay_active_t枚举区分触发模式typedef enum { RELAY_ACTIVE_HIGH 0, // 高电平触发输出 SET 吸合 RELAY_ACTIVE_LOW // 低电平触发输出 RESET 吸合 } relay_active_t;所有操作函数relay_on、relay_off都根据active_mode计算实际物理电平调用方只需关心开/关逻辑。toggle 实现relay_toggle通过HAL_GPIO_ReadPin读取当前引脚电平结合active_mode判断继电器是否已吸合然后翻转。这种读-判断-写的方式比维护内部状态变量更可靠状态始终与硬件一致。API 参考函数说明relay_init(cb, gpio_x, gpio_pin, active_mode, set_pin)初始化并关闭继电器relay_on(cb)吸合继电器relay_off(cb)释放继电器relay_set(cb, val)设置状态0关, 非0开relay_toggle(cb)翻转状态使用示例#include driver_relay.h ​ relay_control_t relay1; ​ int main(void) { // 初始化高电平触发GPIOB_PIN_12 relay_init(relay1, (uint32_t)GPIOB, GPIO_PIN_12, RELAY_ACTIVE_HIGH, (relay_gpio_set_func_t)HAL_GPIO_WritePin); ​ relay_on(relay1); // 吸合 HAL_Delay(1000); relay_off(relay1); // 释放 HAL_Delay(1000); relay_toggle(relay1); // 再次吸合 HAL_Delay(1000); relay_set(relay1, 0); // 通过变量控制释放 ​ while (1); }注意事项gpio_x参数为uint32_t类型传入 GPIO 端口时需要强转set_pin函数指针不能为 NULL否则relay_init返回RELAY_ERRORrelay_toggle内部调用HAL_GPIO_ReadPin需要该引脚已在 CubeMX 中正确配置初始化后继电器默认处于关闭释放状态总结本驱动仅 ~150 行代码核心价值在于用active_mode字段消除了不同继电器模块在触发方式上的差异让上层代码完全透明。完整源码driver_relay.h/** * file driver_relay.h * author Jiang Ying * brief 继电器驱动头文件 * version V1.0.0 * date 2026.03.28 * note 该文件包含继电器驱动函数声明提供初始化、开启、关闭、 * 设置和切换功能。用户可以通过调用这些函数来控制继电器的状态。 */ ​ #ifndef _DRIVER_RELAY_H #define _DRIVER_RELAY_H ​ /* Includes ------------------------------------------------------------------*/ #include stm32f1xx_hal.h ​ #include stdint.h ​ /** * brief 继电器状态枚举 * note 定义继电器的两种状态关闭和开启 */ typedef enum { RELAY_ERROR 0, RELAY_OK !RELAY_ERROR }relay_state_t; ​ /** * brief 继电器状态枚举 * note 定义继电器的两种状态关闭和开启 */ typedef enum { RELAY_RESET 0, RELAY_SET }relay_set_t; ​ /** * brief 继电器触发模式枚举 * note 定义继电器的不同触发模式 */ typedef enum { RELAY_ACTIVE_HIGH 0, /* 高电平触发模式GPIO输出高电平时继电器吸合 */ RELAY_ACTIVE_LOW /* 低电平触发模式GPIO输出低电平时继电器吸合 */ }relay_active_t; ​ /** * brief GPIO设置函数指针类型 * note 用于设置GPIO引脚状态的函数指针类型 */ typedef relay_state_t (*relay_gpio_set_func_t)(uint32_t, uint32_t, uint32_t); ​ /** * brief 继电器控制结构体 * note 包含继电器的GPIO配置、触发模式和控制函数 */ typedef struct { uint32_t gpio_x; /* GPIO端口 */ uint32_t gpio_pin; /* GPIO引脚 */ relay_active_t active_mode; /* 继电器触发模式 */ relay_gpio_set_func_t set_pin; /* GPIO设置函数指针 */ }relay_control_t; ​ ​ relay_state_t relay_init(relay_control_t *cb, uint32_t gpio_x, uint32_t gpio_pin, relay_active_t active_mode, relay_gpio_set_func_t set_pin); relay_state_t relay_on(relay_control_t *cb); relay_state_t relay_off(relay_control_t *cb); relay_state_t relay_set(relay_control_t *cb, uint32_t val); relay_state_t relay_toggle(relay_control_t *cb); ​ ​ #endif /* _DRIVER_RELAY_H */ ​driver_relay.c/** * file driver_relay.c * author Jiang Ying * brief 继电器驱动源文件 * version V1.0.0 * date 2026.03.28 */ /* Includes ------------------------------------------------------------------*/ #include driver_relay.h ​ /** * brief 打开继电器 * param cb 继电器控制结构体指针 * return 继电器操作状态 * note 根据继电器的触发模式决定输出高电平还是低电平 */ relay_state_t relay_on(relay_control_t *cb) { relay_state_t state RELAY_ERROR; uint32_t pin_state; ​ /* 根据触发模式决定实际输出的电平 */ if (cb-active_mode RELAY_ACTIVE_HIGH) { pin_state RELAY_SET; /* 高电平触发模式输出高电平吸合继电器 */ } else { pin_state RELAY_RESET; /* 低电平触发模式输出低电平吸合继电器 */ } ​ state cb-set_pin(cb-gpio_x, cb-gpio_pin, pin_state); ​ return state; } ​ /** * brief 关闭继电器 * param cb 继电器控制结构体指针 * return 继电器操作状态 * note 根据继电器的触发模式决定输出高电平还是低电平 */ relay_state_t relay_off(relay_control_t *cb) { relay_state_t state RELAY_ERROR; uint32_t pin_state; ​ /* 根据触发模式决定实际输出的电平 */ if (cb-active_mode RELAY_ACTIVE_HIGH) { pin_state RELAY_RESET; /* 高电平触发模式输出低电平释放继电器 */ } else { pin_state RELAY_SET; /* 低电平触发模式输出高电平释放继电器 */ } ​ state cb-set_pin(cb-gpio_x, cb-gpio_pin, pin_state); ​ return state; } ​ /** * brief 设置继电器状态 * param cb 继电器控制结构体指针 * param val 继电器状态值0表示关闭非0表示打开 * return 继电器操作状态 * note 根据继电器的触发模式和状态值决定输出高电平还是低电平 */ relay_state_t relay_set(relay_control_t *cb, uint32_t val) { if (val) { return relay_on(cb); /* 打开继电器 */ } else { return relay_off(cb); /* 关闭继电器 */ } } ​ /** * brief 初始化继电器控制结构体 * param cb 继电器控制结构体指针 * param gpio_x GPIO端口 * param gpio_pin GPIO引脚 * param active_mode 继电器触发模式 * param set_pin GPIO设置函数指针 * return 继电器操作状态 * note 配置继电器控制结构体并初始化继电器为关闭状态 */ relay_state_t relay_init(relay_control_t *cb, uint32_t gpio_x, uint32_t gpio_pin, relay_active_t active_mode, relay_gpio_set_func_t set_pin) { relay_state_t state RELAY_ERROR; ​ if (cb NULL || set_pin NULL) { return RELAY_ERROR; } ​ /* 配置继电器控制结构体 */ cb-gpio_x gpio_x; cb-gpio_pin gpio_pin; cb-active_mode active_mode; cb-set_pin set_pin; ​ /* 初始化继电器为关闭状态 */ state relay_off(cb); ​ return state; } ​ /** * brief 切换继电器状态 * param cb 继电器控制结构体指针 * return 继电器操作状态 * note 如果继电器当前是打开状态则关闭如果是关闭状态则打开 */ relay_state_t relay_toggle(relay_control_t *cb) { relay_state_t state RELAY_ERROR; uint32_t current_state; uint32_t new_state; ​ /* 获取当前引脚状态 */ if (cb-active_mode RELAY_ACTIVE_HIGH) { /* 高电平触发模式下引脚为高表示继电器打开 */ current_state (HAL_GPIO_ReadPin((GPIO_TypeDef*)cb-gpio_x, cb-gpio_pin) GPIO_PIN_SET) ? 1 : 0; } else { /* 低电平触发模式下引脚为低表示继电器打开 */ current_state (HAL_GPIO_ReadPin((GPIO_TypeDef*)cb-gpio_x, cb-gpio_pin) GPIO_PIN_RESET) ? 1 : 0; } ​ /* 切换状态 */ new_state current_state ? 0 : 1; ​ /* 设置新状态 */ state relay_set(cb, new_state); ​ return state; } ​

相关新闻

连山区口腔机构排名,专业的竟然是这些!

连山区口腔机构排名,专业的竟然是这些!

引言在连山区,口腔健康备受关注,众多口腔机构林立。究竟哪些机构专业度较高呢?让我们一同探寻。专业口腔机构剖析连山区兴工路周雷口腔诊所:这是一家备受赞誉的口腔机构。诊所环境整洁舒适,诊疗设备定期消毒&#xff0…

2026/8/2 7:39:15阅读更多 →
AI语音视频解说正在淘汰传统剪辑师?(头部MCN内部培训手册流出:3天速成AIGC配音导演认证路径)

AI语音视频解说正在淘汰传统剪辑师?(头部MCN内部培训手册流出:3天速成AIGC配音导演认证路径)

更多请点击: https://kaifayun.com 第一章:AI语音视频解说的行业颠覆性本质 AI语音视频解说正从工具层跃升为内容生产范式的结构性变量——它不再仅替代配音员,而是重构创作链路、重定义版权边界、并重塑用户注意力分配逻辑。当模型能同步理…

2026/8/2 7:37:15阅读更多 →
分布式系统时钟精度:Accuracy、Tolerance与Jitter的深度解析与实战优化

分布式系统时钟精度:Accuracy、Tolerance与Jitter的深度解析与实战优化

1. 从一次线上故障说起:为什么时钟的“准”与“不稳”如此致命? 去年,我们团队负责的一个分布式实时数据处理系统,在业务高峰期突然出现了大量数据乱序和重复计算的问题。监控大盘上,各个节点的处理延迟曲线像心电图一…

2026/8/2 7:37:15阅读更多 →
工业AI边缘设备刷机实战:从Jetson Orin NX系统部署到优化

工业AI边缘设备刷机实战:从Jetson Orin NX系统部署到优化

1. 项目概述:为工业AI边缘设备注入灵魂最近在折腾一块来自Jetson生态的工业级AI计算设备——reComputer AI Industrial R2000。这玩意儿本质上是一个基于NVIDIA Jetson Orin NX模组的工业载板,性能强悍,专为苛刻的工业环境设计。但拿到手的时…

2026/8/2 8:55:35阅读更多 →
逻辑函数化简:从公式法到卡诺图的数字电路设计核心技能

逻辑函数化简:从公式法到卡诺图的数字电路设计核心技能

1. 项目概述:从“会算”到“会变”的思维跃迁刚接触数字电路的朋友,可能都有过这样的经历:面对一个逻辑函数表达式,感觉每个字母和符号都认识,但组合在一起就像一团乱麻,不知道从何下手。课本上告诉你&…

2026/8/2 8:55:35阅读更多 →
C语言volatile与extern关键字:底层原理、应用场景与实战避坑指南

C语言volatile与extern关键字:底层原理、应用场景与实战避坑指南

1. 项目概述:为什么这两个关键字值得深挖? 搞C语言开发,尤其是嵌入式、驱动、操作系统内核或者高性能服务端编程,你肯定不止一次在代码里见过 volatile 和 extern 这两个关键字。它们不像 int 、 if 、 for 那样天天用&…

2026/8/2 8:55:35阅读更多 →
5分钟掌握uesave:轻松编辑Unreal Engine游戏存档的完整指南

5分钟掌握uesave:轻松编辑Unreal Engine游戏存档的完整指南

5分钟掌握uesave:轻松编辑Unreal Engine游戏存档的完整指南 【免费下载链接】uesave Rust library and CLI to read and write Unreal Engine save files 项目地址: https://gitcode.com/gh_mirrors/ue/uesave 还在为游戏存档损坏而烦恼吗?想要备…

2026/8/2 8:55:35阅读更多 →
Prism语法高亮库:3步打造专业级代码展示体验的终极指南

Prism语法高亮库:3步打造专业级代码展示体验的终极指南

Prism语法高亮库:3步打造专业级代码展示体验的终极指南 【免费下载链接】prism Lightweight, robust, elegant syntax highlighting. 项目地址: https://gitcode.com/gh_mirrors/pr/prism 在当今技术内容爆炸的时代,一个优雅的代码展示方案能极大…

2026/8/2 8:55:35阅读更多 →
【计算机毕业设计】基于Java Web的小区物业管理系统

【计算机毕业设计】基于Java Web的小区物业管理系统

1.系统介绍随着城市化进程加快,传统人工化的小区物业管理模式存在效率低、流程不规范、业主交互体验差等问题,已难以满足现代小区精细化管理与业主多元化服务需求。为解决这一痛点,本研究设计并实现了一套基于 Java Web 的小区物业管理系统&a…

2026/8/2 8:53:33阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/2 0:00:10阅读更多 →
限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

更多请点击: https://intelliparadigm.com 第一章:AI模板批量生成的核心价值与落地全景 AI模板批量生成正从实验性工具演进为现代软件工程的关键基础设施。它通过语义理解、上下文感知与结构化约束,将重复性高、模式明确的代码/文档/配置生成…

2026/8/2 0:00:12阅读更多 →
如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南 【免费下载链接】web-archives Browser extension for viewing archived and cached versions of web pages, available for Chrome, Edge and Safari 项目地址: https://gitcode.com/gh_mirrors/we/web-a…

2026/8/2 0:00:13阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/2 0:00:10阅读更多 →
限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

限时公开!某头部SaaS公司内部AI模板工厂架构文档(含5类行业模板源码+性能压测报告)

更多请点击: https://intelliparadigm.com 第一章:AI模板批量生成的核心价值与落地全景 AI模板批量生成正从实验性工具演进为现代软件工程的关键基础设施。它通过语义理解、上下文感知与结构化约束,将重复性高、模式明确的代码/文档/配置生成…

2026/8/2 0:00:12阅读更多 →
如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南

如何快速找回消失的网页:Web Archives浏览器扩展终极指南 【免费下载链接】web-archives Browser extension for viewing archived and cached versions of web pages, available for Chrome, Edge and Safari 项目地址: https://gitcode.com/gh_mirrors/we/web-a…

2026/8/2 0:00:13阅读更多 →
无损视频剪辑终极指南:如何实现快速高效的多媒体处理

无损视频剪辑终极指南:如何实现快速高效的多媒体处理

无损视频剪辑终极指南:如何实现快速高效的多媒体处理 【免费下载链接】lossless-cut The swiss army knife of lossless video/audio editing 项目地址: https://gitcode.com/gh_mirrors/lo/lossless-cut 在数字媒体创作领域,视频编辑处理的质量损…

2026/8/2 1:29:34阅读更多 →
AI辅助本科论文写作:8大工具评测与高效使用指南

AI辅助本科论文写作:8大工具评测与高效使用指南

1. 本科生论文写作的AI辅助现状本科毕业论文是每个大学生必须跨越的一道坎。记得我当年写论文时,光是文献检索就花了整整两周时间,打印的参考文献堆满了半个书桌。如今AI技术的发展为学术写作带来了革命性变化,合理使用这些工具可以节省80%以…

2026/8/2 2:32:55阅读更多 →
如何快速配置大麦自动抢票系统:从零开始搭建Python抢票助手

如何快速配置大麦自动抢票系统:从零开始搭建Python抢票助手

如何快速配置大麦自动抢票系统:从零开始搭建Python抢票助手 【免费下载链接】ticket-purchase 大麦自动抢票,支持人员、城市、日期场次、价格选择 项目地址: https://gitcode.com/GitHub_Trending/ti/ticket-purchase 还在为抢不到热门演唱会门票…

2026/8/2 2:09:20阅读更多 →