高端电流检测

写在前面
本文为个人微信公众号文章,在硬件电路模块中的“高端电流检测”一文,建议扫描下方二维码观看,微信中排版清晰,有助于阅读,还可以找我拿材料哦!
高端电流检测_第1张图片
原文链接:https://mp.weixin.qq.com/s?__biz=Mzg5MDA5ODE2Nw==&mid=2247483789&idx=1&sn=259a7d5a7a441ee02acbbeb69a35917c&chksm=cfe09915f89710032612f5a711bc72285309c372dc58bf497977060837d052efccdad1d39ed5&token=480517982&lang=zh_CN#rd
正文开始
本篇文章是介绍通过高端电流检测放大器MAX4372与芯片STC12C5A60S2组合电路来检测输入电压、输出电压、输出电流,并最终使用LCD1602显示,要求做到误差小于正负0.1。
下面附上成功图片,以免各位看的没底(看完文章,如有需要材料可点击微信公众号中“个人”,找我免费拿):
高端电流检测_第2张图片那么下面我们先从MAX4372这个模块电路说起:
1、MAX4372概述
MAX4375是MAXIM公司最新推出的高端电流检测放大器,工作电压+2.7V到+28V,电源电流30uA,放大器增益分20/50/100三档,具有与电源电压无关的0V+28V共模输入范围,输出电压2V10V,满刻度准确性0.18%,输出阻抗1.5Ω,容性负载1000PF,可应用与电流保护/电流检测设备、4~20mA电流环系统、可编程电流源、智能电池/充电器等系统中。
2、引脚排列及功能
高端电流检测_第3张图片
典型应用电路图
高端电流检测_第4张图片
3实际应用图片
实际电路图:
高端电流检测_第5张图片
排版图:
高端电流检测_第6张图片
接下来介绍的是使用STC12C5A60S2芯片的AD转换功能,来实现输入电压、输出电压、输出电流的显示。
1、STC12C5A60S2 AD转换功能原理知识
先来一张引脚图:
高端电流检测_第7张图片
再来看下一张:高端电流检测_第8张图片
整理出来的重点有如下几点:
一、
AD转换结束后,最终的转换结果保存到ADC转换结果寄存器ADC_RES和ADC_RESL,同时,置位ADC控制寄存器ADC_CONTR中的A/D转换结束标志位ADC_FLAG,以供程序查询或发出中断申请。
二、
模拟通道的选择控制由ADC控制寄存器ADC_CONTR中的CHS2~CHS0确定。
三、
ADC的转换速度由ADC控制寄存器中的SPEED1和SPEED0确定。
四、
在使用ADC之前,应先给ADC上电,也就是置位ADC控制寄存器中的ADC_POWER位。
五、
AUXR1辅助寄存器的ADRJ位是A/D转换结果寄存器(ADC_RES、ADC_RESL)的数据格式调整控制位。当ADRJ=0时,10位A/D转换结果的高8位存放在ADC_RES中,低2位存放在ADC_RESL的低2位中。当ADRJ=1时,10位A/D转换结果的高2位存放在ADC_RES中,低8位存放在ADC_RESL的低2位中。
P1口模拟功能控制寄存器P1ASF
高端电流检测_第9张图片
ADC控制寄存器ADC_CONTR
在这里插入图片描述
ADC_POWER:
ADC电源控制位:
0:关闭A/D转换器电源
1:打开A/D转换器电源
高端电流检测_第10张图片
STC12C5A60S2系列单片机的A/D转换模块所使用的时钟是内部R/C振荡器所产生的系统时钟。
ADC_FLAG:
数模转换器转换结束标志位,当A/D转换完成后,ADC_FLAG=1,一定要软件清零。
ADC_START:
数模转换器(ADC)转换启动控制位,设置为1时,开始转换,转换结束后为零。
高端电流检测_第11张图片
设置ADC_CONTP控制寄存器后,要加4个空操作延时才可以正确读到ADC_CONTR寄存器的值。
EA:
CPU的中断开放标志位,EA=1,CPU开放中断,EA=0,CPU屏蔽所有的中断申请。
EADC:
A/D转换中断允许位。
EADC=1,允许A/D转换中断;
EADC=0,禁止A/D转换中断。
PADCH,PADC:
A/D转换中断优先级控制位。
当PADCH=0且PADC=0时,A/D转换中断为最低优先级中断(优先级0)
当PADCH=0且PADC=1时,A/D转换中断为较低优先级中断(优先级1)
当PADCH=1且PADC=1时,A/D转换中断为较高优先级中断(优先级2)
当PADCH=1且PADC=1时,A/D转换中断为最高优先级中断(优先级3)
2、STC12C5A60S2 AD转换、LCD显示核心代码(因为代码量大,这里只有核心代码,如有需要完整代码,可直接找我免费拿)

#include "reg51.h"
#include "intrins.h"
#include "1602.h"					
#include "ADC.H"
#include "Display.h"
/*****************主函数*****************/
unsigned char set;
void main()
{
	unsigned int a;
    double VIN,VOUT,VOI;	    //输入、输出电压、电流存放变量
	unsigned int UIN,UOUT,UOI;	//定义ADC结果读回存放变量
	LcdInit();		            //LCD初始化
	InitADC();	                //ADC初始化
	set = 32;	                //设置默认关断电流阀值
	while(1)
	{
		UIN = GetADCResult(0);		    //读取输入电压
		UOUT = GetADCResult(1);       	//读取输出电压
		UOI = filter(2);	            //读取输出电流值,并采用中位值滤波	
		VIN = (float)UIN*5/1024*4;		//计算输入电压
		VIN *=10000;
		if(VIN>160000)
			VIN += 1000;
		if(VIN>10000)
			VIN += 1000;
		VOUT = (float)UOUT*5/1024*3;	//计算输出电压
		VOUT *=10000;
		VOI = (float)UOI*5/1024;	    //计算输出电流
		VOI /= 0.128;
		VOI *= 10000;
		if(VOI>30000)
		VOI += 2000;
		if(VOI>14500)
		VOI += 1000;
		if(VOI>6000)
		VOI += 200;
		if(VOI>100)
		VOI += 2000;
/********显示结果*************/
		V_IN(VIN);
		V_OUT(VOUT);
		V_OI(VOI);
		SET(set);
    }
}

下面为ADC.c代码

//++++++++++++++++++++++++++++++++++++++++++++++
//+以下代码中ADC及串口配置部分引用了STC的代码+
//++++++++++++++++++++++++++++++++++++++++++++++
#include "reg52.h"
#include "intrins.h"
/******ADC功能寄存器*********/
sfr ADC_CONTR   =   0xBC;           //ADC控制寄存器     //BC 地址   
sfr ADC_RES     =   0xBD;           //ADC高8位结果   //转换结果
sfr ADC_RESL    =   0xBE;			//ADC低2位结果   //转换结果
sfr P1ASF       =   0x9D;           //P1口第2功能控制寄存器   模拟功能配置寄存器
#define ADC_POWER   0x80            //ADC电源控制位
#define ADC_FLAG    0x10            //ADC完成标志
#define ADC_START   0x08            //ADC起始控制位
#define ADC_SPEEDLL 0x00            //540个时钟
#define ADC_SPEEDL  0x20            //360个时钟
#define ADC_SPEEDH  0x40            //180个时钟
#define ADC_SPEEDHH 0x60            //90个时钟
#define N 21                        //ADC中值滤波次数,必须为基数
/*----------------------------
软件延时
----------------------------*/
void Delay(unsigned int n)
{
    unsigned int x;
    while (n--)
    {
        x = 5000;
        while (x--);
    }
}
/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
    P1ASF = 0x07;                   //设置P1口为AD口      0000 0111            //P1ASF  模拟功能配置寄存器
    ADC_RES = 0;                    //清除结果寄存器(高位)
		ADC_RESL= 0;										//清除结果寄存器(低位)
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
    Delay(2);                       //ADC上电并延时
	//yan:ADC_POWER=1;
	//yan:ADC_FLAG=1;
}
/*----------------------------
读取ADC结果
----------------------------*/
unsigned int GetADCResult(unsigned char ch)
{
		unsigned int rew;
    ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
    _nop_();                            //等待4个NOP
    _nop_();
    _nop_();
    _nop_();
    while (!(ADC_CONTR & ADC_FLAG));    //等待ADC转换完成
    ADC_CONTR &= ~ADC_FLAG;             //Close ADC
		rew=ADC_RES*4+ADC_RESL;         //组合成10位
		_nop_();
		_nop_();
    //return ADC_RES;                      //返回ADC结果
		return rew;
}
unsigned int filter(unsigned char dat)     //中位值滤波
{
   unsigned int value_buf[N];
   unsigned int count,i,j,temp;
   for(count=0;countvalue_buf[i+1] )
         {
            temp = value_buf[i];
            value_buf[i] = value_buf[i+1];
            value_buf[i+1] = temp;
         }
      }
   }
   return value_buf[(N-1)/2];
}
void timer_init(void)//定时器初始化
{
	TMOD=0x01;/////////设置工作方式1
	TH0=(65536-50000)/256;///////赋值
	TL0=(65536-50000)%256;
	EA=1;ET0=1;//开总中断;开定时器中断
	TR0=1;////////启动计数器
}

你可能感兴趣的:(单片机,硬件电路)