link
#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();//恒压充电
}
}
}
转载于:https://www.cnblogs.com/JonsonXP/archive/2007/06/26/795708.html