一、 功能简介:
基于 51 单片机的智能充电器系统
通过定时器定时从 A/D 上读取数据,根据不同的电压选择不同的控制充电方案,
使用 PWM 控制输出脉宽来控制电流。
二、 器件以及接口
本文中使用了 8051 和 ADC0809 芯片。下面对所使用的器件以及器件和单片机的接
口作以下说明。
1、器件和原理
本文中主要使用的器件是可以进行 A/D 转换的 8 位 ADC0809 芯片。ADC0809 是一
种逐次逼近式 8 路模拟输入、8 位数字量输出的 A/D 转换器。其引脚如图 1 所示。
In3
In4
In5
In6
In7
START
EOC
-52
OUTPUTENABLE
CLOCK
VCC
(+)
GND
-7
VREE
2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
28
27
26
25
24
23
22
21
20
19
18
17
16
15
In2
In1
In0
ADDA
ADDB
ADDC
ALE
-1
2 MSB
2
2
2
-8
2
V
REE
-6
2
LSB
(-)
-2
-3
-4
图 1 ADC0809 外观图
由引脚图可知,ADC0809 共有 28 引脚,采用双列直插式封装。其主要引脚功能如
下。
(1)、IN0~IN7 是 8 路模拟信号输入端。
(2)、2^(-1)~2^(-8)是 8 位数字量输出端。
(3)、ADDA、ADDB、ADDC 与 ALE 控制 8 路模拟通道的切换,ADDA、ADDB、ADDC 分别与
3 根地址线或数据线相连,三者编码对应 8 个通道地址口。ADDC、ADDB、ADDA=000~111
分别对应 IN0~IN7 通道地址。
(4)、OUTPUT ENABLE、START、CLK 为控制信号端,OUTPUT ENABLE 为输出允许端、START
为启动信号输入端、CLK 为时钟信号输入端。
(5)、VREF(-)和 VREF(+)为参考电压输入端。
2、器件的接口
在讨论 8051 与 ADC0809 的接口设计之前,先来讨论单片机如何控制 ADC 的问题。
用单片机控制 ADC 时,多数采用查询和中断控制两种方法。查询法是在单片机把启
第 1 页 共 10 页
动命令送到 ADC 之后,执行别的程序,同时对 ADC 的状态进行查询,以检查 ADC 变换
是否已经结束,如查询到变换已结束,则读入转换完毕的数据。
中断控制法是在启动信号达到 ADC 之后,单片机执行别的程序。当 ADC 变换结束并
向单片机发出中断请求信号时,单片机响应此中断请求,进入中断服务程序。读入转
换数据,并进行必要的数据处理,然后返回到原程序。这种方法单片机无需进行转换
时间的管理。CPU 效率高,所以特别适合于变换时间较长的 ADC。
如果对转换速度要求高,采用上述两种 ADC 控制方式往往不能满足要求,可采用
DMA(直接存储器存取)的方法,这时可在 ADC 与单片机之间插入一个 DMA 接口(例如,
btel 公司的 8237DM 控制器)。传输一开始,AD 转换的数据就可以从输出寄存器经过 DMA
中的数据寄存器直接传输到主存储器,因而不必受程序的限制。
在本文中,采用中断方式。从 ADC0809 与 8051 的中断方式接口电路如硬件电路图
2 和图 3 所示,ADC0809 和 8051 的 INT0 管脚连接,当转换结束的时候,EOC 向 8051
发送一个脉冲信号,提出中断申请,单片机响应中断请求,由外部中断 l 的中断服务
程序读 A/D 结果,并启动 8051 的下一个转换,外部中断 1 采用跳沿触发方式。
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
17
9
30
29
31
20
U1 8051
P1 0.
P1 1.
P1 2.
P1 3.
P1 4.
P1 5.
P1 6.
P1 7.
. /
. /
. /
. /
. /
. /
. /
. /
P3 0 RXD
P3 1 TXD
P3 2 INT0
P3 3 INT1
P3 4 T0
P3 5 T1
P3 6 WR
P3 7 RD
RST
ALE PROG
/
PSEN
EA
GND
VCC
P0 0.
P0 1.
P0 2.
P0 3.
P0 4.
P0 5.
P0 6.
P0 7.
P2 0.
P2 1.
P2 2.
P2 3.
P2 4.
P2 5.
P2 6.
P2 7.
XTAL2
XTAL1
40
39
38
37
36
35
34
33
32
21
22
23
24
25
27
27
28
18
19
VCC
D7
D6
D5
D4
D3
D2
D1
D0
PWM contralor
C6
100pF
Crystal
.
11 0592MHZ
2
1
C7
VCC
U3
74F138SJ
VCC
16
15
14
13
12
11
10
9
7
D7
D6
D5
D4
D3
D2
D1
D0
VCC
Y0
Y1
Y2
Y3
Y4
Y5
Y6
Y7
D2
1
D1 2
D0 3
A
B
C
Vcc
6
4
5
8
Oe1
OE2A
OE2B
GND
1
2
1
2
U4A
74F00PC
3
U5A
74F00PC
3
VCC
1
9
10
7
2
3
4
5
6
8
RST
PE
CET
CEP
CLK
P0
P1
P2
P3
GND
16
15
14
13
12
11
VCC
TC
Q0
Q1
Q2
Q3
U6
DM74163N
图 2 智能充电器原理电路图
第 2 页 共 10 页
U2
ADC0809CN
VCC
10
6
26
27
28
1
2
3
4
5
CLK
START
In0
In1
In2
In3
In4
In5
In6
In7
25
24
23
22
ADDA
ADDB
ADDC
ALE
13 GND
D2
D1
D0
VCC
EOC
OE
D0
D1
D2
D3
D4
D5
D6
D7
VREF+
VREF-
11
7
9
17
14
15
8
18
19
20
21
12
16
D7
D6
D5
D4
D3
D2
D1
D0
VCC
U3
74F138SJ
VCC
D2 1
D1 2
D0 3
A
B
C
Vcc
6
4
5
8
Oe1
OE2A
OE2B
GND
VCC
16
15
14
13
12
11
10
9
7
D7
D6
D5
D4
D3
D2
D1
D0
Analog Voltage Input
Y0
Y1
Y2
Y3
Y4
Y5
Y6
Y7
U 4A
74F00PC
3
U5A
74F00PC
3
1
2
1
2
VCC
VCC
U6
DM74163N
1
9
10
7
2
3
4
5
6
8
RST
PE
CET
CEP
CLK
P0
P1
P2
P3
GND
16
15
VCC
TC
14
13
12
11
Q0
Q1
Q2
Q3
三、硬件电路图
图 3 智能充电器原理电路图
本文中,单片机电路主要包括 8051 和 ADC0809 两块芯片,DM74163N 用做分频器,
74F138SJ 用来产生和选择地址。具体的连接原理电路图如图 2 和图 3 所示。其中,8051
的晶振频率为 11.0592MHz。电路有 2 个输入输出端口,Analog Voltage Input 是作为
电池组电压的输入,PWM contraltor 是做为电池组控制脉宽的输出。
四、软件程序设计
本文为智能充电器,传统充电器采用电流负反馈来进行控制,本程序使用 8051 单
片机作为控制器进行控制。
对于电池中不同的电量,如果采取同样的方案,不会获得满意的充电效果,一般根
据电池两端不同的电压值采取不同的方案进行充电。
本文中,将采集电池组的电压值,通过 ADC 转到单片机,在单片机端接收到信号后,
根据不同的电压情况采取不同的方案。当电压非常小的时候,采取方案 1 来充电,方
案 l 采取小电流充电;当电压比较小但是不是极小的时候,采取方案 2 来充电,方案 2
采取较大电流充电;当电压达到正常电压的时候,采取方案 3 来充电,方案 3 采取恒
流充电;对于电压超出正常电压,采取方案 4,即不充电的方案。
本文中,采用定时查询电压的机制,定时器每 500ms 给出标志位,查询 A/D 上的
电压值,根据不同的电压值选择不同的方案。
对于电流的控制,采用 PWM 控制脉宽的方法来控制电流,应用不同的占空比,占空
第 3 页 共 10 页
比越高,电流越大。
下面将首先对程序的主要模块进行介绍,然后给出整个程序。
(1)、初始化
在初始化程序中,需要进行与定时器相关的寄存器的初始化以及各个标志位和计
数位的清零,如果采用中断方式,还包括与中断相关的寄存器。
本文中,电路中采用的晶振频率 fosc=11.0592MHz,需要每 500ms 查询 l 次,将
定时器设置成 16 位计数器,根据计算,可以得出定时器 T0 的初值为 7936(1F00H),并
且中断中使用计数器,计满 8 就达到了 500ms。将方案选择位置 1,以便主程序查询。
初始化程序清单如下:
;设置堆栈
;设置 A/D 存储单元初始地址
;打开所有中断
;采集通道首地址,只使用一路 A/D 就可以
;程序开始,初始化各个寄存器以及标志位
START:
MOV SP,#050H
MOV R0,#030H
MOV IE,#0FFH
MOV DPTR,#78FFH
MOV R0,#40H
MOV @R0,#00H
MOV R0,#40H
MOV @R0,#00H
MOV R1,#042H
MOV @R0,#00H
LCALL TIMER1_INIT
;清除方案选择位
;清除方案选择触发位
;清除定时器计数器
;设置定时器 T1 为方式 2
;定时器 T0 工作在方式 1
;禁止定时器 T1
TIMER1_INIT:
ANL TMOD,#0FH
ORL TMOD,#10H
MOV TMOD,#21H
MOV PCON,#080H
CLR TR1
SETB EA
SETB ET1
SETB ET0
SETB PT0
CLR TF1
MOV TL0,#00H
MOV TH0,#01FH
SETB TR0
CLR TF0
RET;
(2)、定时器中断
定时器中断是用来计时的,在中断中使用软件计数来达到想要的时间。当时间到达
0FFFFH 后,再跳到 O000H,TFX 位就会申请中断。使用定时器 T0,那么 TF0 位会申请
中断,进入中断服务程序,进行中断处理,设置相应的触发标志位。应当注意的是,
在采用中断方式处理时,对于中断中使用到的寄存器、变量(作为全局变量使用的除外)
;定时器 T0 中断发生时间为 62.5ms
;定时器 T0 中断优于串口中断
;使能定时器 T0
第 4 页 共 10 页
应当进行压栈处理,并且更换寄存器的区域。
;程序状态字入栈
;切换寄存器区域
;累加器入栈
;禁止定时器 T0
;清除定时器中断 TF0
;进入定时器中断,每 500ms 设置 1 次标志位
TIMER0_INIT:
PUSH ACC
PUSH PSW
MOV PSW,#18H
CLR TF0
CLR TR0
MOV TL0,#00H
MOV TH0,#01FH
CLR TF0
MOV R1,#042H
INC @R1
CJNE @R1,#08H,TIMER0_READY
MOV @R1,#00H
MOV R1,#041H
MOV @R1,#01H
TIMER0_READY:
SETB TR0
POP PSW
POP ACC
RETI
;程序状态字出栈
;清除溢出中断位
;使能定时器 T0
;累加器出栈
;定时器 T0 中断发生时间为 6
;增加计数器的值,到 8 为止,这样达到 500ms
;清除计数器的值
;设置标志位,每 500ms 重新选择方案
(3)、A/D 转换器的使用
当 ADC 转换结束时,会向单片机发出中断请求信号,触发单片机的外部中断,这
时单片机响应此中断请求,进入中断服务程序,读取转换数据,ADC 读入的首地址要依
靠电路原理图来确定。程序清单如下:
;累加器压栈
;程序状态字压栈
;切换寄存器区域
;A/D 转换器首地址
EXTERN_INIT:
PUSH ACC
PUSH PSW
MOV PSW,#010H
MOV DPTR,#78FFH
MOVX A,@DPTR
MOV R1,#030H
MOV @R1,A
POP PSW
POP ACC
RETI
(4)、PWM 脉冲宽度的控制
在本文中,需要控制 PWM 脉冲的占空比来控制充电的电流,因此采用直接设置对
应管脚高低来产生脉冲,对于不同的要求,可以使用空跑来设置不同占空比。本文选
用方案 1.程序清单如下:
;存储 A/D 转换器的数据的地址
;将 A/D 的值读入该地址
;程序状态字出栈
;读入 A/D 的值
;累加器出栈
PROCESS_01:
MOV R1,#040H
MOV @R1,#01H
;选择方案 1
第 5 页 共 10 页
PROCESS_01_NEXT:
SETB P2.0
MOV R1,#0F0H
MOV R0,#00H
PROCESS_01_01:
DJNZ R1,PROCESS_01_01
DJNZ R0,PROCESS_01_01
CLR P2.0
MOV R1,#070H
MOV R0,#00H
PROCESS_01_02:
DJNZ R1,PROCESS_01_02
DJNZ R0,PROCESS_01_02
MOV R1,#041H
;将和 PMW 连接的管脚置高
;空跑 16×256×2 个周期
;将和 PMW 链接的管脚置低
; 空跑 16×256×2×9 个周期
;当方案改变标志位到来的时候,清除
;标志并且重新进行判断
CJNE @R1,#00H,CLEAR_FLAG
SJMP PROCESS_01_NEXT
注意:当输出脉冲的时候,应一直在查询方案改变标志位,当标志位到来的时候
跳出循环,重新选择新的万菜。
(5)、方案的选择控制
本实例中,在主程序中需要对不同的方案进行选择,需要根据输入信号的不同范
围进行跳转,对于 8051,通常与需要比较的数进行相减,然后读取进位标志位,根据
标志位来判断两个数的大小。程序清单如下:
;进入循环,查询标志位,采取不同的方案
LOOP:
MOV R0,#30H
;30H 是 AD 转换的地址,将数据和几个值
;进行比较,确定方案
MOV A,@R0
SUBB A,#30H
JC PROCESS_01
MOV A,@R0
SUBB A,#90H
JC PROCESS_02
MOV A,@R0
SUBB A,#90H
JZ PROCESS_03
;当电压很小的时候,采用第一种方案,
;向引脚 PWM 发送占空比为 10%的信号
;当电压较小的时候,采用第二种方
;案,向引脚 PWM 发送占空比为 20%的信号
; 当电压正好的时候,采用第三种方
;案,向引脚 PWM 发送占空比为 50%的信号
MOV A,#04H
; 当电压超出的时候,采用第四种方
;案,向引脚 PWM 发送占空比为 0%的信号
LJMP PROCESS_04
(6)、程序全貌
本文中,A/D 采用外部中断触发的方式,当数据到来的时候将数据读入,根据不
第 6 页 共 10 页
同的电压值选择不同方案,并且用定时器每 500ms 查询 l 次,改变原来的方案。程序
清单如下:
;外中断入口
;定时器中断入口
;智能充电器
;功能:通过定时器定时从 A/D 上读取数据,根据不同的电压选
;择不同的控制充电方案,使用 PWM 控制输出脉宽来控制电流
ORG 0000H
LJMP START
ORG 0003H
LJMP EXTERN_INT
ORG 000BH
LJMP TIMER0_INT
;程序开始,初始化各个寄存器以及标志位
START:
MOV SP,#050H
MOV R0,#030H
MOV IE,#0FFH
MOV DPTR,#78FFH
MOV R0,#40H
MOV @R0,#00H
MOV R0,#40H
MOV @R0,#00H
MOV R1,#042H
MOV @R0,#00H
LCALL TIMER1_INIT
;进入循环,查询标志位,采取不同的方案
LOOP:
MOV R0,#30H
;设置 A/D 存储单元初始地址
;30H 是 A/D 转换的地址,
;清除方案选择触发位
;清楚定时器计数器
;设置堆栈
;打开所有中断
;采集通道首地址,只使用一路 A/D 就可以
;清除方案选择位
MOV A,@R0
SUBB A,#30H
JC PROCESS_01
MOV A,@R0
SUBB A,#90H
JC PROCESS_02 ;
MOV A,@R0
SUBB A,#90H
JZ PROCESS_03
;将数据和几个值进行比较,确定方案
;当电压很小的时候,采用第一种方案,
;向引脚 PWM 发送占空比为 10%的信号
;当电压较小的时候,采用第二种方案,
;向引脚 PWM 发送占空比为 20%的信号
; ;当电压正好的时候,采用第三种方案,
;向引脚 PWM 发送占空比为 50%的信号
MOV A,#04H
; ;当电压超出的时候,采用第四种方案,
;向引脚 PWM 发送占空比为 0%的信号
LJMP PROCESS_04
CLEAR_FLAG:
第 7 页 共 10 页
MOV R0,#40H
MOV @R0,#00H
MOV R0,#41H
MOV @R0,#00H
LJMP LOOP
PROCESS_01:
MOV R1,#40H
MOV @R1,#01H
PROCESS_01_NEXT:
SETB P2.0
MOV R1,#0F0H
MOV R0,#00H
PROCESS_01_01:
DJNZ R1,PROCESS_01_01
DJNZ R0,PROCESS_01_01
CLR P2.0
MOV R1,#070H
MOV R0,#00H
PROCESS_01_02:
DJNZ R1,PROCESS_01_02
DJNZ R0,PROCESS_01_02
MOV R1,#041H
CJNE @R1,#00H,CLEAR_FLAG
SJMP PROCESS_01_NEXT
PROCESS_02:
MOV R1,#040H
MOV @R1,#02H
PROCESS_02_NEXT:
SETB P2.0
MOV R1,#0E0H
MOV R0,#00H
PROCESS_02_01:
DJNZ R1,PROCESS_02_01
DJNZ R0,PROCESS_02_01
CLR P2.0
MOV R1,#080H
MOV R0,#00H
PROCESS_02_02:
DJNZ R1,PROCESS_02_02
DJNZ R0,PROCESS_02_02
MOV R1,#041H
CJNE @R1,#00H,CLEAR_FLAG
;清除方案选择位
;清除触发位
;选择方案 1
;将和 PWM 连接的管脚置高
;空跑 16×256×2 个周期
;将和 PWM 连接的管脚置低
; 空跑 16×256×2×9 个周期
;当方案改变标志位到来的时候,
;清除标志并且重新进行判断
;选择方案 2
;将和 PWM 连接的管脚置高
; 空跑 16×256×2 个周期
; 将和 PWM 连接的管脚置低
; 空跑 16×256×2×8 个周期
;当方案改变标志位到来的时候,
;清除标志并且重新进行判断
第 8 页 共 10 页