COP820CJ是美国国家半导体公司生产的一款8位单片机,它内含64字节RAM和1k字节ROM,并带有24个I/O口,时钟频率为10MHz,工作电压为2.5~6.0V。COP820CJ具有多输入唤醒(MIWU)、低压复位保护、片上模拟比较器和低电磁辐射设计等功能,其I/O口可编程为三态、推挽输出、弱上拉输入等类型。
COP820CJ的端口分为L/I/D/G四类。其中I口为4位输入端口,D口为4位输出端口,G口有6位I/O口和2位输入口,L口为8位I/O口。同时L口也是芯片的唤醒端口,其中L1和L2又是比较器输入口,L3又是比较器输出口。L口配有数据寄存器(LDATA [0DOH])和配置寄存器(LCONF [0D1H]),两寄存器可共同决定该端口的状态。具体关系见表1所列。
表1 L口状态表
L口配置寄存器值 L口数据寄存器值 L口状态 0 0 高阻输入 0 1 输入(带弱上拉) 1 0 推挽输出'0' 1 1 推挽输出'1'
COP820CJ的片上RAM、端口、寄存器均可映射到00H~FEH的数据内存空间,其中C0~CFH段主要是唤醒及用看门狗控制寄存器,D0~DFH段有8个端口类寄存器,E0~EFH段为计时器和系统寄存器。00~2FH及F0~FFH为RAM地址。其中,F0~FEH段可用作寄存器,并包括B地址寄存器[FCH]、X地址寄存器[FEH]和SP堆栈指针[FDH]三个专用寄存器。
2 COP820CJ的工作原理
2.1 基本原理
利用COP820CJ的片上模拟比较器和脉冲宽度调制方式可以构成由软件调控且输入范围可变的A/D转换器。其工作原理图见图1所示。图中,L1和L2为比较器输入端,当电容电压小于输入电压时,L3端输出高电平脉冲。反之,L3输出低脉冲,并对低脉冲减1计数。电路中的输入电压可通过L1、L2之间并联的两个背向二极管对电容C1快速充放电,以使两者电位迅速接近。
比较器允许的输入电压为0.4V~VCC-1.5V(此时电容电压与充电、放电时间之间为近似线性关系),实际输入电压范围可能要更小一些。因此,可以通过设定高低脉冲的参数使电容电压始终保持在测量范围之内。若电源为5V,时钟频率为10MHz,脉冲周期为24个,即2.4μs,输入电压范围是1.0V~3.3V。那么,可以设置高脉冲为先低8个时钟,再高16个时钟;设置低脉冲为先高5个时钟,再低19个时钟。这样,如果L3始终输出高脉冲,电容电压VH将近似为Vcc×16/24=3.30V;如果L3始终输出低电平,电容电压VL则近似为Vcc×5/24=1.04V。进行A/D转换时,L3可根据比较结果输出高低脉冲,当脉冲数足够多时,计数器的值即代表了输入的电压值,并可用下式表示:
VIN=VL+(VH-VL)(NTON/NTOTAL)
其中,NTON为计数器的值,NTOTAL为总脉冲数。
2.2 转换时间及分辨率
由于脉冲周期为2.4μs,若脉冲总数为100,那么,进行两次计数的转换时间近似为2.4×100×2=480μs。当输入为高速变化的信号时,只需减少脉冲总数即可。如脉冲总数为100,输入电压为1.0~3.3V,则分辨率为23mV。为提高分辨率,可先对输入信号进行粗测,然后调整高低脉冲的占空比,以使对应电压略超出测量结果的上下限值,这样即可获得更高的分辨率。
3 软件设计
图2所示是用COP820CJ设计的A/D转换器的工作软件流程图。其中,控制寄存器2(CNTRL2[CC])的第三位是比较器允许位,第四位为比较器输出。X指令为交换两寄存器中的数据。“SBIT(RBIT)i,n”指令为将n寄存器的第i位置1(0)。“IFBITi,n”指令在n寄存器的第i位为1时执行一条指令,否则跳过。“DRSZ n”指令的作用是先将寄存器n的值减1,如结果非零,则执行下一条指令,否则跳过。
要保证脉冲周期为24个时钟,必须精确计算指令周期。其指令周期的时钟数分别为:
NOP:1个时钟;SBIT/RBIT/IFBIT(对B,X寄存器操作时):1个时钟;DRSZ/JP:3个时钟。
具体的汇编程序如下:
(B=LDATA)
SBIT 4,CNTRL2 ;允许比较器工作
LD LCONF,#00
LD LDATA,#00 ;置L口为高阻输入
CONV:LD A,#02
LD 0F1,#02 ;记录次数
LD TOTAL,#064
LD TON,#064 ;计数器赋初值
SBIT3,[B]
SBIT 3,LCONF ;令L3输出1
LOOP:IFBIT3,CNTRL2
JP HIGH ;如比较器输出为1,则跳转
NOP
NOP ;延时,使高低脉冲开始时间点一致
SBIT 3,[B];低脉冲部分。L3置高5个时钟
DRSZ TON ;TON减1
NOP
RBIT 3,[B] ;L3置低19个时钟
NOP
NOP
JP COUNT
HIGH:RBIT3,[B];高脉冲部分。L3置低8个时钟
NOP
NOP
NOP
NOP
NOP
NOP
SBIT 3,[B] ;置高16个时钟
NOP
NOP
COUNT:DRSZ TOTAL ;TOTAL计数器减1
JP LOOP
RBIT 3,LCONF
RBIT 3,[B];置L3为高阻输入,以防差错
IFEQ A,0F1
JP RELOAD ;第一次计数器到零则到RELOAD
JP DEC ;否则到DEC
RELOAD:LD TON,#064
LD TOTAL,#064;重新装入计数器
DEC:SBIT 3,[B]
SBIT 3,LCONF 令L3输出1
DRSZ 0F1
JMP LOOP ;进行第二次计数
LD A,TON
X A,00 ;保存TON到RAM00H
END