基于51单片机的太阳能锂电池充电器系统电压电流检测方案原理图设计
系统功能分析本系统具体框图如下图所示本设计由STC89C52单片机+LCD1602液晶显示电路+A/D转换芯片PCF8591电路+电压检测电路+电流检测电路ACS712-5A+继电器控制电路+电源电路设计而成。1、通过太阳能电池板给锂电池充电,通过单片机检测太阳能给电池的充电电压和充电电流,并在1602液晶上显示出来!2、通过继电器,有过压保护,当锂电池充电电压超过了4.5V或者充电电流超过1A,
原文:http://www.jh-tec.cn/archives/8280
系统功能分析
本系统具体框图如下图所示
本设计由STC89C52单片机+LCD1602液晶显示电路+A/D转换芯片PCF8591电路+电压检测电路+电流检测电路ACS712-5A+继电器控制电路+电源电路设计而成。
1、通过太阳能电池板给锂电池充电,通过单片机检测太阳能给电池的充电电压和充电电流,并在1602液晶上显示出来!
2、通过继电器,有过压保护,当锂电池充电电压超过了4.5V或者充电电流超过1A,继电器断开,充电停止。
3.1.2系统总体结构
原理图
PCF8591 A/D采样电路设计
本系统选择PCF8591作为A/D采样芯片。PCF8591是一个单片集成、单独供电、低功耗、8-bit CMOS数据获取器件。PCF8591具有4个模拟输入、1个模拟输出和1个串行I²C总线接口。PCF8591的3个地址引脚A0, A1和A2可用于硬件地址编程,允许在同个I2C总线上接入8个PCF8591器件,而无需额外的硬件。在PCF8591器件上输入输出的地址、控制和数据信号都是通过双线双向I2C总线以串行的方式进行传输。
一、芯片特性
(1)单独供电
(2)PCF8591的操作电压范围2.5V-6V
(3)低待机电流
(4)通过I2C总线串行输入/输出
(5)PCF8591通过3个硬件地址引脚寻址
(6)PCF8591的采样率由I2C总线速率决定
(7)个模拟输入可编程为单端型或差分输入
(8)自动增量频道选择
(9)PCF8591的模拟电压范围从VSS到VDD
(10)PCF8591内置跟踪保持电路
(11)8-bit逐次逼近A/D转换器
其具体原理图如下图所示。两个电阻为上拉电阻,让数字信号的读取更稳定。
分压电路设计
串联分压的原理:
在串联电路中,各电阻上的电流相等,各电阻两端的电压之和等于电路总电压。可知每个电阻上的电压小于电路总电压,故称串联电阻分压。
在设计中,选择的A/D芯片采集的5V电压,故超过5V的电压需要分压后降压为0-5V才可以经过A/D转换。其电路原理理图如下图所示。
ACS712电流传感器模块电路设计
该传感器使用芯片为ACS712-05A,能够检测5A范围内的直流电流。ACS712芯片专们用于电流检测芯片, 高度集成的制作工艺和专业的电流检测技术可为各种交直流电流检测提供经济实惠且精确的解决方案。该器件封装便于客户轻松实施。ACS712芯片的经典应用于开关式电源设备和过电流故障保护、载荷检测和管理系统、电动机控制系统等。
ACS712芯片,使用了精准的,低偏置的线性霍尔传感器电路,且其电流路径强敌了电流路径的阻抗,宁切路径靠近晶片的表面更增加了测量的准确度。
通过该通知的电流路径施加上电流,是芯片内部产生磁场,磁场被集成在内部的霍尔器件获取,并转化为一定比例的电压值。通过该电压值经过AD转化被微处理器获取,精处理后可以显示,该期间在出厂时已经进行了精确度的校准。
当芯片内部中的电流路径(从引脚 1 和 2,到 引脚3 和 4)的电流持续上升的时候,器件的输出属于正斜率 (>VIOUT(Q))。这是的 ACS712 电流传感器 IC 可以使用在那些要求电气绝缘但没有使用光电绝缘器以及其它昂贵绝缘技术的应用。
程序流程图
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include<stdio.h>
#include "1602.h"
#include "delay.h"
#include "i2c.h"
sbit relay=P1^0; //继电器接口
unsigned char dis0[16]; //打印数组初始化
unsigned long time_20ms=0; //定时器计数
unsigned char count =0; //采集次数计数
float Volt=0.0; //检测电压
xdata float sumVolt,midV; //用于滤波 中间变量
float Acurrent=0.0; //检测电流
xdata float sumAcur,midA; //用于滤波 中间变量
void Init_Timer0(void); //函数声明
void uartSendStr(unsigned char *s,unsigned char length);
void UART_Init(void);
void uartSendByte(unsigned char dat);
void main (void)
{
Init_Timer0(); //定时器0初始化
UART_Init();
LCD_Init(); //初始化液晶
DelayMs(20); //延时有助于稳定
LCD_Clear();
relay=0; //初始化测试继电器
DelayMs(200);
relay=1;
LCD_Write_String(0,0,"my designer ! ");//显示
uartSendStr("reday ok!!",10);
while (1) //主循环
{
midV=(float)ReadADC(1)*5.2/255*5; //计算出电压 *3表示分压值
DelayMs(2); //延时有助于稳定
Acurrent=(float)ReadADC(0)*5.2/255; //计算出电流
if(Acurrent>2.62) //如果电流转换后的电压值超过2.62
{midA=(Acurrent-2.62)/0.185;} //电流模块 电压转换计算
else
{midA=0;}
if(midA < 0.15) midA = 0; //防止参考电压变化造成影响
sumAcur = sumAcur + midA; //多次测量求平均
sumVolt = sumVolt + midV; //多次测量求平均
count++;//采集次数
if(count >= 5)
{
count = 0;
Acurrent = sumAcur/5; //Q求平均
if(Acurrent < 0.1) Acurrent= 0;//滤波微小波动
sumAcur = 0;
Volt = sumVolt/5;
if(Volt<1)Volt=0;
sumVolt =0;
if(((Acurrent>=1.0)||(Volt>=4.5))&&(time_20ms>100)) //对比电压电流值
{
relay=0; //继电器动作
}
sprintf(dis0,"V:%3.2fv A:%3.2fA ",Volt,Acurrent);//打印电压电流值
LCD_Write_String(0,1,dis0);//显示第二行
if(((Acurrent>=1.0)||(Volt>=4.5))&&(time_20ms>100)) //对比电压电流值
{
relay=0; //继电器动作
}
}
DelayMs(40); //延时有助于稳定
}
}
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0=(65536-20000)/256; //重新赋值 20ms
TL0=(65536-20000)%256;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
void Timer0_isr(void) interrupt 1
{
TH0=(65536-20000)/256; //重新赋值 20ms
TL0=(65536-20000)%256;
time_20ms++;
}
void UART_Init(void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TL1 = TH1;
TR1 = 1; // TR1: timer 1 打开
EA = 1; //打开总中断
ES = 1; //打开串口中断
}
void uartSendByte(unsigned char dat)
{
unsigned char time_out;
time_out=0x00;
SBUF = dat; //将数据放入SBUF中
while((!TI)&&(time_out<100)) //检测是否发送出去
{time_out++;DelayUs2x(10);} //未发送出去 进行短暂延时
TI = 0; //清除ti标志
}
void uartSendStr(unsigned char *s,unsigned char length)
{
unsigned char NUM;
NUM=0x00;
while(NUM<length) //发送长度对比
{
uartSendByte(*s); //放松单字节数据
s++; //指针++
NUM++; //下一个++
}
}
void UART_SER (void) interrupt 4 //串行中断服务程序
{
if(RI) //判断是接收中断产生
{
RI=0; //标志位清零
}
if(TI) //如果是发送标志位,清零
TI=0;
}
更多推荐
所有评论(0)