- Materiale necesare:
- Cerințe prealabile:
- Diagrama circuitului:
- Programare pentru ceas cu alarmă:
- Simulare:
- Funcționarea ceasului cu alarmă digitală utilizând PIC16F877A:
Revoluția digitală începută în 1950 schimbă toate structurile electronice mecanice și analogice existente în computere digitale. Deoarece creșterea electronicii digitale a fost exponențială, astăzi este aproape imposibil ca o persoană să reziste la utilizarea oricărui echipament electronic. Începând de la ceasul deșteptător care te trezește și de la prăjitorul de pâine care îți servește micul dejun, totul este o contribuție din electronica digitală. Gândindu-ne la toate acestea, este cu adevărat interesant să ne programăm propriile lucruri care ar putea face sarcini simple, dar utile, cum ar fi ceasul cu alarmă pe care urmează să îl construim în acest proiect cu microcontrolerul PIC. Am construit anterior ceas cu alarmă cu alte microcontrolere:
- Ceas cu alarmă Raspberry Pi utilizând modulul RTC DS1307
- Ceas digital bazat pe Arduino cu alarmă
- Ceas cu alarmă utilizând microcontrolerul ATmega32
Acest ceas cu alarmă va avea un ecran LCD de 16x2, care va afișa ora curentă și ora setată. Vom folosi câteva butoane pentru a seta ora alarmei ori de câte ori este necesar. Ora curentă va fi ținută în evidență folosind modulul RTC DS3231 și vom folosi comunicația IIC pentru a obține aceste valori de la modulul RTC. Am aflat deja despre modulul RTC și cum să-l interfațăm cu PIC. Prin urmare, este recomandat să citiți acest tutorial, vom sări peste majoritatea informațiilor acoperite în acel tutorial.
Materiale necesare:
- Pană de pâine - 2Nos
- PIC16F877A
- Sursă de alimentare 5V - Modul de alimentare
- Cristal de 20 MHz
- Condensator 33pf - 2Nos
- Modulul DS3231 RTC
- Modul de afișaj LCD 16 * 2
- GHID 10K
- Rezistor de 10k și 1K
- Butoane - 5No
- Buzzer
- Conectarea firelor
Cerințe prealabile:
Acest proiect necesită să cunoașteți câteva elemente de bază despre microcontrolerul PIC și cum să îl programați. Pentru acest proiect vom folosi GPIO-uri, afișaj LCD și modul RTC. Deci, este mai bine să învățați cum să utilizați aceste module în prealabil. Următoarele linkuri vă vor ajuta să aflați la fel
- Scrierea primului dvs. program cu microcontroler PIC
- Interfață LCD cu PIC
- Comunicare I2C folosind PIC
- DS3231 interfață RTC cu PIC
Diagrama circuitului:
Schema de circuit pentru acest proiect cu ceas cu alarmă bazat pe PIC este prezentată mai jos, care a fost creată folosind software-ul proteus. De asemenea, va fi utilizat pentru simulare în continuare în acest proiect.
Cele cinci butoane vor acționa ca o intrare pentru setarea alarmei pentru timpul necesar. Deci, un capăt al tuturor butoanelor este conectat la masă și celelalte capete sunt conectate la pinul PORTB, rezistența de tracțiune internă va fi utilizată pe acești pin pentru a evita plutirea pinilor. Buzzerul va acționa ca o ieșire și ne va da un bip atunci când alarma este declanșată și este conectată la pinul PORT S. Ora curentă este întotdeauna menținută de modul DS3231 RTC de la care PIC primește datele prin magistrala I2C, astfel încât pinii SCL și SDA ai modulului RTC sunt conectați la pinul SCL și SDA al controlerului PIC. Un afișaj LCD este atașat la PORTD al PIC, care este utilizat pentru a afișa ora curentă și ora setată. Aflați mai multe despre utilizarea modulului DS3231 RTC cu PIC aici.
Circuitul complet poate fi construit pe o placă de calcul. Deoarece există câteva zeci de fire pentru a vă conecta, aveți răbdare și asigurați-vă că conexiunile sunt corecte. Configurarea hardware-ului meu arăta cam așa mai jos odată ce am terminat cu conexiunile
Am folosit un modul de panou și un adaptor de 12V pentru a alimenta modulul. Aceasta este sursa mea de tensiune de alimentare de + 5V. De asemenea, trebuie să folosesc două panouri pentru a menține circuitul curat. De asemenea, puteți lipi întregul circuit pe o placă de perfecționare dacă doriți să faceți un proiect mai robust.
Programare pentru ceas cu alarmă:
Programul complet PIC pentru acest proiect cu ceas cu alarmă poate fi găsit în partea de jos a acestei pagini. Acest proiect necesită, de asemenea, trei biblioteci pentru utilizarea LCD, I2C și RTC cu PIC. Codul complet cu fișiere antet poate fi descărcat de aici din fișierul ZIP și poate fi deschis folosind MPLABX după extragere. Mai jos, explic doar fișierul principal c sub formă de fragmente mici. Puteți reveni la tutorialele menționate mai sus dacă doriți să știți cum funcționează fișierele antet.
Înainte de a intra în programul principal, trebuie să definim pinii pe care i-am folosit cu un nume mai semnificativ. În acest fel va fi ușor să le utilizați în timpul programării. Pinii definiți în programul nostru sunt afișați mai jos
// Definiți pinii LCD #define RS RD2 // Resetați pinul LCD #define EN RD3 // Activați pinul LCD #define D4 RD4 // Bitul de date 0 al LCD #define D5 RD5 // Bitul de date 1 al LCD #define D6 RD6 // Bitul de date 2 al LCD #define D7 RD7 // Bitul de date 3 al LCD // Definirea butoanelor #define MB RB1 // Butonul din mijloc #define LB RB0 // Butonul din stânga #define RB RB2 // Butonul din dreapta # definește UB RB3 // Butonul superior #define BB RB4 // Butonul de jos // Define Buzz #define BUZZ RD1 // Buzzerul este conectat la RD1
În interiorul funcției principale începem prin declararea pinilor de intrare și ieșire. În proiectul nostru, PORTB este utilizat pentru butoane, care este un dispozitiv de intrare, așa că le setăm pinii ca intrări, iar PORTD este utilizat pentru LCD și buzzer, așa că le setăm pinii ca ieșire. De asemenea, un pin nu ar trebui să fie lăsat niciodată plutitor, adică pinii I / O trebuie conectați întotdeauna fie la masă, fie la tensiunea + 5V. În cazul nostru pentru butoane, pinii nu vor fi conectați la nimic atunci când butonul nu este apăsat, așa că folosim un rezistor de tragere intern care setează pinul la High atunci când nu este utilizat. Acest lucru se face folosind registrele de control așa cum se arată mai jos
TRISD = 0x00; // Faceți pinii portului D ca ieșire pentru interfața LCD TRISB = 0xFF; // Comutatoarele sunt declarate ca pini de intrare OPTION_REG = 0b00000000; // Activați pull up Resistor pe portul B pentru comutatoarele BUZZ = 0; // Turnul soneriei
Deoarece avem fișierele de antet LCD și I2C legate de programul principal, putem începe inițializarea LCD apelând o funcție simplă. La fel se poate face și pentru inițializarea I2C. Aici începem comunicarea I2C la 100kHz, deoarece modulul RTC funcționează cu 100kHz.
Lcd_Start (); // Inițializați modulul LCD I2C_Initialize (100); // Inițializați I2C Master cu ceas de 100KHz
Funcția de mai jos este utilizată pentru a seta ora și data pe modulul RTC, după ce ora și data sunt setate, eliminați această linie. Altfel de fiecare dată când porniți programul, ora și data vor fi setate din nou și din nou
// Eliminați linia de mai jos odată ce data și ora sunt setate pentru prima dată. Set_Time_Date (); // setați ora și data pe modulul RTC
Pentru a indica faptul că programul pornește, afișăm un mic ecran introductiv care afișează numele proiectului și numele site-ului web așa cum se arată mai jos
// Trimiteți un mesaj introductiv pe LCD Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String („Ceas cu alarmă”); Lcd_Set_Cursor (2,1); Lcd_Print_String ("-Circuit Digest"); __delay_ms (1500);
În interiorul buclei while trebuie să citim ora și data curente din modulul RTC, acest lucru se poate face doar prin apelarea funcției de mai jos.
Update_Current_Date_Time (); // Citiți data și ora curente din modulul RTC
Apelarea funcției de mai sus va actualiza variabilele sec, min și oră cu valoarea curentă. Pentru a le afișa pe ecranul LCD trebuie să le împărțim în caractere individuale folosind codul de mai jos.
// Împărțiți în caractere pentru a afișa pe lcd caractere sec_0 = sec% 10; char sec_1 = (sec / 10); char min_0 = min% 10; char min_1 = min / 10; char hour_0 = ora% 10; ora char_1 = ora / 10;
Apoi, actualizăm valorile pe ecranul LCD. Ora curentă va fi afișată în prima linie și ora setată la care trebuie declanșată alarma este afișată pe a doua linie. Codul care face același lucru este prezentat mai jos.
// Afișați Ora curentă pe ecranul LCD Lcd_Clear (); Lcd_Set_Cursor (1, 1); Lcd_Print_String ("TIME:"); Lcd_Print_Char (ora_1 + '0'); Lcd_Print_Char (hour_0 + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (min_1 + '0'); Lcd_Print_Char (min_0 + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (sec_1 + '0'); Lcd_Print_Char (sec_0 + '0'); // Afișează Data pe ecranul LCD Lcd_Set_Cursor (2, 1); Lcd_Print_String ("Alarmă:"); Lcd_Print_Char (alarm_val + '0'); Lcd_Print_Char (alarm_val + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (alarm_val + '0 '); Lcd_Print_Char (alarm_val + '0');
Acum, am afișat ora și ora setată pe ecranul LCD, trebuie să verificăm dacă utilizatorul încearcă să seteze ora alarmei. Pentru a face acest lucru, utilizatorul trebuie să apese butonul din mijloc, așa că vom verifica dacă butonul din mijloc este apăsat și vom comuta o variabilă pentru a intra în modul setare alarmă. Același buton va fi apăsat din nou pentru a confirma că valorile sunt setate și, în acest caz, trebuie să ieșim din modul setare alarmă. Deci, folosim linia de cod de mai jos pentru a schimba starea variabilei set_alarm .
// Utilizați butonul din mijloc pentru a verifica dacă alarma trebuie setată dacă (MB == 0 && set_alarm == 0) {// Dacă butonul din mijloc este apăsat și alarma nu este activată în timp ce (! MB); // Așteptați până când butonul este eliberat set_alarm = 1; // începeți să setați valoarea alarmei } dacă (MB == 0 && set_alarm == 1) {// Dacă butonul din mijloc este apăsat și alarma nu este oprită în timp ce (! MB); // Așteptați până când butonul este eliberat set_alarm = 0; // opriți setarea valorii alarmei }
Dacă utilizatorul a apăsat butonul din mijloc, atunci înseamnă că încearcă să seteze ora alarmei. În acest caz, programul intră în modul setare alarmă utilizând codul de mai sus. În modul de setare a alarmei, dacă utilizatorul apasă butonul stânga sau dreapta înseamnă că trebuie să deplasăm cursorul spre stânga sau spre dreapta. Pentru a face acest lucru, pur și simplu creșterea descrește valoarea poziției la care trebuie plasat cursorul
if (LB == 0) {// Dacă butonul stânga este apăsat în timp ce (! LB); // Așteptați până când butonul este eliberat pos--; // Apoi mutați cursorul la stânga } if (RB == 0) {// Dacă butonul din dreapta este apăsat în timp ce (! RB); // Așteptați până când butonul este eliberat pos ++; // Mutați cursorul la dreapta }
În timp ce utilizați un buton cu un microcontroler sau microprocesor, există o problemă comună de rezolvat. Această problemă este denumită sub formă de comutator. Atunci când butonul este apăsat, acesta poate da impulsuri zgomotoase MCU / MPU, care ar putea falsifica MCU pentru mai multe intrări. Această problemă poate fi rezolvată prin adăugarea unui condensator peste comutator sau prin utilizarea unei funcții de întârziere imediat ce este detectată apăsarea butonului. Acest tip de soluție se numește de-bouncing. Aici am folosit o buclă de timp pentru a menține programul în poziție până când butonul este eliberat. Aceasta nu este cea mai bună soluție de deconectare, dar pentru noi va funcționa foarte bine.
while (! RB);
Similar butoanelor stânga și dreapta, avem și butoanele superioară și inferioară, care pot fi folosite pentru a mări sau micșora valoarea timpului de alarmă. Codul pentru a face același lucru este prezentat mai jos. Observați că fiecare caracter al timpului de alarmă setat este adresat de valoarea indicelui matricei. În acest caz putem accesa cu ușurință caracterul necesar ale cărui valori trebuie modificate.
if (UB == 0) {// Dacă butonul superior este apăsat în timp ce (! UB); // Așteptați până când butonul este eliberat alarm_val ++; // Măriți acea valoare a caracterului special } dacă (BB == 0) {// Dacă butonul inferior este apăsat în timp ce (! UB); // Așteptați până când butonul este eliberat alarm_val--; // Reduceți valoarea respectivă a caracterului }
Odată setată ora alarmei, utilizatorul va apăsa din nou butonul din mijloc. Apoi putem începe să comparăm ora curentă cu ora setată. Comparația verificând dacă fiecare caracter al timpului curent este egal cu caracterul timpului stabilit. Dacă valorile sunt egale, atunci declanșăm alarma setând variabila trigger_alarm , altfel comparăm până când devine egală.
// IF alarm is set Verificați dacă valoarea setată este egală cu valoarea curentă if (set_alarm == 0 && alarm_val == hour_1 && alarm_val == hour_0 && alarm_val == min_1 && alarm_val == min_0) trigger_alarm = 1; // Activați declanșatorul dacă valoarea se potrivește
Dacă alarma este setată, trebuie să emită un semnal sonor pentru a avertiza utilizatorul pentru alarmă. Acest lucru se poate face prin simpla comutare a soneriei la un interval regulat, după cum se arată mai jos.
if (trigger_alarm) {// If alarm is triggered // Beep the buzzer BUZZ = 1; __delay_ms (500); BUZZ = 0; __delay_ms (500); }
Simulare:
Acest program poate fi, de asemenea, simulat folosind software-ul proteus. Re-creați circuitul prezentat mai sus și încărcați fișierul hex în PIC. Codul hexagonal pentru acest proiect poate fi găsit în fișierul ZIP care este legat aici. O captură de ecran realizată în timpul simulării este prezentată mai jos
Simularea devine foarte utilă atunci când încercați să adăugați noi caracteristici proiectului. De asemenea, puteți utiliza modulul de depanare I2C pentru a verifica ce date intră și ies prin magistrala I2C. Puteți încerca să apăsați butoanele și să setați, de asemenea, ora alarmei. Când timpul setat este egal cu ora curentă, atunci buzzerul va crește.
Funcționarea ceasului cu alarmă digitală utilizând PIC16F877A:
Construiți circuitul pe panou, obțineți codul de la linkul de descărcare și compilați-l folosind compilatorul MplabX și XC8. Dacă ați descărcat codul din fișierul ZIP furnizat aici, atunci nu ar trebui să aveți nicio problemă la compilarea acestuia, deoarece fișierele antet sunt deja atașate.
După compilare, încărcați programul către hardware folosind programatorul PicKit3. Conexiunea pentru conectarea programatorului pickit la PIC IC este, de asemenea, prezentată în diagrama circuitului. După ce programul este încărcat, ar trebui să vedeți ecranul de introducere și apoi timpul afișat, puteți utiliza butoanele pentru a seta ora alarmei. Configurarea hardware-ului meu atunci când este alimentat arată așa mai jos.
Când ora alarmei se potrivește cu ora curentă, soneria va începe să emită un semnal sonor pentru a alarma utilizatorul. Lucrarea completă poate fi găsită la videoclipul de mai jos. Proiectul are o mulțime de opțiuni pe care să se bazeze. Modulul RTC poate urmări orice oră și dată, astfel încât să puteți efectua o sarcină programată în orice moment / dată necesară. De asemenea, puteți conecta un aparat de curent alternativ ca un ventilator sau o lumină și să-l programați să pornească sau să oprească atunci când este necesar. Există încă mult mai multe lucruri pe care le puteți construi pe acest proiect, anunțați-mi ce idee vă vine în minte ca upgrade la acest proiect și voi fi bucuros să aud de la dvs.
Sper că ați înțeles proiectul și ați învățat ceva util din proces. Dacă aveți nelămuriri în acest proiect, folosiți secțiunea de comentarii pentru a le posta sau utilizați forumurile pentru orice ajutor tehnic.
Codul PIC complet cu fișiere antet poate fi găsit aici