版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第9章单片机综合应用仿真9.1模/数转换器和数/模转换器的仿真与应用9.2存储器I2C24C01C的仿真与应用9.3时钟芯片DS1302的仿真与应用9.4温度传感器DS18B20的仿真与应用9.5电动机的仿真与应用9.6交通管理系统的仿真与应用9.7多路抢答器的仿真与应用本章小结
本章系统叙述在Proteus环境中,51单片机综合应用系统的设计与仿真分析方法。
本章共七节,分别介绍了模/数转换器和数/模转换器的仿真与应用、存储器I2C24C01C的仿真与应用、时钟芯片DS1302的仿真与应用、温度传感器DS18B20的仿真与应用、电动机的仿真与应用、交通管理系统的仿真与应用、多路抢答器的仿真与应用。
通过本章的学习,读者可以以Proteus为平台,方便地设计和仿真51单片机综合应用系统。内容提要
9.1.1用ADC0808实现数字电压表
1.ADC0808的主要性能指标
ADC0808是逐次比较式A/D转换芯片,芯片的主要性能如下:
分辨率为8位。
最大量化误差为
±1LSB(LeastSignificantBit),LSB是数字量的最小有效值表示的模拟量。9.1模/数转换器和数/模转换器的仿真与应用
单一
+5V电源供电,输入的模拟电压范围为0~+5V。
具有锁存控制的8路模拟选通开关。
图9-1ADC0808的逻辑符号
锁存三态输出,输出电平与TTL兼容,芯片输出可直接连至单片机的数据总线。
转换速度取决于芯片的时钟频率。时钟频率范围为(10~1280)kHz,典型的时钟频率为640kHz,此时A/D的转换时间为(90~116)μs,典型值为100μs。
2.ADC0808的逻辑符号与引脚功能
ADC0808的逻辑符号如图9-1所示。
ADC0808的引脚功能如下:
IN0~IN7:8路模拟信号输入端。
ADDA、ADDB、ADDC:3位地址码,选择8路模拟输入信号。
OUT1~OUT8:数字量输出端。OUT1为最高位。
CLOCK:外部时钟输入端。
OE(OUTPUTENABLE):数据输出允许信号,输入,高电平有效。通常与单片机的端相接。转换结束后,结果存放在输出锁存器中。当单片机置该引脚为高电平后,选通芯片内部的三态缓冲器将数据取出。
ALE:地址锁存允许信号,高电平有效。
START:A/D转换启动信号。输入一个正脉冲(至少100ns宽)使其启动(脉冲上升沿使ADC0808复位,下降沿启动A/D转换)。
EOC:A/D转换结束信号,输出。当A/D转换结束时,此端输出一个高电平(转换期间一直为低电平)。此端可作为查询或中断信号。
VREF(+)、VREF(-):正负基准电压输入端。当输入模拟信号电压较低时,基准电压可低于5V。
3.数字电压表电路设计
数字电压表仿真电路如图9-2所示。数码管为4位共阴数码管(7SEG-MPX4-CC),作为拉电流负载,P0口要接上拉电阻;ADC0808的输出接P2口;用P3口作ADC0808的控制信号。
图9-2数字电压表仿真电路
4.控制程序
汇编源程序:
SEG_0EQU 40H ;显示数字存放单元
SEG_1EQU 41H
SEG_2EQU 42H
SEG_3EQU 43H
DATEQU 44H ;ADC转换结果存放单元
CLKBIT P3.4 ;ADC0808控制引脚定义
STBIT P3.5
EOCBIT P3.6
OUT_ENBIT P3.7
ORG0000H ;复位地址
LJMPMAIN
ORG000BH ;定时器T0入口地址
LJMPT0_INT
ORG0100H ;程序存放地址
MAIN:
MOV SEG_0,#00H ;显示数字清零
MOV SEG_1,#00H
MOV SEG_2,#00H
MOV SEG_3,#00H
MOV TMOD,#02H ;定时器T0方式2,8位可重装初值
MOV TH0,#200 ;定时器T0赋初值
MOV TL0,#200
MOV IE,#82H ;T0允许,开放总中断
SETB TR0 ;启动T0
LOOP:
CLR ST ;发A/D转换启动信号
SETB ST
CLR ST
JNB EOC,$ ;等待A/D转换结束
SETB OUT_EN ;打开ADC0808的三态门
MOV DAT,P2 ;读取A/D转换结果
CLR OUT_EN
MOV A,DAT ;A/D转换结果转化为4位BCD码
MOV R7,A
MOV SEG_3,#00H
MOV SEG_2,#00H
MOV A,#00H
LOP1:
ADD A,#20H ;1LSB对应20mV电压
DA A
JNC LOP2
MOV R4,A
INC SEG_2
MOV A,SEG_2
CJNE A,#0AH,LOP4
MOV SEG_2,#00H
INC SEG_3
LOP4:
MOV A,R4
LOP2:
DJNZ R7,LOP1
CALL BTOD1
CALL DISP
SJMP LOOP
BTOD1:MOV R6,A
ANL A,#0F0H
MOV R5,#4
LOP3:
RR A
DJNZ R5,LOP3
MOV SEG_1,A
MOV A,R6
ANL A,#0FH
MOV SEG_0,A
RET
T0_INT:CPLCLK ;产生ADC0808的CLOCK信号
RETI
DISP:
MOV A,SEG_0 ;7段数码管显示程序
MOV DPTR,#TABLE1
MOVC A,@A+DPTR
CLR P3.3
MOV P0,A
CALL DELAY
SETB P3.3
MOV A,SEG_1
MOV DPTR,#TABLE1
MOVC A,@A+DPTR
CLR P3.2
MOV P0,A
CALL DELAY
SETB P3.2
MOV A,SEG_2
MOV DPTR,#TABLE1
MOVC A,@A+DPTR
CLR P3.1
MOV P0,A
CALL DELAY
SETB P3.1
MOV A,SEG_3
MOV DPTR,#TABLE2 ;最高位带小数点显示
MOVC A,@A+DPTR
CLR P3.0
MOV P0,A
CALL DELAY
SETB P3.0
RET
DELAY:MOV R6,#10 ;延时程序
DELAY1:MOV R7,#250
DJNZ R7,$
DJNZ R6,DELAY1
RET
TABLE1:DB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;7段码表(共阴)
TABLE2:DB0BFH,86H,0DBH,0CFH,0E6H,0EDH,0FDH,87H,0FFH,0EFH
;7段码表(带小数点、共阴)
END
C语言源程序:
#include<reg51.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitBIT_0=P3^0; //控制信号端口定义
sbitBIT_1=P3^1;
sbitBIT_2=P3^2;
sbitBIT_3=P3^3;
sbitCLK=P3^4;
sbitST=P3^5;
sbitEOC=P3^6;
sbitOUT_EN=P3^7;
ucharcodedis_char[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
ucharcodedis_add_dot[]={0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF};
ucharAD_RESULT; //A/D转换结果
uint
DIS_DATA; //A/D转换结果对应的电压值
voidDelay(uintm) //延时程序
{
uchari;
while(--m)for(i=0;i<120;i++);
}
voidDisplay() //显示程序
{
BIT_0=0;
P0=dis_add_dot[DIS_DATA/1000]; //显示千位
Delay(10);
BIT_0=1;
BIT_1=0;
P0=dis_char[(DIS_DATA%1000)/100]; //显示百位
Delay(10);
BIT_1=1;
BIT_2=0;
P0=dis_char[(DIS_DATA%100)/10]; //显示十位
Delay(10);
BIT_2=1;
BIT_3=0;
P0=dis_char[DIS_DATA%10]; //显示个位
Delay(10);
BIT_3=1;
}
voidmain()
{
TMOD=0x02; //程序解释同汇编程序
TH0=200;
TL0=200;
IE=0x82;
TR0=1;
while(1)
{
ST=0; //启动A/D转换
ST=1;
ST=0;
while(EOC==0); //等待A/D转换结束
OUT_EN=1; //打开ADC0808的三态门
AD_RESULT=P2; //读取A/D转换结果
OUT_EN=0; //关闭三态门,为下一次A/D转换作准备
DIS_DATA=0;
while(AD_RESULT!=0)
{
DIS_DATA=DIS_DATA+20; //1LSB对应20mV电压值
AD_RESULT--;
}
Display();
}
}
voidTIMER_T0()interrupt1 //定时器T0中断
{
CLK=~CLK; //产生CLK信号
}
5.仿真分析
在Proteus中加载单片机控制程序(HEX文件),单击仿真按钮,开始仿真。仿真结果如图9-2所示。用鼠标移动电位器的滑动端,数码管显示对应的数字电压值。用户可以在输入模拟电压的地方用直流电压表测量,并与数码管显示的电压比较。若存在误差,分析误差产生的原因,进而体会ADC的位数与转换精度之间的误差。
Proteus软件中提供的ADC0809的仿真模型不能用,ADC0809与ADC0808的工作原理一样。因此,ADC0809的仿真可用ADC0808的仿真替代。9.1.2用DAC0832实现信号发生器
1.DAC0832的主要性能指标
分辨率为8位。
单电源(+5~+15V)供电。
DAC0832主要由输入寄存器、DAC寄存器和D/A转换器构成。其数据输入可采用单缓冲、双缓冲或直接数字输入形式,其结构如图9-3所示。
图9-3DAC0832的结构图
只需在满量程下调整其线性度。
输出为电流,需接集成运放转换为电压。
低功耗,20mW。
2.DAC0832的逻辑符号与引脚功能
DAC0832的逻辑符号如图9-4所示。图9-4DAC0832的逻辑符号
RFB:反馈信号输入线,改变RFB端的外接电阻值可调整转换满量程精度。
VCC:电源输入端,VCC的范围为+5V~+15V。
VREF:基准电压输入端,VREF的范围为-10V~+10V。
AGND(引脚3):模拟信号地。
DGND(引脚10):数字信号地。
3.信号发生器电路设计
DAC0832构成的信号发生器仿真电路如图9-5所示。DAC0832接成单缓冲形式,由P2.5产生 信号控制。P2.7接开关K1,开关K1闭合时,输出正弦波形;开关K1打开时,输出锯齿波。
图9-5DAC0832构成的信号发生器仿真电路
4.控制程序
汇编源程序:
K1 BITP2.7 ;开关端口定义
WR1 BITP2.5 ;控制信号端口定义
ORG 0000H ;复位地址
LJMP START
ORG 0100H ;程序存放地址
START:JB K1,TRIAN ;K1打开,输出锯齿波;K1合上,输出正弦波
MOV R0,#63 ;正弦数据表,共64个数据
SINE:MOV A,R0 ;查表,输出正弦波
MOV DPTR,#TABLE
MOVC A,@A+DPTR
SETB WR1
MOV P0,A
CLR WR1 ;产生锁存信号
DJNZ R0,SINE
LJMP START
TRIAN:MOV R0,#0 ;输出三角波
LOP:
SETB WR1
MOV P0,R0
CLR WR1
MOV A,R0
ADD A,#4
MOV R0,A
JNZ LOP
LJMP START
TABLE:
DB80H,8CH,98H,0A5H,0B0H,0BCH,0C7H,0D1H ;正弦数据表
DB0DAH,0E2H,0EAH,0F0H,0F6H,0FAH,0FDH,0FFH
DB0FFH,0FFH,0FDH,0FAH,0F6H,0F0H,0EAH,0E3H
DB0DAH,0D1H,0C7H,0BCH,0B1H,0A5H,99H,8CH
DB80H,73H,67H,5BH,4FH,43H,39H,2EH
DB25H,1DH,15H,0FH,09H,05H,02H,00H
DB00H,00H,02H,05H,09H,0EH,15H,1CH
DB25H,2EH,38H,43H,4EH,5AH,66H,73H
END
C语言源程序:
#include<reg51.h>
#defineucharunsignedchar
ucharcodesine_table[]={0x80,0x8C,0x98,0xA5,0xB0,0xBC,0xC7,0xD1, //正弦数据表 0xDA,0xE2,0xEA,0xF0,0xF6,0xFA,0xFD,0xFF,
0xFF,0xFF,0xFD,0xFA,0xF6,0xF0,0xEA,0xE3,
0xDA,0xD1,0xC7,0xBC,0xB1,0xA5,0x99,0x8C,
0x80,0x73,0x67,0x5B,0x4F,0x43,0x39,0x2E,
0x25,0x1D,0x15,0xF,0x9,0x5,0x2,0x0,0x0,
0x0,0x2,0x5,0x9,0xE,0x15,0x1C,0x25,0x2E,
0x38,0x43,0x4E,0x5A,0x66,0x73};
sbitK1=P2^7; //端口定义
sbitWR1=P2^5;
voidDelay(ucharm) //延时程序
{
uchari;
while(--m)for(i=0;i<1;i++);
}
voidmain() //主程序
{
uchark;
while(1)
{
if(K1==0) //K1合上,输出正弦波
{
for(k=0;k<64;k++)
{
WR1=1;
P0=sine_table[k];
WR1=0;
Delay(1);
}
}
else //K1打开,输出锯齿波
{
for(k=0;k<255;k=k+4)
{
WR1=1;
P0=k;
WR1=0;
Delay(1);
}
}
}
}
5.仿真分析
在Proteus中加载单片机控制程序(HEX文件),单击仿真按钮,开始仿真。用鼠标单击开关K1右边的箭头,将开关合上,输出为正弦波,如图9-6所示。用鼠标单击开关K1右边的箭头,将开关打开,输出为锯齿波,如图9-7所示。图9-6图9-5所示电路输出的正弦波形(K1合上)图9-7图9-5所示电路输出的锯齿波形(K1打开)
9.2.1I2C总线简介
I2C总线是一种用于IC器件之间的两线制总线。它通过串行数据线SDA和串行时钟线SCL与连接至总线上的器件传送信息,实现了完善的全双工数据通信。器件地址采用硬件设置,通过软件寻址避免了器件的片选线寻址方法,从而使硬件系统的扩展简单、灵活。
I2C总线接口的电气结构如图9-8所示。9.2存储器I2C24C01C的仿真与应用
图9-8I2C总线接口的电气结构
I2C总线特性:
I2C总线由串行数据线SDA和串行时钟线SCL构成,可发送和接收数据。
在CPU与被控IC之间、IC与IC之间进行双向传送。标准方式下数据传输速率可达到100kb/s,高速方式下可达到400kb/s。
总线上连接设备的数量以总线上的电容不超过400pF为限。
每个连接到总线上的器件地址由芯片内部硬件电路和外部地址引脚同时决定,避免了片选线的连接方法,并建立简单的主从关系。主器件既可作为发送器,又可作为接收器。I2C总线是一个真正的多主总线,带有竞争监测和总线仲裁电路。多个主机可任意发送而不破坏总线的数据。
为了避免总线信号的混乱,要求连接到总线上设备的输出级必须为漏极开路或集电极开路的形式,以便完成线与的功能。SDA和SCL必须接上拉电阻。9.2.2I2C24C01C芯片简介
1.24C01C逻辑符号与引脚功能
24C01C为128
×
8位的串行E2PROM存储器,有地址选择和写保护功能。24C01C芯片的逻辑符号如图9-9所示。图9-924C01C芯片的逻辑符号
24C01C的引脚功能如下:
SCK(SCL):串行时钟输入端,用于数据传输同步。上升沿时将数据写入E2PROM,下降沿时将数据从E2PROM中读出。
SDA:串行数据I/O口,可双向传输串行数据。该引脚为漏极开路,因此要求在SDA传输线与VCC之间接上拉电阻。对于正常的数据传输,只允许在SCL为低电平期间改变SDA电平;而SDA电平在SCL高电平期间若发生改变,表明起始和停止条件产生。
TEST:写保护控制端。该引脚连接到VCC,写操作被禁止,但读操作不受影响。
A0、A1、A2:芯片地址输入引脚,用于多器件工作,最多可在一条总线上连接8个器件。
2.24C01C的总线特性
总线协议如下:第一,只有在总线空闲时才可启动数据传输。第二,数据传输期间,在时钟线为高电平时,无论如何,数据线都必须保持稳定。在时钟线为高电平期间改变数据将视为起始或停止条件。
I2C串行总线数据传输时序如图9-10所示。图9-10I2C串行总线数据传输时序
总线空闲(A):数据线SDA和时钟线SCL为高电平。
总线启动(B):SCL为高电平时,SDA由高变低表示起始条件产生。起始条件必须先于所有的命令产生。
停止总线(C):SCL为高电平时,SDA由低变高表示停止条件产生。所有操作都必须以停止条件结束。
数据有效(D):必须在SCL为低电平期间改变数据线。一个数据位对应一个时钟脉冲。
3.24C01C读写操作时序
24C01C读写操作时序分别如图9-11~图9-15所示。图9-1124C01C字节写操作时序图9-1224C01C页写操作时序图9-1324C01C当前地址读操作时序图9-1424C01C随即读操作时序图9-1524C01C连续读操作时序9.2.3I2C24C01C应用电路设计与仿真
1.电路设计
I2C24C01C应用仿真电路如图9-16所示。
设计要求:
先对24C01C执行写操作,将数据表中的16个数据写入24C01C中的00H~0FH存储单元中。
执行读操作,循环读出24C01C存储单元中的数据,存入AT89C51内部数据存储器40H~4FH单元中。
在读取每个单元数据的同时,将该数据在7段数码管显示。
图9-16I2C24C01C应用仿真电路
2.控制程序设计
汇编源程序:
SCL BITP1.0 ;总线端口定义
SDA BITP1.1
ORG 0000H ;复位地址
LJMP MAIN
ORG 0100H ;程序存放地址
MAIN:LCALL DELAY ;延时等待芯片复位
LCALL WRITE_24C01C ;调用写24C01C程序
M0: LCALL DELAY
LCALL DELAY
LCALL READ_24C01C ;循环读24C01C存储单元数据
SJMP M0
NOP4:NOP ;4μs延时程序
NOP
NOP
NOP
RET
START:
SETB SDA ;启动总线程序
SETB SCL
LCALL NOP4
CLR SDA
LCALL NOP4
CLR SCL
RET
STOP:
CLR DA ;停止总线程序
CLR SCL
LCALL NOP4
SETB SCL
LCALL NOP4
SETB SDA
RET
RACK:CLR SDA ;发送应答信号程序
NOP
NOP
SETB SCL
LCALL NOP4
CLR SCL
NOP
NOP
RET
NO_ACK:SETB SDA ;发送非应答信号程序
NOP
NOP
SETB SCL
LCALL NOP4
CLR SCL
NOP
NOP
RET
CACK:CLR SDA ;检测应答位程序
NOP
NOP
SETB SCL
NOP
NOP
NOP
CLR SCL
NOP
NOP
NOP
RET
WRITE_BYTE: ;写一个字节(8位)程序
MOV R7,#8
WRITE_0:RLC A ;写0
JC WRITE_1
CLR SDA
NOP
SETB SCL
LCALL NOP4
CLR SCL
SJMP RETURN
WRITE_1:SETB SDA ;写1
SETB SCL
LCALL NOP4
CLR SCL
RETURN:DJNZ R7,WRITE_0
RET
READ_BYTE: ;读一个字节(8位)程序
MOV R7,#8
LOP: SETB SDA
SETB SCL
LCALL NOP4
MOV C,SDA
NOP
NOP
RLC A
NOP
CLR SCL
DJNZ R7,LOP
RET
WRITE_24C01C: ;向24C01C写数据程序
LCALLSTART ;启动总线
MOV A,#0A0H ;发送器件地址字
LCALL WRITE_BYTE
LCALL CACK ;检测器件是否应答
MOV A,#00H ;发送器件片内地址
LCALL WRITE_BYTE
LCALL CACK
MOV R5,#16 ;发送字节数
MO R2,#00 ;查段码偏移量,将数据表中的数据存入24C01C指;定单元
LOP1:
MOV A,R2
MOV DPTR,#TABLE
MOVC A,@A+DPTR
LCALL WRITE_BYTE
LCALL CACK
INC R2
DJNZ R5,LOP1
LCAL STOP ;停止总线
RET
READ_24C01C: ;从24C01C中读数据程序
LCALL START ;启动总线
MOV A,#0A0H ;发送器件地址字
LCALL WRITE_BYTE
LCALL CACK
MOV A,#00H ;发送器件片内地址
LCALL WRITE_BYTE
LCALL CACK
LCALL START ;重新启动总线
MOV A,#0A1H ;发读命令
LCALL WRITE_BYTE
LCALL CACK
MOV R5,#16 ;读16个字节
MOV R0,#40H ;读出的数据存入AT89C51数据区(起始地址为40H)
LOP2:
LCALL READ_BYTE
MOV @R0,A
MOV DPTR,#TABLE1 ;查表,在P2口显示该数据
MOVC A,@A+DPTR
MOV P2,A
MOV R3,#100 ;延时一段时间
LOP3:LCALL DELAY
DJNZ R3,LOP3
DJNZ R5,LOP4 ;16个字节是否读完?未读完发应答信号,读完发
;非应答信号
LCALL NO_ACK
LCALL STOP
RET
LOP4:
LCALL RACK
INC R0
SJMP LOP2
DELAY:MOV R7,#10 ;延时程序
D1: MOV R6,#248
DJNZ R6,$
DJNZ R7,D1
RET
TABLE:
DB01H,08H,09H,02H,03H,05H,07H,00H,04H,05H,08H,03H,05H,06H,07H,08H
TABLE1:DB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;7段码表(共阴)
END
C语言源程序:
#include<reg51.h>
#include<intrins.h>
#defineucharunsignedchar
#defineuintunsignedint
#defineNOP4(){_nop_();_nop_();_nop_();_nop_();} //4μs延时程序
sbitSCL=P1^0; //总线端口定义
sbitSDA=P1^1;
ucharcodedis_code[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//7段码表(共阴)
voidDelay(uintm) //延时程序
{
uchari;
while(m--)for(i=0;i<120;i++);
}
voidStart() //启动总线程序
{
SDA=1;SCL=1;NOP4();SDA=0;NOP4();SCL=0;
}
voidStop() //停止总线程序
{
SDA=0;SCL=0;NOP4();SCL=1;NOP4();SDA=1;
}
voidNO_ACK() //发送非应答信号程序
{
SDA=1;SCL=1;NOP4();SCL=0;SDA=0;
}
voidCACK() //检测应答位程序
{
SDA=1;NOP4();SCL=1;NOP4();SCL=0;
}
voidWrite_One_Byte(ucharb) //写一个字节程序
{
uchari;
for(i=0;i<8;i++)
{
b<<=1;SDA=CY;_nop_();SCL=1;NOP4();SCL=0;
}
CACK();
}
voidWrite_I2C(ucharaddr,uchardat) //向24C01C指定地址写数据
{
Start();
Write_One_Byte(0xa0);Write_One_Byte(addr);Write_One_Byte(dat);
Stop();
Delay(10);
}
ucharRead_One_Byte() //读一个字节程序
{
uchari,b;
for(i=0;i<8;i++)
{
SCL=1;b<<=1;b|=SDA;SCL=0;
}
returnb;
}
ucharRead_Current() //从当前地址读数据
{
uchard;
Start();
Write_One_Byte(0xa1);d=Read_One_Byte();NO_ACK();
Stop();
returnd;
}
ucharRead_Random(ucharaddr) //从任意地址读数据
{
Start();
Write_One_Byte(0xa0);Write_One_Byte(addr);
Stop();
returnRead_Current();
}
voidmain()
{
uchari;
ucharsend_data[16]={1,8,9,2,3,5,7,0,4,5,8,3,5,6,7,8}; //发送给24C01C的数据表
ucharreceive_data[16]={0}; //存储从24C01C读出的数据
for(i=0;i<16;i++) //将16个数写入24C01C内部存储单元
{
Write_I2C(i,send_data[i]);
}
while(1) //循环读出24C01C中的数据
{
for(i=0;i<16;i++)
{
receive_data[i]=Read_Random(i); //数据存储
P2=dis_code[receive_data[i]]; //数据在P2口显示
Delay(300);
}
}
}
3.仿真分析
在Proteus中加载单片机控制程序(HEX文件),单击仿真按钮,开始仿真。
(1)仿真开始后,数码管依次显示24C01C内存单元数据,如图9-17所示。
图9-1724C01C应用电路的仿真结果
(2)观测24C01C内部数据:单击暂停按钮,右击24C01C图标,选择右击菜单命令InternalMemory,则24C01C存储器数据如图9-18所示。16个数据存入24C01C内部指定单元(00H~0FH)。图9-1824C01C存储器数据
(3)观测AT89C51内部数据:单击“暂停”按钮,右击AT89C51图标,选择右击菜单命令80C51CPU/InternalMemory,则AT89C51数据区如图9-19所示。16个数据存入AT89C51数据区指定单元(40H~4FH)。图9-19AT89C51数据区
(4)观测I2CDebug:右击I2CDebug图标,选择菜单命令Terminal,弹出I2CDebug界面,如图9-20所示。
图9-20I2CDebug界面
在图9-20中第1行为发送,单片机向I2C24C01C芯片写数据。从S开始,A0为24C01C的器件地址,从器件应答A,再发送24C01C的片内地址00H,从器件应答A,后面为发送的数据,在每个数据后面均应答A。
第2行为接收单片机读I2C24C01C芯片内部数据。前面几位同第1行,Sr为重新开始,发读命令A1,后面是读出的数据。
表9-1I2CDebug专用符号含义
9.3.1DS1302简介
DS1302是DALLAS公司推出的高性能低功耗涓流时钟芯片。广泛用于智能仪表、电话传真和家用电器等领域。
DS1302芯片内含有一个实时时钟/日历和31字节静态RAM,芯片的实时时钟/日历电路提供秒、分、时、日期、月、周、年的信息,每月的天数和闰年的天数可自动调整,时钟操作可通过AM/PM指示决定采用24或12小时格式。9.3时钟芯片DS1302的仿真与应用图9-21DS1302的逻辑符号
DS1302与单片机之间实现同步串行通信,只需要三根接口线(、I/O、SCLK)。时钟/RAM的读/写数据以一个字节或多达31个字节的字符组方式通信。DS1302工作时功耗很低,保持数据和时钟信息时功率小于1mW。
1.DS1302芯片的逻辑符号和引脚功能
DS1302芯片的逻辑符号如图9-21所示。
DS1302的引脚功能如下:
X1、X2:接32.768kHz晶振。
: 复位输入端。
I/O:数据输入/输出端。
SCLK:串行时钟输入端。
VCC1、VCC2电源供电管脚。DS1302由VCC1或VCC2中较大者供电。
2.DS1302的读写时序
DS1302是SPI总线驱动方式。它不仅要向寄存器写入控制字,还需要读取相应寄存器的数据。单片机与DS1302通信,需借助DS1302的控制字进行,DS1302的控制字(即地址及命令),如表9-2所示。
表9-2DS1302的控制字(即地址及命令)bit7:(控制字的最高位)必须是1,如果为0,则不能把数据写入到DS1302中。
bit6:如果为1,表示存取RAM数据;为0,表示存取日历时钟数据。
bit5~bit1(A4~A0):表示操作单元的地址。
bit0(控制字的最低位):如果为1,表示进行读操作;为0,表示进行写操作。控制字总是从最低位开始输出。在控制字指令输入后的下一个SCLK的上升沿时,数据被写入DS1302,数据写入从最低位(bit0)开始。同样,在紧跟八位控制字指令后的下一个SCLK脉冲的下降沿,从DS1302读出数据,读出的数据也是从最低位到最高位。单字节数据读写时序,如图9-22和9-23所示。图9-22单字节读操作时序图9-23单字节写操作时序
3.DS1302内部寄存器
DS1302内部寄存器如表9-3所示。
表9-3DS1302内部寄存器(1)时钟/日历:包含在7个读/写寄存器中。数据以BCD码形式存储在时钟/日历寄存器中。
(2)时钟标志寄存器:秒寄存器的第七位(CH)定义为时钟暂停标志。当CH=1时,时钟振荡器停止,DS1302进入低功耗备用模式,电源消耗小于100nA。当CH=0时,时钟将启动。
(3)
12-24小时模式:小时寄存器的bit7为12小时或24小时选择模式。当bit7=1,选择12小时模式;当bit7=0,选择24小时模式。在12小时模式下,bit5=1,表示PM;bit5=0,表示AM。
在24小时模式下,bit5为第二个小时位元(20~23小时)。当bit7位被改变时,小时数据要被重新初始化。
(4)写保护位:写保护寄存器的bit7(WP)为写保护位。当WP=1,该位阻止对任何寄存器的写操作;当WP=0,允许对寄存器的写操作。因初始时该电位未定义,因此在写入该器件之前,应将WP位置零。9.3.2DS1302应用电路设计
创建DS1302构成的电子钟仿真电路,如图9-24所示。图9-24DS1302构成的电子钟仿真电路9.3.3电子钟控制程序设计
1.编程思路
从DS1302读出的年、周、月、日、时、分、秒数据分别存放在数据区40H~46H中。年、周、月、日、时、分、秒数据经分离后存入显示缓冲区50H~5FH、60H~6CH相应的单元。显示缓冲区50H~5FH中的数据经查表后在LM1602第1行显示(DATE年-月-日周)。60H~6CH中的数据经查表后在LM1602第2行显示(TIME时:分:秒)。如图9-25所示。
图9-25DS1302构成的电子钟仿真结果数据表(ASCII码表)和字符的对应关系为:
30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,3AH,20H,2DH,41H,44H,45H,49H,4DH,54H
0,1,2,
3,4,
5,6,7,
8,9,:,空,-,A,D,E,I,M,T
2.汇编语言源程序
RST BITP3.5 ;DS1302端口定义
SCLK BITP3.6
IO BITP3.7
RS BITP2.0 ;LM1602控制信号定义
RW BITP2.1
E BITP2.2
YEAR EQU40H ;存放DS1302读出的数据
WEEK EQU41H
MONTH EQU42H
DAY EQU43H
HOUR EQU44H
MINUTE EQU45H
SECOND EQU46H
DS1302_ADDREQU70H
DS1302_DATAEQU71H
ORG 0000H ;复位地址
LJMP MAIN
ORG 0100H ;程序存放地址
MAIN:
CALL INIT_1602 ;1602初始化
MOV DS1302_ADDR,#8EH ;允许写DS1302
MOV DS1302_DATA,#00H
CALL WRITE_1302
MOV DS1302_ADDR,#90H ;DS1302充电
MOV DS1302_DATA,#0A6H
CALL WRITE_1302
MOV 50H,#14 ;显示缓冲区,在指定的位置显示“DATE”、“TIME”、
;“:”、“-”及“空格”
MOV 51H,#13
MOV 52H,#18
MOV 53H,#15
MOV 54H,#11
MOV 57H,#12
MOV 5AH,#12
MOV 5DH,#11
MOV 5EH,#11
MOV 60H,#18
MOV 61H,#16
MOV 62H,#17
MOV 63H,#15
MOV 64H,#11
MOV 67H,#10
MOV 6AH,#10
LOP0:MOV R7,#7 ;循环读出DS1302的数据(依次读出年、周、月、
;日、时、分、秒共7个)依次存入40H~46H
MOV R0,#YEAR
MOV DS1302_ADDR,#8DH
LOP1:CALL READ_1302
MOV @R0,DS1302_DATA
INC R0
MOV A,DS1302_ADDR
CLR C ;因其后指令为SUBB(带进位减法指令)
SUBB A,#2
MOV DS1302_ADDR,A
DJNZ R7,LOP1
MOV R6,YEAR ;将年、周、月、日、时、分、秒经分离后存入显
;示缓冲区指定位置
CALL SEPARATE
MOV 55H,R3
MOV 56H,R2
MOV 5FH,WEEK
DEC 5FH ;周日,周一~周六(0,1~6)读出DS1302的数据分别是1~7
MOV R6,MONTH
CALL SEPARATE
MOV 58H,R3
MOV 59H,R2
MOV R6,DAY
CALL SEPARATE
MOV 5BH,R3
MOV 5CH,R2
MOV R6,HOUR
CALL SEPARATE
MOV 65H,R3
MOV 66H,R2
MOV R6,MINUTE
CALL SEPARATE
MOV 68H,R3
MOV 69H,R2
MOV R6,SECOND
CALL SEPARATE
MOV 6BH,R3
MOV 6CH,R2
CALL DISP_1602 ;数据在LM1602显示
LJMP LOP0
WRITE_1302: ;向DS1302写数据
CLR SCLK
NOP
SETB RST
NOP
MOV A,DS1302_ADDR ;发送地址给DS1302
MOV R4,#8
W1: RRC A
NOP
NOP
CLR SCLK
NOP
NOP
NOP
MOV IO,C
NOP
NOP
NOP
SETB SCLK
NOP
NOP
DJNZ R4,W1
CLR SCLK
NOP
MOV A,DS1302_DATA ;发送数据给DS1302
MOV R4,#8
W2: RRC A
NOP
NOP
CLR SCLK
NOP
NOP
NOP
MOV IO,C
NOP
NOP
NOP
SETB SCLK
NOP
NOP
DJNZ R4,W2
CLR RST
RET
READ_1302: ;读DS1302数据
CLR SCLK
NOP
NOP
SETB RST
NOP
MOV A,DS1302_ADDR ;发送地址给DS1302
MOV R4,#8
RD1: RRC A
NOP
NOP
CLR SCLK
NOP
NOP
NOP
MOV IO,C
NOP
NOP
NOP
SETB SCLK
NOP
NOP
DJNZ R4,RD1
MOV R4,#8
RD2: CLR SCLK
NOP
NOP
NOP
MOV C,IO
NOP
NOP
NOP
RRC A
NOP
NOP
SETB SCLK
NOP
DJNZ R4,RD2
MOV DS1302_DATA,A ;读出DS1302数据
CLR RST
RET
SEPARATE: ;分离程序(将两位十六进制数分离)
MOV A,R6
MOV B,#10H
DIV AB
MOV R2,B
MOV R3,A
RET
INIT_1602: ;1602初始化程序
MOV P0,#01H ;清除屏幕
CALL ENABLE
MOV P0,#38H ;功能设定(8位、2行、5
×
7点阵)
CALL ENABLE
MOV P0,#0CH ;显示器ON,光标OFF、闪烁OFF
CALL ENABLE
MOV P0,#06H ;I/D=1(加1模式)
CALL ENABLE
RET
DISP_1602: ;1602显示程序
MOV R2,#16 ;第1行显示16个字符
MOV P0,#80H ;第1行起始地址
CALL ENABLE
MOV R1,#50H ;将显示缓冲区数据取出,查表显示
D1: MOV A,@R1
MOV DPTR,#TABLE
MOVC A,@A+DPTR
CALL WRITE_1602
INC R1
DJNZ R2,D1
MOV R2,#13 ;第2行显示13个字符
MOV P0,#0C0H ;第2行起始地址
CALL ENABLE
MOV R1,#60H ;将显示缓冲区数据取出,查表显示
D2: MOV A,@R1
MOV DPTR,#TABLE
MOVC A,@A+DPTR
CALL WRITE_1602
INC R1
DJNZ R2,D2
RET
WRITE_1602: ;数据写入1602程序
MOV P0,A
SETB RS
CLR RW
CLR E
CALL DELAY
SETB E
RET
ENABLE: ;1602使能程序
CLR RS
CLR RW
CLR E
CALL DELAY
SETB E
RET
DELAY:MOV R7,#05 ;延时程序
D4: MOV R6,#250
DJNZ R6,$
DJNZ R7,D4
RET
TABLE:DB30H,31H,32H,33H,34H,35H,36H,37H,38H,39H
DB3AH,20H,2DH,41H,44H,45H,49H,4DH,54H
;0~9、DATE、TIME、“:”、“-”、“空格”的ASCII码表
END
3.C语言源程序
#include<reg51.h>
#include<intrins.h>
#defineucharunsignedchar
#defineBUSY0x80
sbitRST=P3^5; //DS1302端口定义
sbitSCLK=P3^6;
sbitIO=P3^7;
sbitRS=P2^0; //LM1602控制信号定义
sbitRW=P2^1;
sbitE=P2^2;
ucharcodelook_ASCII[16]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
//0~9对应的ASCII码
uchardatadisplay1[16]= //显示缓冲区,在第1行显示“DATE年-月-日周”
{0x44,0x41,0x54,0x45,0x20,0x32,0x33,0x2D,0x35,0x36,0x2D,0x38,0x39};
uchardatadisplay2[16]= //显示缓冲区,在第2行显示“TIME时:分:秒”
{0x54,0x49,0x4D,0x45,0x20,0x32,0x30,0x3A,0x33,0x2E,0x3A,0x36,0x2E};
voidWRITE_1302(ucharDS1302_ADDR,ucharDS1302_DATA) //写DS1302程序
{
uchari;
SCLK=0;
_nop_();
RST=1;
_nop_();
for(i=0;i<8;i++) //发送地址给DS1302
{
SCLK=0;
_nop_();
_nop_();
_nop_();
if((DS1302_ADDR&0x01)==0x01)
IO=1;
else
IO=0;
_nop_();
_nop_();
_nop_();
SCLK=1;
_nop_();
_nop_();
_nop_();
_nop_();
for(i=0;i<8;i++) //发送数据给D
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 电子谱曲嵌入式课程设计
- 电子节拍器 课程设计
- 电子系课程设计
- 电子积木幼儿园课程设计
- 电子温度课程设计
- 电子摩天轮课程设计
- 管理人员学习合同
- 电子处方系统课程设计
- 电子商务平台课程设计
- 2024工程总承包项目合同管理规定
- HG20592-97化工部标准法兰规格
- 汉语阅读教程第一册第八课
- 麦克维尔单螺杆冷水机组PFS.C样本
- CCTV雨污水管道检测缺陷内容判断依据判断标准
- 仓管员考核试题仓管员理论知识与业务技能试卷(含答案)
- 土地权属争议案件调查处理文书格
- 樱花栽培管理浅谈
- 《探究串并联电路中电流的规律》说课稿
- 医院回避制度
- 新概念第二册第62课
- DB63∕T 954-2020 压力容器安全使用管理规范
评论
0/150
提交评论