一、实验功能
本实验使用 STM32F103 单片机驱动 5V 继电器模块,实现:
- 继电器 每间隔 1 秒吸合一次
- 继电器 每间隔 1 秒断开一次
- 循环往复,持续工作
- 模块化编程
二、硬件连接
- 继电器 VCC → 5V
- 继电器 GND → 开发板 GND
- 继电器 IN → PA0
- 低电平触发吸合,高电平断开
三、完整代码
main.c 主程序文件
// 包含STM32内核与外设库文件
#include "stm32f10x.h"
// 工程主头文件
#include "main.h"
// 包含LED初始化函数声明
#include "led.h"
// 包含继电器初始化函数声明
#include "relay.h"
/**
* @brief 毫秒级软件延时函数
* @param time: 延时时间,单位约1ms
* @return 无
*/
void delay(uint16_t time) //延时 1ms函数
{
uint16_t i = 0;
while(time --) // 循环time次,实现延时
{
i = 12000; // 内部空循环,消耗CPU时间
while(i --);
}
}
/**
* @brief 主函数,程序上电入口
* @param 无
* @return int
*/
int main()
{
// 初始化LED引脚(如果不需要可删除)
LED_Init();
// 初始化继电器控制引脚 PA0
Relay_Init();
// 初始状态:PA0输出高电平 → 继电器默认断开
GPIO_SetBits( GPIOA, GPIO_Pin_0);
// 死循环,程序永久执行
while(1)
{
// PA0输出低电平 → 继电器吸合(有咔哒声)
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
delay(1000); // 保持吸合1秒
// PA0输出高电平 → 继电器断开
GPIO_SetBits( GPIOA, GPIO_Pin_0);
delay(1000); // 保持断开1秒
}
}
relay.c 继电器驱动文件
// 包含STM32标准库
#include "stm32f10x.h"
// 包含继电器头文件
#include "relay.h"
/**
* @brief 继电器初始化函数
* @detail 配置 PA0 为推挽输出模式,用于控制继电器
* @param 无
* @return 无
*/
void Relay_Init(void)
{
// 定义GPIO初始化结构体
GPIO_InitTypeDef relay_initstruct;
// 开启GPIOA的时钟(必须开时钟才能使用GPIO)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置PA0引脚
relay_initstruct.GPIO_Pin = GPIO_Pin_0;
// 推挽输出模式(可输出强高低电平,适合驱动继电器)
relay_initstruct.GPIO_Mode = GPIO_Mode_Out_PP;
// GPIO速度设置为10MHz
relay_initstruct.GPIO_Speed = GPIO_Speed_10MHz;
// 初始化PA0引脚
GPIO_Init(GPIOA, &relay_initstruct);
}
relay.h 继电器头文件
// 防止头文件重复包含(标准写法)
#ifndef RELAY_H_
#define RELAY_H_
// 继电器初始化函数声明
void Relay_Init(void);
#endif
四、文字讲解
1. 实验原理
继电器是一种 电磁开关,通过单片机小电流控制大电流设备(灯泡、风扇、水泵等)。
本实验中:
- PA0 输出低电平 → 继电器吸合
- PA0 输出高电平 → 继电器断开
通过延时函数控制高低电平时间,实现继电器循环动作。
2. 代码结构
- main.c:主逻辑,控制继电器循环吸合 / 断开
- relay.c:继电器 GPIO 初始化
- relay.h:函数声明 + 防止重复包含
3. 关键函数说明
- Relay_Init():初始化 PA0 为推挽输出,用于驱动继电器
- GPIO_ResetBits():输出低电平,吸合继电器
- GPIO_SetBits():输出高电平,断开继电器
- delay(1000):延时约 1 秒
4. 实验现象
- 继电器每 响一声(吸合)→ 停 1 秒 → 断开
- 循环不断,直到断电
5. 注意事项
- 继电器 VCC 必须接 5V,不能接 3.3V
- 继电器 IN 引脚接单片机 PA0
- 单片机与继电器必须 共 GND
- 继电器为 低电平触发
为什么头文件要写:
#ifndef RELAY_H_
#define RELAY_H_
void Relay_Init(void);
#endif
防止头文件被重复包含,避免编译报错。