În acest proiect, vom demonstra realizarea unui ceas RTC folosind microcontrolerul 8051. Dacă doriți să faceți acest proiect cu Arduino, verificați acest ceas digital folosind Arduino. Componenta principală a acestui proiect este DS1307, care este un IC cu ceas digital în timp real. Vă informăm în detaliu despre acest IC.
RTC DS1307:
Ceasul în timp real serial (RTC) DS1307 este un ceas / calendar zecimal complet complet codat binar (BCD) de putere redusă, plus 56 de octeți de NV SRAM. Acest cip funcționează pe protocolul I²C. Ceasul / calendarul oferă informații despre secunde, minute, ore, zi, dată, lună și an. Data la sfârșitul lunii este ajustată automat pentru lunile cu mai puțin de 31 de zile, inclusiv corecțiile pentru anul bisect. Ceasul funcționează fie în format de 24 de ore, fie de 12 ore, cu indicatorul AM / PM. DS1307 are un circuit încorporat de detectare a puterii care detectează defecțiunile de alimentare și trece automat la sursa de rezervă. Operația de cronometrare continuă în timp ce piesa funcționează din sursa de rezervă. Cipul DS1307 poate rula continuu până la 10 ani.
Ceasul în timp real bazat pe 8051 este un ceas digital pentru afișarea în timp real folosind un RTC DS1307, care funcționează pe protocolul I2C. Ceasul în timp real înseamnă că funcționează chiar și după întreruperea alimentării. Când alimentarea este reconectată, aceasta afișează timpul real, indiferent de timpul și durata în care a fost în starea oprită. În acest proiect am folosit un modul LCD de 16x2 pentru a afișa ora în formatul (oră, minut, secunde, dată, lună și an). Ceasurile în timp real sunt utilizate în mod obișnuit în computerele, casele, birourile și dispozitivele noastre electronice pentru a le menține actualizate în timp real.
Protocolul I2C este o metodă de conectare a două sau mai multe dispozitive folosind două fire la un singur sistem și, prin urmare, acest protocol este numit și protocol cu două fire. Poate fi folosit pentru a comunica 127 de dispozitive către un singur dispozitiv sau procesor. Majoritatea dispozitivelor I2C rulează pe o frecvență de 100Khz.
Pași pentru scrierea de date master către slave (modul de recepție slave)
- Trimite condiția START sclavului.
- Trimite adresa sclavului sclavului.
- Trimiteți bitul de scriere (0) către sclav.
- Bit ACK primit de la sclav
- Trimite cuvinte adresate sclavului.
- Bit ACK primit de la sclav
- Trimite date sclavului.
- Bit ACK primit de la sclav.
- Și ultima trimite starea STOP către sclav.
Pași pentru citirea datelor de la slave la master (modul de transmisie slave)
- Trimite condiția START sclavului.
- Trimite adresa sclavului sclavului.
- Trimiteți bitul de citire (1) către sclav.
- Bit ACK primit de la sclav
- Date primite de la sclav
- Bit ACK primit de la sclav.
- Trimite starea STOP sclavului.
Diagrama și descrierea circuitului
În circuit am folosit cele mai multe componente DS1307, AT89S52 și LCD. Aici AT89S52 este utilizat pentru citirea timpului de pe DS1307 și afișarea acestuia pe ecranul LCD de 16x2. DS1307 trimite ora / data folosind 2 linii către microcontroler.
Conexiunile de circuit sunt ușor de înțeles și sunt prezentate în diagrama de mai sus. Pinul cip DS1307 SDA și SCL sunt conectate la pinii P2.1 și P2.0 ai microcontrolerului 89S52 cu rezistență pull up care deține valoarea implicită HIGH la liniile de date și ceas. Și un oscilator cu cristale de 32,768KHz este conectat cu DS1307chip pentru a genera întârziere exactă de 1 secundă. Și o baterie de 3 volți este, de asemenea, conectat la pinul 3 - lea (BAT) din DS1307 care păstrează timp de funcționare, după eșecul de energie electrică. 16x2 LCD este conectat cu 8051 în modul pe 4 biți. Pinii de control RS, RW și En sunt conectați direct la pinul 89S52 P1.0, GND și P1.1. Și pinul de date D0-D7 este conectat la P1.4-P1.7 din 89S52.
Trei butoane și anume SET, INC / CHANGE și Next sunt utilizate pentru setarea orei ceasului la pinul P2.4, P2.3 și P2.2 din 89S52 (activ activ). Când apăsăm SET, modul de setare a timpului se activează și acum trebuie să setăm ora folosind butonul INC / CHANGE, iar butonul Next este utilizat pentru trecerea la cifră. După setare, ceasul rulează continuu.
Descrierea programului
În cod, am inclus 8051 bibliotecă familială și o bibliotecă standard de ieșire de intrare. Și am definit pinii pe care i-am folosit și am luat o variabilă pentru calcule.
#include
Iar funcția dată este utilizată pentru conducerea ecranului LCD.
void daten () {rs = 1; ro = 1; întârziere (1); ro = 0; } void lcddata (unsigned char ch) {lcdport = ch & 0xf0; daten (); lcdport = (ch << 4) & 0xf0; daten (); } void cmden (void) {rs = 0; ro = 1; întârziere (1); ro = 0; } void lcdcmd (caractere nesemnate)
Această funcție este utilizată pentru inițializarea RTC și pentru citirea orei și datei din formularul RTC IC.
I2CStart (); I2CSend (0xD0); I2CSend (0x00); I2CStart (); I2CSend (0xD1); sec = BCDToDecimal (I2CRead (1)); min = BCDToDecimal (I2CRead (1)); ora = BCDToDecimal (I2CRead (1)); day1 = BCDToDecimal (I2CRead (1)); data = BCDToDecimal (I2CRead (1)); mon = BCDToDecimal (I2CRead (1)); year = BCDToDecimal (I2CRead (1)); I2CStop (); arată timpul(); // afișează întârziere oră / dată / zi (1);
Aceste funcții sunt utilizate pentru conversia zecimalului în BCD și BCD în Zecimală.
int BCDToDecimal (char bcdByte) {char a, b, dec; a = (((bcdByte & 0xF0) >> 4) * 10); b = (bcdByte & 0x0F); dec = a + b; returnare dec; } char DecimalToBCD (int decimalByte) {char a, b, bcd; a = ((decimalByte / 10) << 4); b = (decimalByte% 10); bcd = ab; returnează bcd; }
Funcțiile de mai jos sunt utilizate pentru comunicarea I2C.
void I2CStart () {SDA = 1; SCL = 1, SDA = 0, SCL = 0;} // funcția „start” pentru comunicarea cu ds1307 RTC void I2CStop () {SDA = 0, SCL = 1, SDA = 1; } // Funcția „stop” pentru a comunica cu ds1307 RTC nesemnat I2CSend (nesemnat Char Data) // trimite date către ds1307 {char i; char ack_bit; pentru (i = 0; i <8; i ++) {if (Data & 0x80) SDA = 1; altfel SDA = 0; SCL = 1; Date << = 1; SCL = 0; } SDA = 1, SCL = 1; ack_bit = SDA; SCL = 0; returnează ack_bit; } unsigned char I2CRead (char ack) // primesc date de la ds1307 {unsigned char i, Data = 0; SDA = 1; pentru (i = 0; i <8; i ++) {Date << = 1; faceți {SCL = 1;} în timp ce (SCL == 0); if (SDA) Data- = 1; SCL = 0; } if (ack) SDA = 0; altfel SDA = 1; SCL = 1; SCL = 0; SDA = 1; returnează date; }
Funcția set_time este utilizată pentru a seta ora în ceas și funcția show_time de mai jos este utilizată pentru a afișa ora pe ecranul LCD.
void show_time () // funcție pentru afișarea orei / datei / zilei pe LCD {char var; lcdcmd (0x80); lcdprint ("Data:"); sprintf (var, "% d", data); lcdprint (var); sprintf (var, "/% d", lun); lcdprint (var); sprintf (var, "/% d", an + 2000); lcdprint (var); lcdprint (""); lcdcmd (0xc0); lcdprint ("Ora:"); sprintf (var, "% d", oră); lcdprint (var); sprintf (var, ":% d", min); lcdprint (var); sprintf (var, ":% d", sec); lcdprint (var); lcdprint (""); // zi (ziua1); lcdprint (""); }