Turbo51
Модули обслуживания часов реального времени
DS1306
unit DS1306;
{$O-}
{$xdata}
{$idata}
interface
var
year1305,month1305,day1305,date1305,hours1305,min1305,sec1305:byte;
procedure gets;
procedure sets;
procedure Setyear;
procedure SetMonth;
procedure wrm1305;
procedure rdm1305;
procedure setall;
procedure getall;
procedure ENWRITE;
procedure WRS1305;
procedure SaveBuffer;
procedure LoadBuffer;
implementation
uses declare,ports;
procedure wra13051;forward;
//===============================================
procedure WRA1305;assembler;
asm
setb l1305clk
setb l1305ce
clr l1305clk
lcall wra13051
end;
//===============================================
procedure wra13051;
begin
ar7:=acc;
for i:=1 to 8 do
begin
asm
mov a,r7
RLC A
mov r7,a
MOV L1305OUT,C
SETB L1305CLK
NOP
NOP
CLR L1305CLK
end;
end;
end;
//===============================================
procedure WRB1305;assembler;
asm
LCALL WRA1305
MOV A,B
LCALL WRA13051
SETB L1305CLK
CLR L1305CE
RET
end;
//===============================================
procedure RDB1305;
begin
WRA1305;
ar7:=0;
for i:=1 to 8 do
begin
asm
SETB L1305CLK
NOP
NOP
mov a,r7
MOV C,L1305IN
RLC A
mov r7,a
CLR L1305CLK
end;
end;
asm
setb l1305clk
clr l1305ce
mov a,r7
end;
end;
//===============================================
procedure WRS1305;assembler;
asm
MOV A,#0FH
LCALL RDB1305
ANL A,#01111111B
MOV B,#7
MOV A,#8FH
LCALL WRB1305
RET
end;
//===============================================
procedure ENWRITE;assembler;
asm
MOV A,#0FH
LCALL RDB1305
ANL A,#10111111B
MOV B,A
MOV A,#8FH
LCALL WRB1305
RET
end;
//===============================================
procedure WRM1305;assembler;
asm
clr c
ADDc A,#0A0H
LCALL WRB1305
RET
end;
//================================================
procedure RDM1305;assembler;
asm
clr c
ADDc A,#20H
LCALL RDB1305
RET
end;
//===============================================
procedure gets;assembler;
asm
mov a,r7
//mov ar7,a
anl ar7,#00001111b
swap a
anl a,#00001111b
mov b,#10
mul ab
add a,ar7
mov r7,a
ret
end;
//===============================================
procedure sets;assembler;
asm
{clr c
da a}
mov r6,a //сохранение А в регистре 6
mov b,#10
div ab
mov r5,a //в регистре 5 частное от деления, то есть количество десяток
mov b,#10
mul ab //умножаем частное на 10
mov r7,a //и сохраняем в регистре 7
clr c
mov a,r6
subb a,r7 //вычитаем из исходного количество целых десяток,
//умноженное на 10, и получаем количество единиц
mov r6,a
mov a,r5
swap a
add a,r6
ret
end;
//===============================================
procedure SETYEAR;assembler;
asm
MOV a,YEAR1305
LCALL SETS
mov b,a
MOV A,#86H
LCALL WRB1305
RET
end;
//===============================================
procedure SETMONTH;assembler;
asm
MOV a,MONTH1305
LCALL SETS
mov b,a
MOV A,#85H
LCALL WRB1305
RET
end;
//===============================================
procedure SETDATE;assembler;
asm
MOV a,DATE1305
LCALL SETS
mov b,a
MOV A,#84H
LCALL WRB1305
RET
end;
//===============================================
procedure SETHOURS;assembler;
asm
MOV a,HOURS1305
LCALL SETS
mov b,a
MOV A,#82H
LCALL WRB1305
RET
end;
//===============================================
procedure SETMIN;assembler;
asm
MOV A,MIN1305
LCALL SETS
mov b,a
MOV A,#81H
LCALL WRB1305
RET
end;
//===============================================
procedure SETSEC;assembler;
asm
MOV A,SEC1305
LCALL SETS
mov b,a
MOV A,#80H
LCALL WRB1305
RET
end;
//===============================================
procedure SETDAY;assembler;
asm
MOV A,DAY1305
LCALL SETS
mov b,a
MOV A,#83H
LCALL WRB1305
RET
end;
//===============================================
procedure GETYEAR;assembler;
asm
MOV A,#06H
LCALL RDB1305
LCALL GETS
MOV YEAR1305,r7
RET
end;
//===============================================
procedure GETMONTH;assembler;
asm
MOV A,#05H
LCALL RDB1305
LCALL GETS
MOV MONTH1305,r7
RET
end;
//===============================================
procedure GETDATE;assembler;
asm
MOV A,#04H
LCALL RDB1305
LCALL GETS
MOV DATE1305,r7
RET
end;
//===============================================
procedure GETHOURS;assembler;
asm
MOV A,#02H
LCALL RDB1305
LCALL GETS
MOV HOURS1305,r7
RET
end;
//===============================================
procedure GETMIN;assembler;
asm
MOV A,#01H
LCALL RDB1305
LCALL GETS
MOV MIN1305,r7
RET
end;
//===============================================
procedure GETSEC;assembler;
asm
MOV A,#00H
LCALL RDB1305
LCALL GETS
MOV SEC1305,r7
RET
end;
//===============================================
procedure GETDAY;assembler;
asm
MOV A,#03H
LCALL RDB1305
LCALL GETS
MOV DAY1305,r7
RET
end;
//===============================================
procedure GETALL;assembler;
asm
LCALL GETSEC
LCALL GETMIN
LCALL GETHOURS
LCALL GETDAY
LCALL GETDATE
LCALL GETMONTH
LCALL GETYEAR
RET
end;
//===============================================
procedure SETALL;assembler;
asm
LCALL SETSEC
LCALL SETMIN
LCALL SETHOURS
LCALL SETDAY
LCALL SETDATE
LCALL SETMONTH
LCALL SETYEAR
RET
end;
//======================================================
//процедура сохранения буфера в памяти 1305
procedure SaveBuffer;
begin
for j:=0 to 63 do
begin
b:=sn[j];
acc:=j;
wrm1305;
end;
end;
//===============================================
//процедура загрузки из памяти 1305 сохраненного содержимого буфера
procedure LoadBuffer;
begin
for j:=0 to 63 do
begin
acc:=j;
rdm1305;
b:=acc;
sn[j]:=b;
end;
end;
//===============================================
end.
DS1307
unit ds1307;
{$Idata}
{$O-}
{$xdata}
interface
const adr1307=%11010000;
reg1307=%10010011;
var
year1305,
month1305,
day1305,
date1305,
hours1305,
min1305,
sec1305:byte;
ac1307:byte; //субадрес ОЗУ DS1307
data1307:byte; //данные DS1307
procedure WriteControl1307;
procedure ReadControl1307;
procedure StartWrite1307(mem:boolean);
procedure StartRead1307;
procedure WriteByte1307;
procedure ReadByte1307;
procedure WriteMem1307;
procedure ReadMem1307;
procedure gets;
procedure sets;
procedure Setyear;
procedure SetMonth;
procedure GetAll;
procedure SetAll;
procedure getSec;
procedure SetSec;
procedure StartGen1307;
procedure Init1307;
implementation
uses declare,i2c;
//===============================================
procedure StartGen1307;
begin
GetSec;
//sec1305:=sec1305 and %01111111;
acc:=sec1305;
if acc.7 then
begin
sec1305:=0;
SetSec;
end;
end;
//===============================================
//процедура исходной инициализации DS1307
procedure Init1307;
begin
//I2CINIT;
StartGen1307; //запуск (или подтверждение) генератора
WriteControl1307; //установка состояния управляющего регистра
end;
//===============================================
//процедура записи контрольного регистра
procedure WriteControl1307;
begin
ac1307:=7;
StartWrite1307(false);
acc:=reg1307;
i2cwb;
i2cans;
i2cstop;
end;
//===============================================
//процедура чтения контрольного регистра
procedure ReadControl1307;
begin
ac1307:=7;
StartWrite1307(false);
i2cstop;
StartRead1307;
i2crb;
data1307:=acc;
i2cnoansm;
i2cstop;
end;
//===============================================
//процедура старта записи - передача адреса 1307 и
//адреса ячейки памяти или часовые регистры.
//если установлен флаг MEM, производится запись
//в память данных, то есть к адресу автоматически
//прибавляется 8 - начало пространства ОЗУ пользователя.
procedure StartWrite1307(mem:boolean);
begin
acc:=adr1307;
cy:=false;
i2cadr;
if mem then acc:=ac1307+8
else
acc:=ac1307;
i2cwb;
i2cans;
end;
//===============================================
//процедура старта чтения - передача адреса 1307
//и получение ответа
procedure StartRead1307;
begin
cy:=true;
acc:=adr1307;
i2cadr;
end;
//===============================================
//процедура записи байта в 1307 через адрес ас1307
procedure WriteByte1307;
begin
startwrite1307(false); //запрос устройства и передача адреса ас1307
acc:=data1307; //байт
i2cwb; //запись байта
i2cans; //ожидание ответа
i2cstop; //прекращение обмена
end;
//===============================================
//процедура чтения байта из 1307 через адрес ас1307
procedure ReadByte1307;
begin
StartWrite1307(false); //запрос устройства и передача адреса ас1307
i2cstop; //прекращение обмена
StartRead1307; //запуск чтения
i2crb; //чтение байта
data1307:=acc; //байт в data1307
i2cnoansm; //отрицательный ответ мастера
i2cstop; //прекращение обмена
end;
//===============================================
//процедура преобразования двоично-десятичного кода
//в двоичный
procedure gets;assembler;
asm
mov ar7,a
anl ar7,#00001111b
swap a
anl a,#00001111b
mov b,#10
mul ab
add a,ar7
end;
//===============================================
//процедура двоично-десятичного преобразования на 4 разряда.
//входные данные R2:R3, выходные ar23:ar22:a21:ar20.
procedure ddc4;
label
ddc40,ddc41,ddc42,ddc43,ddc44,ddc45,ddc46;
begin
asm
MOV R4,#16
CLR A
MOV ar20,A
MOV ar21,A
MOV ar22,A
MOV ar23,A
DDC40: MOV R0,#ar20
MOV R5,#4
DDC41: MOV A,@R0
XRL A,#5
JZ DDC45
MOV A,@R0
SUBB A,#5
JC DDC43
DDC45: MOV A,@R0
ADD A,#3
MOV @R0,A
DDC43: INC R0
DJNZ R5,DDC41
DDC42: CLR C
MOV A,R3
RLC A
MOV R3,A
MOV A,R2
RLC A
MOV R2,A
MOV F0,C
MOV R0,#ar20
MOV R5,#4
DDC46: MOV C,F0
MOV A,@R0
RLC A
MOV C,ACC.4
MOV F0,C
ANL A,#0FH
MOV @R0,A
INC R0
DJNZ R5,DDC46
DJNZ R4,DDC40
end;
end;
//*************************************************
//процедура двоично-десятичного преобразования
procedure sets;
begin
asm
mov r2,#0
mov r3,a
end;
ddc4;
valb:=ar21 shl 4;
valb:=valb+ar20;
acc:=valb;
end;
//===============================================
//процедура чтения всех временных параметров
procedure GetAll;
begin
ac1307:=0;
startwrite1307(false);
i2cstop;
startread1307;
i2crb;
gets;
sec1305:=acc;
i2cansm;
i2crb;
gets;
min1305:=acc;
i2cansm;
i2crb;
gets;
hours1305:=acc;
i2cansm;
i2crb;
day1305:=acc;
i2cansm;
i2crb;
gets;
date1305:=acc;
i2cansm;
i2crb;
gets;
month1305:=acc;
i2cansm;
i2crb;
gets;
year1305:=acc;
i2cnoansm;
i2cstop;
end;
//===============================================
//процедура установки (записи) всех временных параметров
procedure SetAll;
begin
ac1307:=0;
startwrite1307(false);
acc:=sec1305;
sets;
i2cwb;
i2cans;
acc:=min1305;
sets;
i2cwb;
i2cans;
acc:=hours1305;
sets;
i2cwb;
i2cans;
acc:=day1305;
i2cwb;
i2cans;
acc:=date1305;
sets;
i2cwb;
i2cans;
acc:=month1305;
sets;
i2cwb;
i2cans;
acc:=year1305;
sets;
i2cwb;
i2cans;
i2cstop;
end;
//===============================================
procedure WriteMem1307;
begin
startwrite1307(true); //запрос устройства и передача адреса ас1307
acc:=data1307; //байт
i2cwb; //запись байта
i2cans; //ожидание ответа
i2cstop;
end;
//===============================================
procedure ReadMem1307;
begin
startwrite1307(true);
i2cstop;
startread1307;
i2crb;
i2cnoansm;
i2cstop;
data1307:=acc;
end;
//===============================================
procedure SETYEAR;
begin
ac1307:=6;
acc:=year1305;
sets;
data1307:=acc;
writebyte1307;
end;
//===============================================
procedure SETMONTH;
begin
ac1307:=5;
acc:=month1305;
sets;
data1307:=acc;
writebyte1307;
end;
//===============================================
procedure SETDATE;
begin
ac1307:=4;
acc:=date1305;
sets;
data1307:=acc;
writebyte1307;
end;
//===============================================
procedure SETDAY;
begin
ac1307:=3;
data1307:=day1305;
writebyte1307;
end;
//===============================================
procedure SETHOURS;
begin
ac1307:=2;
acc:=hours1305;
sets;
data1307:=acc;
writebyte1307;
end;
//===============================================
procedure SETMIN;
begin
ac1307:=1;
acc:=min1305;
sets;
data1307:=acc;
writebyte1307;
end;
//===============================================
procedure SETSEC;
begin
ac1307:=0;
acc:=sec1305;
sets;
data1307:=acc;
writebyte1307;
end;
//===============================================
procedure GETYEAR;
begin
ac1307:=6;
readbyte1307;
acc:=data1307;
gets;
year1305:=acc;
end;
//===============================================
procedure GETMONTH;
begin
ac1307:=5;
readbyte1307;
acc:=data1307;
gets;
month1305:=acc;
end;
//===============================================
procedure GETDATE;
begin
ac1307:=4;
readbyte1307;
acc:=data1307;
gets;
date1305:=acc;
end;
//===============================================
procedure GETDAY;
begin
ac1307:=3;
readbyte1307;
day1305:=data1307;
end;
//===============================================
procedure GETHOURS;
begin
ac1307:=2;
readbyte1307;
acc:=data1307;
gets;
hours1305:=acc;
end;
//===============================================
procedure GETMIN;
begin
ac1307:=1;
readbyte1307;
acc:=data1307;
gets;
min1305:=acc;
end;
//===============================================
procedure GETSEC;
begin
ac1307:=0;
readbyte1307;
acc:=data1307;
gets;
sec1305:=acc;
end;
//===============================================
end.