#include
<
AT89X51.h
>
float Vtest;
sbit ISet = 0x90 ;
sbit VSet = 0x91 ;
sbit ChipOn = 0x93 ;
sbit ChipOff = 0x92 ;
float R12 = 20000 ;
float GetV(bit channel)
{
if (channel)
B=0x01;
else
B=0x00;
#pragma ASM
ADCS BIT P1.7 ;使能接口
ADCLK BIT P1.6 ;时钟接口
ADDO BIT P1.5 ;数据输出接口(复用)
ADDI BIT P1.4 ;数据输入接口
;以下语句在调用转换程序前设定
ADCONV:
SETB ADDI ;初始化通道选择
NOP
NOP
CLR ADCS ;拉低/CS端
NOP
NOP
SETB ADCLK ;拉高CLK端
NOP
NOP
CLR ADCLK ;拉低CLK端,形成下降沿
MOV A,B
MOV C,ACC.1 ;确定取值通道选择
MOV ADDI,C
NOP
NOP
SETB ADCLK ;拉高CLK端
NOP
NOP
CLR ADCLK ;拉低CLK端,形成下降沿2
MOV A,B
MOV C,ACC.0 ;确定取值通道选择
MOV ADDI,C
NOP
NOP
SETB ADCLK ;拉高CLK端
NOP
NOP
CLR ADCLK ;拉低CLK端,形成下降沿3
SETB ADDI
NOP
NOP
MOV R7,#8 ;准备送下后8个时钟脉冲
AD_1:
MOV C,ADDO ;接收数据
MOV ACC.0,C
RL A ;左移一次
SETB ADCLK
NOP
NOP
CLR ADCLK ;形成一次时钟脉冲
NOP
NOP
DJNZ R7,AD_1 ;循环8次
MOV C,ADDO ;接收数据
MOV ACC.0,C
MOV B,A
MOV R7,#8
AD_13:
MOV C,ADDO ;接收数据
MOV ACC.0,C
RR A ;左移一次
SETB ADCLK
NOP
NOP
CLR ADCLK ;形成一次时钟脉冲
NOP
NOP
DJNZ R7,AD_13 ;循环8次
CJNE A,B,ADCONV ;数据校验
SETB ADCS ;拉高/CS端
CLR ADCLK ;拉低CLK端
SETB ADDO ;拉高数据端,回到初始状态
RET
#pragma ENDASM
return ACC/0xff * 5;
}
// 预充电
void Charge0()
{
int i;
VSet=0;
for(i=0;i<10;i++)
if(i<1)
ISet=1;
else
ISet=0;
}
// 恒流充电
void Charge1()
{
VSet=0x00;
ISet=1;
}
// 涓流保护
void Charge3()
{
int i;
VSet=0;
for(i=0;i<10;i++)
if(i<1)
ISet=1;
else
ISet=0;
}
// 恒压充电
void Charge2()
{
float temp_V;
float temp_I;
temp_V=GetV(1);
temp_I=((temp_V/0xff*5)/R12)*1000;
if(temp_I>50)
{
ISet=0;
VSet=1;
}
else
{
Charge3();
}
}
void main ( void ) {
ChipOff=0;
ChipOn=1;
while(1)
{
Vtest=GetV(0);
if (Vtest<=2.5)
{
Charge0();//预充电
}
else if (Vtest>2.5 & Vtest<4.2)
{
Charge1();//恒流充电
}
else
{
Charge2();//恒压充电
}
}
}
float Vtest;
sbit ISet = 0x90 ;
sbit VSet = 0x91 ;
sbit ChipOn = 0x93 ;
sbit ChipOff = 0x92 ;
float R12 = 20000 ;
float GetV(bit channel)
{
if (channel)
B=0x01;
else
B=0x00;
#pragma ASM
ADCS BIT P1.7 ;使能接口
ADCLK BIT P1.6 ;时钟接口
ADDO BIT P1.5 ;数据输出接口(复用)
ADDI BIT P1.4 ;数据输入接口
;以下语句在调用转换程序前设定
ADCONV:
SETB ADDI ;初始化通道选择
NOP
NOP
CLR ADCS ;拉低/CS端
NOP
NOP
SETB ADCLK ;拉高CLK端
NOP
NOP
CLR ADCLK ;拉低CLK端,形成下降沿
MOV A,B
MOV C,ACC.1 ;确定取值通道选择
MOV ADDI,C
NOP
NOP
SETB ADCLK ;拉高CLK端
NOP
NOP
CLR ADCLK ;拉低CLK端,形成下降沿2
MOV A,B
MOV C,ACC.0 ;确定取值通道选择
MOV ADDI,C
NOP
NOP
SETB ADCLK ;拉高CLK端
NOP
NOP
CLR ADCLK ;拉低CLK端,形成下降沿3
SETB ADDI
NOP
NOP
MOV R7,#8 ;准备送下后8个时钟脉冲
AD_1:
MOV C,ADDO ;接收数据
MOV ACC.0,C
RL A ;左移一次
SETB ADCLK
NOP
NOP
CLR ADCLK ;形成一次时钟脉冲
NOP
NOP
DJNZ R7,AD_1 ;循环8次
MOV C,ADDO ;接收数据
MOV ACC.0,C
MOV B,A
MOV R7,#8
AD_13:
MOV C,ADDO ;接收数据
MOV ACC.0,C
RR A ;左移一次
SETB ADCLK
NOP
NOP
CLR ADCLK ;形成一次时钟脉冲
NOP
NOP
DJNZ R7,AD_13 ;循环8次
CJNE A,B,ADCONV ;数据校验
SETB ADCS ;拉高/CS端
CLR ADCLK ;拉低CLK端
SETB ADDO ;拉高数据端,回到初始状态
RET
#pragma ENDASM
return ACC/0xff * 5;
}
// 预充电
void Charge0()
{
int i;
VSet=0;
for(i=0;i<10;i++)
if(i<1)
ISet=1;
else
ISet=0;
}
// 恒流充电
void Charge1()
{
VSet=0x00;
ISet=1;
}
// 涓流保护
void Charge3()
{
int i;
VSet=0;
for(i=0;i<10;i++)
if(i<1)
ISet=1;
else
ISet=0;
}
// 恒压充电
void Charge2()
{
float temp_V;
float temp_I;
temp_V=GetV(1);
temp_I=((temp_V/0xff*5)/R12)*1000;
if(temp_I>50)
{
ISet=0;
VSet=1;
}
else
{
Charge3();
}
}
void main ( void ) {
ChipOff=0;
ChipOn=1;
while(1)
{
Vtest=GetV(0);
if (Vtest<=2.5)
{
Charge0();//预充电
}
else if (Vtest>2.5 & Vtest<4.2)
{
Charge1();//恒流充电
}
else
{
Charge2();//恒压充电
}
}
}