|
Obsluha zdroje reálného času DS1302 mikroprocesorem ATMEGA8
Zdroj reálného času patří k nezbytným
periferiím mikroprocesorových obvodů při realizaci
rozmanitých zapojení, která zaznamenávají čas. Na
trhu je nepřeberné množství těchto obvodů, které se
liší provedením a cenou.
|
testovací zapojení s DS1302 |
Dle provedení lze RTC rozdělit
takto:
- vnitřní
nebo externí krystal
- vnitřní
nebo externí záložní baterie
- výstup
pro probouzení mikroprocesoru
Dle zapojení do obvodu:
- sériové
připojení pomocí 1wire, I2C nebo 3 wire sběrnice
- paralelní
připojení
Pro svoji konstrukci jsem zvolil
obvod reálného času od firmy Dallas. Tyto obvody sice
nemají vnitřní baterii, ani krystal, za to však mají
srozumitelné ovládání (i když se to na první pohled
z datasheetu nezdá) a využívají minimální počet
pinů pro komunikaci s mikroprocesorem. Základním
obvodem je DS1302, jehož rozbor komunikace bude popsán níže.
Obvod DS1302 komunikuje s mikroprocesorem po třech
vodičích. Signál RESET aktivuje komunikaci s DS1302,
signál SCLK potvrzuje platná data a nakonec signál
SDATA, který data přijímá, ale i odesílá. Komunikace
je dvoubytová. Nejprve se odešle příkazový byte a následně
se odešle byte s daty, nebo přijme byte s daty.
MSB bit příkazového bytu je vždy log.
1, jinak by nešlo do obvodu zapisovat.
Příkazový byte slouží jak pro čtení
tak zápis z DS1302. Obvod DS1302 je rovněž vybaven pamětí
EEPROM s 31 paměťovými místy, více informací v datasheetu. Data se posílají
od méně významného bitu po nejdůležitější(od LSB
po MSB), tedy bit 0, 1, 2...
Příkazový byte je v
prvních dvou sloupcích tabulky. Je vymyšlen tak, aby vždy
MSB bit příkazového bytu byl v logické 1. V dalších
sloupcích jsou popsána data, která se odesílají,
respektive přijímají po odeslání příkazového bytu.
Za zmínku stojí bit 7 (WP - Write Protect) z bytu 0x8E,
který je třeba před jakoukoliv komunikací vynulovat,
aby bylo možné do DS1302 zapisovat. Dále pak bit 7
(12/24) pro byty 0x85 a 0x84 nastavíme rovněž do 0,
neboť používáme 24 hodinový cyklus. Obvod umožňuje
i zadání dne v týdnu. To však v ukázkových rutinách
není aplikováno, aby nedocházelo ke kolizi mezi datem a
dnem v týdnu. Vždy je dobré zadat jen datum, den v týdnu
si už DS1302 určí sám.
Před samotným zahájením
přenosu je třeba aktivovat linku RESET. Dále pak odesíláme
command byte tak, že nastavíme linku SDA do potřebné
logické úrovně a následně aktivujeme puls na lince
SCLK. Náběžná hrana tohoto pulsu potvrzuje platná
data. Přenos se ukončí shozením signálu RESET do
logické úrovně 0.
Čtení z obvodu DS1302
je trochu složitější. Aktivace linky RESET a odeslání
příkazového bytu je stejné jako v případě zápisu
do obvodu DS1302. Ovšem první sestupná hrana z posledního
pulsu potvrzuje platná data na lince SDA. Tato data jsou
platná po celou dobu signálu SCLK v logické úrovni 0.
Po náběžné hraně signálu SCLK přejde SDA do stavu
vysoké impedance, čímž hodnota napětí
"plave". Při další sestupné hraně se
potvrzují nová platná data. Přenos se ukončí shozením
signálu RESET do logické úrovně 0. Reálné průběhy
z osciloskopu jsou na dalších obrázcích.
|
|
průběh zápisu dat do DS1302 |
průběh čtení dat z DS1302 |
Příklad rutin pro komunikaci s
DS1302:
1) init_DS1302 ... nastaví
komunikační linky do klidového stavu
2) imp_DS1302 ... vytváří hodinový
puls na výstup SCLK
3) read_DS1302 ... načte obsah z jedné
adresy DS1302 a vrátí data
4) write_DS1302 ... zapíše data na určitou
adresu do DS1302
void init_DS1302()
{
SCLK_M = 1; //nastavit jako vystup
RESET_M = 1;
SDA_M = 1;
SCLK = 0; // klidovy stav log 0
RESET = 0;
SDO = 0;
}
void imp_DS1302()
{
delay_us (5); SCLK = 1; delay_us (5); SCLK = 0; delay_us (5);
}
unsigned char read_DS1302 (unsigned char adresa)
{
unsigned char cc1, data;
init_DS1302();
data=0;
RESET = 1; // aktivovat linku, zahajit prenos
for (cc1=0; cc1<8; cc1++) // prenos command BYTE
{
if ((adresa&0x01) == 1) SDO = 1;
else SDO = 0;
adresa = adresa >> 1; // posunout o jeden bit vpravo
imp_DS1302();
}
SDA_M = 0; // nastavit linku SDA jako vstup
data = 0;
for (cc1=0; cc1<8;cc1++) // prenos data
{
SCLK = 0;
delay_us(2);
data = data >>1;
if (SDI == 1) data=data|0x80;
else data = data|0x00;
imp_DS1302();
}
SDO =0; // ukonceni komunikace
RESET =0;
return data;
}
write_DS1302 (unsigned char adresa, unsigned char data)
{
unsigned char cc1;
init_DS1302();
RESET = 1; // aktivovat linku, zahajit prenos
for (cc1=0; cc1<8; cc1++) // prenos command BYTE
{
if ((adresa&0x01) == 1) SDO = 1;
else SDO = 0;
adresa = adresa >> 1; // posunout o jeden bit vpravo
imp_DS1302();
}
for (cc1=0; cc1<8;cc1++) // prenos dat
{
if ((data&0x01) == 1) SDO = 1;
else SDO = 0;
data = data >> 1; // posunout o jeden bit vpravo
imp_DS1302();
}
SDO =0;
RESET =0;
}
stáhnout
zdrojový kód
|
|
|