基于STM32F103C8T6单片机驱动ACS712模块进行电流检测

基于STM32F103C8T6单片机驱动ACS712模块进行电流检测

    • [一、ACS712 模块简介](#一、ACS712 模块简介)
      • 1.1产品简介
      • [1.2 模块特性](#1.2 模块特性)
      • [1.3 引脚定义](#1.3 引脚定义)
    • 二、硬件连接
      • [2.1 单片机接线](#2.1 单片机接线)
      • [2.2 电流检测端及分压接线](#2.2 电流检测端及分压接线)
      • [2.3 实物接线](#2.3 实物接线)
    • 三、软件代码
      • [3.1 AD.c](#3.1 AD.c)
      • [3.2 主程序](#3.2 主程序)
    • 四、测试现象
      • [4.1 理想数据](#4.1 理想数据)
      • [4.2 实测数据](#4.2 实测数据)
    • 五、常见问题
      • [Q1: 读数一直为 0?](#Q1: 读数一直为 0?)
      • [Q2: 读数跳变很大?](#Q2: 读数跳变很大?)
      • [Q3: 负电流显示?](#Q3: 负电流显示?)
      • [Q4: 精度不够?](#Q4: 精度不够?)

一、ACS712 模块简介

1.1产品简介

在嵌入式开发中,电流检测是一个常见需求。本文详细介绍如何使用 STM32F103C8T6 驱动 ACS712 霍尔效应电流传感器 ,并完成1-5A电流的实测验证。
ACS712 是一款基于霍尔效应的电流传感芯片,用来测量直流或交流电流。它通过内部导体感应电流产生的磁场,再由霍尔元件转换成与电流成比例的模拟电压输出(一般以 Vcc/2 为零点)。该芯片具有电气隔离、安全性高、响应速度快 的特点,常见量程有 ±5A、±20A、±30A,广泛用于电源监测、电机控制和过流检测等场景。

1.2 模块特性

  • 工作电压:5V DC(不可以用3.3V供电,输出不稳定误差大,官方手册工作电压在4.5-5.5V之间)
  • 输出类型:模拟电压输出
  • 零点电压:VCC/2 = 2.5V(无电流时)
  • 灵敏度 :185mV/A(5A 版本)
    ACS712 不同量程的灵敏度不同,可以看下表:

1.3 引脚定义

引脚 功能 连接
VCC 电源正极 接 5V
OUT 模拟输出 接 STM32 PA0(ADC 输入)
GND 电源负极 共地
IP+ 电流输入 检测电路电流输入
IP- 电流输出 检测电路电流输出

二、硬件连接

2.1 单片机接线

ACS712 STM32F103C8T6 OLED
VCC(外部电源接5V) -- --
OUT 分压后接到PA0 --
GND(外部电源接地) GND GND
-- 3.3V VCC
-- PB8 SCL
-- PB9 SDA

2.2 电流检测端及分压接线

①这里检测电路和板子供电的5V建议分开供电。

②在PA0对地之间可以加个0.1uF的独石电容,增加稳定性。

③加分压电路的原因:5A电流时,OUT输出电压理论值3.425V已经超过STM32的采样电压3.3V了,因此需要加分压电路。

2.3 实物接线


三、软件代码

STM32F103C8T6驱动ACS712电流检测(标准库代码)。

3.1 AD.c

c 复制代码
#include "stm32f10x.h"                  // Device header

/**
  * 函    数:AD初始化
  * 参    数:无
  * 返 回 值:无
  */
void AD_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);	//开启ADC1的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
	
	/*设置ADC时钟*/
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);						//选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA0引脚初始化为模拟输入
	
	/*规则组通道配置*/
	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);		//规则组序列1的位置,配置为通道0
	
	/*ADC初始化*/
	ADC_InitTypeDef ADC_InitStructure;						//定义结构体变量
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;		//模式,选择独立模式,即单独使用ADC1
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//数据对齐,选择右对齐
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//外部触发,使用软件触发,不需要外部触发
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;		//连续转换,失能,每转换一次规则组序列后停止
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;			//扫描模式,失能,只转换规则组的序列1这一个位置
	ADC_InitStructure.ADC_NbrOfChannel = 1;					//通道数,为1,仅在扫描模式下,才需要指定大于1的数,在非扫描模式下,只能是1
	ADC_Init(ADC1, &ADC_InitStructure);						//将结构体变量交给ADC_Init,配置ADC1
	
	/*ADC使能*/
	ADC_Cmd(ADC1, ENABLE);									//使能ADC1,ADC开始运行
	
	/*ADC校准*/
	ADC_ResetCalibration(ADC1);								//固定流程,内部有电路会自动执行校准
	while (ADC_GetResetCalibrationStatus(ADC1) == SET);
    /*开始校准*/
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1) == SET);
}

/**
  * 函    数:获取AD转换的值
  * 参    数:无
  * 返 回 值:AD转换的值,范围:0~4095
  */
uint16_t AD_GetValue(void)
{
    /*开始转换*/
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);					//软件触发AD转换一次
	while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);	//等待EOC标志位,即等待AD转换结束
	return ADC_GetConversionValue(ADC1);					//读数据寄存器,得到AD转换的结果
    
}

3.2 主程序

c 复制代码
/**********************************************
***基于STM32F103C8T6单片机驱动ACS712模块进行电流检测***
注意:启动时电流必须是0A电流,程序会在启动时获取0电流下的零点值带入后面的计算;
如果启动不是零点值,需要在重新启动读取0电流值计算才可以读数正确(或者自己更换后面计算的V_zero数值)
| ACS712            |STM32F103C8T6  | OLED|
| VCC(外部电源接5V)  | --           | --   |
| OUT               | 分压后接到PA0 | --   |
| GND(外部电源接地)  | GND          | GND  |
| --                | 3.3V          | VCC |
| --                | PB8           | SCL |
| --                | PB9           | SDA |
**********************************************/

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"

uint16_t ADValue;			    //定义AD值变量
float Voltage,Vsensor,Current;	//定义电压,电流变量
float sum = 0;
float V_zero;                   //定义零点电压变量

int main(void)
{
	/*模块初始化*/
	OLED_Init();			//OLED初始化
	AD_Init();				//AD初始化

	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "ADValue:");      //ad采样值
	OLED_ShowString(2, 1, "Voltage:0.00V"); //读取电压值
    OLED_ShowString(3, 1, "Vsensor:0.00V"); //OUT输出实际电压值
    OLED_ShowString(4, 1, "Current:0.00A"); //转换出来的电流值
    for(int i=0;i<20;i++)
    {   
        sum += AD_GetValue();
    }
        ADValue = sum / 20;
        sum = 0;
    V_zero = (float)ADValue / 4095 * 3.3 * 2.0f;//获取无电流下的零点电压值

	while (1)
	{
        /*滤波处理*/
        for(int i=0;i<20;i++)
        {   
            
            sum += AD_GetValue();
        }
        ADValue = sum / 20;                         //获取AD转换的平均值
        sum = 0;
//		ADValue = AD_GetValue();					//获取AD转换的值
		Voltage = (float)ADValue / 4095 * 3.3;		//将AD值线性变换到0~3.3的范围,表示电压
        Vsensor = Voltage * 2.0f;
        Current = (Vsensor - V_zero) / 0.185f;		    //获取读出的电压,换算成电流
		
		OLED_ShowNum(1, 9, ADValue, 4);				//显示AD值
		OLED_ShowNum(2, 9, Voltage, 1);				//显示读取电压值的整数部分
		OLED_ShowNum(2, 11, (uint16_t)(Voltage * 100) % 100, 2);	//显示读取电压值的小数部分
        OLED_ShowNum(3, 9, Vsensor, 1);				//显示OUT电压值的整数部分
		OLED_ShowNum(3, 11, (uint16_t)(Vsensor * 100) % 100, 2);	//显示OUT电压值的小数部分
		OLED_ShowNum(4, 9, Current, 1);				//显示电流值的整数部分
		OLED_ShowNum(4, 11, (uint16_t)(Current * 100) % 100, 2);	//显示电流值的小数部分
        Delay_ms(300);			//延时300ms,手动增加一些转换的间隔时间
	}
}

四、测试现象

4.1 理想数据

4.2 实测数据


五、常见问题

Q1: 读数一直为 0?

  • 检查 ACS712 供电是否正常
  • 检查 OUT 引脚是否连接到 PA0
  • 确认 ADC 通道配置正确

Q2: 读数跳变很大?

  • 增加采样次数(建议 10-20 次平均)
  • 添加软件滤波(滑动平均/中值滤波)
  • 检查电源是否稳定

Q3: 负电流显示?

  • 空载时零点电压可能不是精确 VCC/2
  • 运行校准程序获取实际零点
  • 检查电流方向是否正确

Q4: 精度不够?

  • ACS712 本身精度约±3%
  • 高精度需求建议使用 INA219 等专用芯片
  • 校准实际灵敏度参数

如果觉得有帮助,欢迎点赞👍 收藏⭐ 关注📌!

有问题或者需要资料请在评论区留言~

相关推荐
程序员打怪兽3 小时前
生产消费模型与多线程架构
嵌入式
崇山峻岭之间3 小时前
单片机外部中断实验
单片机·嵌入式硬件
chipsense3 小时前
工业UPS电流传感器选型实战指南:AS1V系列如何应对工业配电特殊挑战
单片机·嵌入式硬件·ups·电流传感器
振浩微433射频芯片4 小时前
告别“喊破嗓”:深度解析433MHz射频在宠物训练器中的核心应用与选型
单片机·嵌入式硬件·物联网·学习·宠物
╰⋛⋋⊱⋋翅膀⋌⊰⋌⋚╯4 小时前
ESP32-NVS保存
单片机
Hall_IC5 小时前
意法半导体STM32F103RCT6分销商
stm32·单片机·嵌入式硬件
世微 如初6 小时前
基于AP5160的大功率LED恒流驱动设计:原理分析与外围计算
驱动开发·单片机·芯片
程序员打怪兽6 小时前
跨平台相机适配方案总结
嵌入式
华清远见IT开放实验室6 小时前
硬核根基,智能载体:华清远见嵌入式“硬件+仿真+课程+师资”产教融合与实践教学方案
linux·人工智能·stm32·物联网·嵌入式·虚拟仿真