- Material som krävs:
- RTC-modul:
- Ansluta DS3231 RTC med PIC Microcontroller:
- Programmering av PIC för RTC-modul:
- Kort förklaring av PIC16F877a_DS3231.h rubrikfil:
- Simulering:
- Visningstid och datum på LCD:
Nästan alla inbäddade enheter är utformade för att interagera med den verkliga världen. De fungerar som en bro för att kommunicera mellan den digitala världen och den verkliga världen. För att göra denna process enklare och effektivare skulle den digitala världen ibland behöva hålla reda på tidpunkten för och datumet för den verkliga världen. På så sätt vet den digitala världen vilken tid / dag det är i den verkliga världen och kan till och med skilja mellan dag eller natt. Det kan också fungera som en tidskälla för att utföra vissa uppgifter vid en viss tid eller ett visst datum. Så här gränssnitt vi en RTC-modul med PIC Microcontroller och visar tid och datum på 16x2 LCD. Detta projekt kan också användas som digital klocka.
Material som krävs:
- Reglerad 5V-försörjning
- PIC16F877A
- Crystal Oscillator 20Mhz
- Kondensator 33pf - 2Nos
- 10K, 5.1K, 1K motstånd
- DS3231 RTC-modul
- POT -10k
- LCD-modul 16 * 2
- Anslutande ledningar
RTC-modul:
Det vanligaste sättet för en mikrokontroller att hålla reda på den verkliga världens tid eller datum är att använda en RTC IC. Termen RTC står för Real Time Clock; denna IC håller reda på den verkliga världens tid och datum och skulle dela denna information med mikrokontrollern när så önskas. RTC IC som vi använder här är den mest populära och korrekta DS3231. Denna IC driver bara några sekunder varje år och är därför mycket tillförlitlig. För denna handledning använder vi DS3231 RTC-modulen som enkelt kan köpas online eller från den lokala hårdvaruaffären. Modulen levereras med en 3V-myntcell som alltid driver RTC-modulen och därför kommer tid och datum att uppdateras så länge som myntcellen lever.
DS3231-modulen kommunicerar med hjälp av I2C-protokollet, så om du inte är medveten om vad det är och hur det används med PIC, läs I2C med PIC-handledning innan du fortsätter. I den här självstudien ska vi skapa en rubrikfil som kan användas för att kommunicera med vår RTC-modul och testa samma på hårdvara genom att visa tid och datum på en LCD-skärm så det är också viktigt att lära sig hur man gränssnitt LCD display med PIC-mikrokontroller. Rubrikfilen som skapats i den här självstudien för DS3231 kan senare användas / ändras för att passa dina applikationer.
Vi har tidigare använt DS3231 RTC med Arduino i nedanstående projekt:
- Automatisk husdjursmatare med Arduino
- Arduino Data Logger
Ansluta DS3231 RTC med PIC Microcontroller:
Kretsschema för PIC Microcontroller-baserad digital klocka ges nedan. Som tidigare nämnts fungerar DS3231 med hjälp av I2C-kommunikation så att den kommer att ha en seriell klocka (SCL) och en SDA-stift (Serial Data) som måste anslutas till I2C-stiften på vår PIC som är stift 18 (SCL) och stift 23 (SDA). Ett pull-up-motstånd med värdet 4,7k används för att hålla bussen i högt tillstånd när den är i tomgång.
En LCD-skärm är också ansluten till stiften på port D för att visa aktuellt datum och tid. Hela kretsschemat designades på proteus och visas nedan. Vi kommer att använda samma för att simulera eller programmera senare i denna handledning.
Följ kretsschemat och gör anslutningarna därefter, I2C-rutan som visas ovan används för I2C-felsökning så att vi inte tar med den i våra anslutningar. Det visas inte heller att RTC-modulen måste drivas med en + 5V-matning med hjälp av Vcc och jordstift på modulen. Jag använde mitt brödbräda för att skapa anslutningen och efter att ha gjort de nödvändiga anslutningarna såg min inställning ungefär så här nedan.
Om du är ny på PIC Microcontroller börja med Komma igång med PIC Microcontroller.
Programmering av PIC för RTC-modul:
Det fullständiga programmet för denna digitala klocka kan laddas ner från ZIP-filen här. Programmet innehåller tre huvudfiler helt och hållet. De är lcd.h- filen för att arbeta med LCD-skärm, PIC16F877a_I2C.h- filen för att arbeta med I2C-kommunikation med PIC och slutligen PIC16F877a_DS3231.h fil för att fungera med RTC-moduler. Alla tre huvudfiler krävs för detta program och finns i ZIP-filen ovan. Längre ner kommer jag att förklara huvudprogrammet som använder alla dessa rubrikfiler för att läsa tid och datum från RTC-modulen och visa det på LCD-skärmen. Efter det kommer jag att förklara vad som faktiskt händer i RTC-huvudfilen. Som alltid börja programmet med att ställa in konfigurationsbitarna och ställa in klockfrekvensen som 20MHz eftersom det är vad vi har använt i vår hårdvara.
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled) # pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled ) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 är digital I / O, HV på MCLR måste användas för programmering) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all programm memory) kan skrivas till av EECON-kontroll) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) #define _XTAL_FREQ 20000000
Nästa steg skulle vara att definiera LCD-stift, om du tittar på hårdvaran kan du märka att vi har anslutit LCD-stiften till PORT D från RD2 till RD7, så vi definierar samma som visas nedan.
#define RS RD2 #define EN RD3 #define D4 RD4 #define D5 RD5 #define D6 RD6 #define D7 RD7
Som standard när du köpte RTC-modulen kommer rätt tid och datum inte att anges i den, så vi måste ställa in den genom vårt program. Så vi förklarar variabla för varje data och flöde i verklig tid och datum som visas nedan. Vid tidpunkten för uppladdning av programmet var min tid och datum kl 10:55 den 6-5-2018 så jag har ställt in variablerna enligt nedan. Du kan ställa in rätt tid och datum enligt din faktiska ansökan
/ * Ställ in aktuellt värde för datum och tid under * / int sec = 00; int min = 55; int timme = 10; int datum = 06; int månad = 05; int år = 18; / * Tid och datum inställd * /
Därefter lägger vi till alla rubrikfiler som vi diskuterade om. Om du har laddat ner och öppnat programmet från ZIP-filen kommer det inte att vara ett problem. Se till att alla rubrikfiler läggs till i din källfil eller projektkatalog.
#omfatta
Eftersom vi har använt PORT D som utgångsstift för gränssnitt mellan LCD-skärmen måste vi förklara dem som utgångsstift i vårt program och initialisera LCD-skärmen enligt nedan.
TRISD = 0x00; // Gör Port D-stift som outptu för LCD-gränssnitt Lcd_Start (); // Initiera LCD-modulen
RTC-modulen kommunicerar med hjälp av I2C-protokollet så vi måste aktivera I2C-kommunikationen vår PIC-mikrokontroller. De flesta enheter inklusive våra DS3231-moduler har en I2C-arbetsfrekvens på 100 kHz så vi startar I2C-kommunikationen med en frekvens på 100 kHz som visas nedan
I2C_Initialize (100); // Initiera I2C Master med 100KHz klocka
Så snart vi har skapat en I2C-kommunikation med RTC-modulen är det första vi gör att ställa in aktuell tid och datum som vi angav i vårt program. Detta kan göras genom att anropa funktionen set_Time_Date enligt nedan. När tid och datum har ställts in kommer modulen att automatiskt hålla reda på det och öka dem precis som en digital klocka.
Set_Time_Date (); // ställa in tid och datum på RTC-modulen
För att indikera att programmet har startat visar vi ett litet introduktionsmeddelande som förblir på skärmen i 2 sekunder. Detta meddelande visar RTC med PIC – Circuit Digest på skärmen. Programmet för detsamma visas nedan
Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String ("RTC med PIC"); Lcd_Set_Cursor (2,1); Lcd_Print_String ("-Circuit Digest"); __fördröja_ms (1500);
Inuti vår oändliga stund- slinga bör vi läsa aktuell tid och datum och sedan visa värdena på vår LCD-skärm. För att läsa tid och datum från RTC-modulen kan funktionen Update_Current_Time_Date användas som visas nedan. Denna funktion läser värdet från RTC-modulen och uppdaterar variablerna sek, min, timme, datum, månad och år med aktuella värden. Då kan vi använda dem för vårt syfte.
Update_Current_Date_Time (); // Läs aktuellt datum och tid från RTC-modulen
Variablerna är av heldatatyp, vi måste konvertera dem till enskilda tecken så att vi kan visa dem på LCD-skärmen. Så vi använder moduloperatorn för att få en siffra och dela variabeln med 10 för att få tiotals siffran. Samma sak görs för alla variabler.
// Dela upp i char för att visas på LCD char sec_0 = sec% 10; char sec_1 = (sek / 10); char min_0 = min% 10; char min_1 = min / 10; char hour_0 = timme% 10; char hour_1 = hour / 10; char date_0 = datum% 10; char date_1 = datum / 10; char månad_0 = månad% 10; char månad_1 = månad / 10; char år_0 = år% 10; char år_1 = år / 10;
Allt som återstår att göra är att visa informationen som vi fick på LCD-skärmen. Detta kan enkelt göras med LCD-funktionerna som vi tidigare har diskuterat i vår LCD-handledning. Så koden för visningstid anges nedan, samma metod används också för att visa datumet. En fördröjning på 500 ms ges efter visning av data så att den fungerar som ett uppdateringsintervall.
Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String ("TIME:"); Lcd_Print_Char (hour_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');
Kort förklaring av PIC16F877a_DS3231.h rubrikfil:
Saker som förklarats hittills är tillräckliga för att använda DS3231-modulen med PIC för dina egna projekt, men för de nyfikna sinnen där ute vill veta vad som faktiskt händer i huvudfilen och data tas faktiskt emot från RTC-modulen av PIC, bara läs vidare.
Det bästa sättet att gå igenom detta är att läsa databladet för DS3231 fullständigt. För att ge en kortfattad beskrivning av vad som behövs fungerar modulen som en slav till PIC och adressen för alla DS3231-moduler är D0. Så skriv data till modulen vi måste skicka adressen D0 och för att läsa data från RTC måste vi skicka adressen D1. Om vi skickar skrivadressen till RTC-modulen är vi beredda att få data från PIC så att den därav följande data som skrivits av PIC kommer att tas emot och sparas i RTC-modulen. På samma sätt om vi skickar adressen till Readdå bör PIC göra sig redo att läsa värdena från RTC eftersom RTC-modulen börjar skicka all data den har. Bitsekvensen för både D0 och D1 visas nedan från databladet. Lägg märke till att adressen 0b11010000 står för D0 (Skriv) och 0b11010001 står för D01 (Läs)
När PIC skickar adressen D0 eller D1 antingen för att skriva eller läsa, ska följande data läsas eller skrivas i en ordning. Denna ordning visas i tabellen nedan. Så de första uppgifterna kommer att vara sek (00h) följt av minuter (01h) följt av timmar (02h) följt av dag (03h) och upp till MSB för temperatur.
RTC-modulen förstår inte decimalvärden, den kommunicerar endast via BCD-värden. Så innan du skriver några värden till RTC-modulen ska den konverteras till BCD och även de värden som tas emot från RTC-modulen kommer att vara i BCD-format och den ska konverteras till decimal för att vara vettigt för oss. Med detta i åtanke kan du skapa alla funktioner som krävs för att använda RTC-modulen.
BCD_2_DEC och DEC_2_BCD funktioner:
De två första funktionerna skulle användas för att konvertera BCD-data till decimal och decimaldata till BCD eftersom RTC-modulen endast förstår BCD. Formlerna för att konvertera BCD till decimal och för BCD till decimal är
Decimal = (BCD >> 4) * 10 + (BCD & 0x0F) BCD = ((Decimal / 10) << 4) + (Decimal% 10)
Vi måste bara använda dessa två formler för att skapa en funktion som tar i motsatt enhet som parameter och konverterar den till önskat format och returnerar den, funktionen för att göra detsamma visas nedan
int BCD_2_DEC (int to_convert) { return (to_convert >> 4) * 10 + (to_convert & 0x0F); } int DEC_2_BCD (int to_convert) { return ((to_convert / 10) << 4) + (to_convert% 10); }
Set_Time_Date () -funktion:
Denna funktion skriver tid och datum från PIC till RTC-modulen. Värdena för realtid och datum måste uppdateras i variablerna sek, min, timme, datum, månad och år av användaren. Dessa värden konverteras sedan till BCD och skrivs till RTC-modulen.
Som vi diskuterade, för att skriva ett värde till RTC-modulen måste vi skicka adressen D0 och skriva en bullbit 0 för att initiera skrivprocessen. Sedan kan vi skicka uppgifterna i den ordning som visas i tabellen ovan.
ogiltig Set_Time_Date () { I2C_Begin (); I2C_Write (0xD0); I2C_Write (0); I2C_Write (DEC_2_BCD (sek)); // uppdatera sek I2C_Write (DEC_2_BCD (min)); // uppdatera min I2C_Write (DEC_2_BCD (timme)); // uppdatera timme I2C_Write (1); // ignorera uppdateringsdag I2C_Write (DEC_2_BCD (datum)); // uppdateringsdatum I2C_Write (DEC_2_BCD (månad)); // uppdatera månad I2C_Write (DEC_2_BCD (år)); // uppdatera år I2C_End (); }
Update_Current_Date_Time () funktion:
Den sista funktionen i biblioteket är den som används för att läsa tid och datum från RTC-modulen och vidarebefordra den till PIC-mikrokontrollern. Denna funktion är uppdelad i tre segment, ett för att starta läsningsprocessen, det andra för att läsa värdena och spara den till de globala variablerna som sek, min, timme, datum, månad och år. Och det tredje är att erkänna att läsningen lyckades.
Observera att för varje åtgärd bör I2C-kommunikationen startas och avslutas.
För att läsa värdena från RTC måste vi skicka adressen D0 följt av en 0. Detta kommer att göra att RTC-modulen skickar alla värden den har i den ordning som visas i tabellen ovan. Vi kan bara läsa dem omvandla dem till decimal och spara den till variablerna i samma ordning.
Slutligen, efter att läsningen är klar, skickar RTC-modulen en bekräftelsebit som också bör läsas och kvitteras.
ogiltig Update_Current_Date_Time () { // START för att läsa I2C_Begin (); I2C_Write (0xD0); I2C_Write (0); I2C_End (); // LÄS I2C_Begin (); I2C_Write (0xD1); // Initiera data läs sek = BCD_2_DEC (I2C_Read (1)); min = BCD_2_DEC (I2C_Read (1)); timme = BCD_2_DEC (I2C_Read (1)); I2C_Read (1); datum = BCD_2_DEC (I2C_Read (1)); månad = BCD_2_DEC (I2C_Read (1)); år = BCD_2_DEC (I2C_Read (1)); I2C_End (); // END Reading I2C_Begin (); I2C_Write (0xD1); // Initiera data läst I2C_Read (1); I2C_End (); }
Simulering:
Projektet kan simuleras med hjälp av Proteus-simuleringsprogramvaran. Gör anslutningarna som visas i kopplingsschemat och ladda hex-filen till PIC-styrenheten. När du simulerar det hittar du två popup-rutor och datum och tid visas på LCD-skärmen som visas nedan.
Den lilla överst visar tiden och datumet som är aktuellt i RTC-modulen och den andra popupen är I2C-felsökaren. Det är ett utmärkt verktyg för att kontrollera vilka data som faktiskt skickas in och ut I2C-felet.
Visningstid och datum på LCD:
När din hårdvara är klar och koden laddas ner som ZIP-fil via länken ges öppnar du programmet med MPLABX IDE. Du måste starta IDE först och använda det öppna projektalternativet och bläddra till innehållet i ZIP-filen och öppna.X-mappen.
Kontrollera bara om programmet kompilerar och ladda upp koden i din hårdvara med hjälp av PicKit3. Så snart programmet laddas upp bör du se introduktionsmeddelandet och sedan tid och datum ska visas som visas nedan.
Om det inte finns något på LCD-skärmen, kontrollera dina anslutningar och se till att kontrastnivån är korrekt inställd genom att variera potentiometern. Det är så du kan visa tid och datum för alla dina PIC-mikroprojektprojekt och kan använda detta som digital klocka. Hoppas att du har lärt dig något nytt och gillat att lära dig denna handledning. Om du har stött på problem kan du lägga upp dem på kommentarerna nedan eller på forumet för teknisk hjälp.
Ladda ner hela PIC-programmet för detta projekt med rubrikfiler härifrån och kolla vidare våra PIC-handledning här.