- Nødvendige materialer:
- Forudsætninger:
- Kredsløbsdiagram:
- Programmering til vækkeur:
- Simulation:
- Arbejde med digitalt vækkeur ved hjælp af PIC16F877A:
Den digitale revolution startede i 1950 ændrer alle eksisterende mekaniske og analoge elektroniske strukturer til digitale computere. Da væksten af digital elektronik har været eksponentiel, er det i dag næsten umuligt for en person at modstå at bruge noget elektronisk udstyr. Fra det vækkeur, der vækker dig og brødristeren, der serverer morgenmad, er alt et bidrag fra digital elektronik. Når jeg tænker på alle disse, er det virkelig spændende at programmere vores egne ting, der kan udføre enkle, men nyttige opgaver, som det vækkeur, vi skal bygge i dette projekt med PIC Microcontroller. Vi har tidligere bygget vækkeur med andre mikrocontrollere:
- Raspberry Pi vækkeur ved hjælp af RTC-modul DS1307
- Arduino-baseret digitalt ur med alarm
- Vækkeur ved hjælp af ATmega32 Microcontroller
Dette vækkeur har et 16x2 LCD display, der viser det aktuelle tidspunkt og den indstillede tid. Vi bruger få trykknapper til at indstille alarmtiden, når det er nødvendigt. Den aktuelle tid holdes på sporet ved hjælp af DS3231 RTC-modulet, og vi bruger IIC-kommunikation til at hente disse værdier fra RTC-modulet. Vi har allerede lært om RTC-modulet og hvordan man bruger det til PIC. Så det anbefales at læse igennem denne tutorial, vi springer over de fleste af de oplysninger, der er dækket af denne tutorial.
Nødvendige materialer:
- Brødbræt - 2Nr
- PIC16F877A
- 5V strømkilde - forsyningsmodul
- 20 MHz krystal
- 33pf kondensator - 2Nos
- DS3231 RTC-modul
- 16 * 2 LCD display modul
- 10K POTTE
- 10k og 1K modstand
- Trykknapper - 5Nr
- Summer
- Tilslutning af ledninger
Forudsætninger:
Dette projekt kræver, at du kender nogle få grundlæggende oplysninger om PIC-mikrocontrolleren, og hvordan du programmerer den. Vi bruger GPIO'er, LCD-display og RTC-modul til dette projekt. Så det er bedre at lære at bruge disse moduler på forhånd. Følgende links hjælper dig med at lære det samme
- Skriv dit første program med PIC Microcontroller
- Grænseflade LCD med PIC
- I2C kommunikation ved hjælp af PIC
- DS3231 RTC-grænseflade med PIC
Kredsløbsdiagram:
Kredsløbsdiagrammet til dette PIC-baserede vækkeursprojekt er vist nedenfor, som blev oprettet ved hjælp af proteus-softwaren. Den vil også blive brugt til simulering yderligere i dette projekt.
De fem trykknapper fungerer som en indgang til indstilling af alarmen til den krævede tid. Så den ene ende af alle trykknapper er forbundet til jorden, og de andre ender er forbundet til PORTB-pin, intern pull-up-modstand vil blive brugt på disse ben for at undgå, at benene flyder. Summeren fungerer som en output og giver os et bip, når alarmen udløses og er forbundet til PORT S-stiften. Den aktuelle tid holdes altid på sporet af DS3231 RTC-modulet, hvorfra PIC modtager dataene via I2C-bus, så SCL- og SDA-stifterne på RTC-modulet er forbundet til SCL og SDA-stiften på PIC-controlleren. En LCD-skærm er fastgjort til PORTD på PIC, som bruges til at vise det aktuelle tidspunkt og den indstillede tid. Lær mere om brug af DS3231 RTC-modul med PIC her.
Det komplette kredsløb kan bygges over et brødbræt. Da der er et par dusin ledninger, der skal forbindes, så vær bare tålmodig og sørg for, at forbindelserne er korrekte. Min hardwareopsætning så ud som dette nedenfor, når jeg var færdig med forbindelserne
Jeg har brugt et breadboard-modul og 12V-adapter til at drive modulet. Dette er min kilde til + 5V forsyningsspænding. Jeg er også nødt til at bruge to brødbrædder for at holde kredsløbet rent. Du kan også lodde hele kredsløbet til et perf-kort, hvis du ønsker at skabe et mere robust projekt.
Programmering til vækkeur:
Det komplette PIC-program til dette vækkeursprojekt findes nederst på denne side. Dette projekt kræver også tre biblioteker til brug af LCD, I2C og RTC med PIC. Den komplette kode med headerfiler kan downloades fra ZIP-filen her og kan åbnes ved hjælp af MPLABX efter udpakning. Længere nedenfor forklarer jeg bare de vigtigste c-filer som små uddrag. Du kan falde tilbage til de ovennævnte tutorials, hvis du vil vide, hvordan header-filerne fungerer.
Før vi går ind i hovedprogrammet, skal vi definere de ben, vi har brugt med et mere meningsfuldt navn. På denne måde vil det være let at bruge dem under programmering. De ben, der er defineret i vores program, vises nedenfor
// Definer LCD-stifter #definer RS RD2 // Nulstil stift på LCD # definer EN RD3 // Aktivér stift på LCD # definer D4 RD4 // Databit 0 i LCD # definer D5 RD5 // Databit 1 i LCD # definer D6 RD6 // Databit 2 i LCD #definer D7 RD7 // Databit 3 i LCD // Definer knapper #definer MB RB1 // Den midterste knap #definer LB RB0 // Venstre knap #definer RB RB2 // Højreknap # definere UB RB3 // Øvre knap #definer BB RB4 // Bundknap // Definer buzz #definer BUZZ RD1 // Buzzer er tilsluttet RD1
Inde i hovedfunktionen starter vi med at erklære input- og outputpindene. I vores projekt bruges PORTB til trykknapper, som er en inputenhed, så vi indstiller deres ben som indgange og PORTD bruges til LCD og summer, så vi indstiller deres ben som Output. Også en stift skal aldrig efterlades flydende, hvilket betyder, at I / O-stifterne altid skal tilsluttes enten jord eller til + 5V spænding. I vores tilfælde for trykknapperne er stifterne ikke forbundet til noget, når der ikke trykkes på knappen, så vi bruger en intern pull-up-modstand, der sætter stiften til High, når den ikke er i brug. Dette gøres ved hjælp af kontrolregistrene som vist nedenfor
TRISD = 0x00; // Lav Port D-stifter som outptu for LCD-interface TRISB = 0xFF; // Omskiftere erklæres som inputstifter OPTION_REG = 0b00000000; // Aktiver pull up- modstand på port B for switche BUZZ = 0; // Turn af summer
Da vi har LCD- og I2C-headerfilen forbundet med hovedprogrammet, kan vi starte LCD-initialiseringen ved at kalde en simpel funktion. Det samme kan også gøres for I2C-initialisering. Her starter vi I2C-kommunikationen ved 100 kHz, da RTC-modulet fungerer med 100 kHz.
Lcd_Start (); // Initialiser LCD-modul I2C_Initialize (100); // Initialiser I2C Master med 100KHz ur
Nedenstående funktion bruges til at indstille tid og dato på RTC-modulet, når tid og dato er indstillet, skal du fjerne denne linje. Ellers hver gang du starter programmet, indstilles tid og dato igen og igen
// Fjern nedenstående linje, når tid og dato er indstillet for første gang. Set_Time_Date (); // indstil tid og dato på RTC-modulet
For at indikere, at programmet starter, viser vi en lille introduktionsskærm, der viser navnet på projektet og webstedsnavnet som vist nedenfor
// Giv en introbesked på LCD-skærmen Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String ("Alarm Clock"); Lcd_Set_Cursor (2,1); Lcd_Print_String ("-Circuit Digest"); __forsink_ms (1500);
Næste inde i while- sløjfen skal vi læse den aktuelle tid og dato fra RTC-modulet, dette kan gøres ved blot at ringe til nedenstående funktion.
Update_Current_Date_Time (); // Læs den aktuelle dato og tid fra RTC-modulet
Når du kalder ovenstående funktion, opdateres variablerne sek, min og time med den aktuelle værdi. For at vise dem på LCD-skærmen er vi nødt til at opdele dem i individuelle tegn ved hjælp af nedenstående kode.
// Del den i char for at blive vist på lcd char sec_0 = sec% 10; char sec_1 = (sek / 10); char min_0 = min% 10; char min_1 = min / 10; char time_0 = time% 10; char hour_1 = time / 10;
Dernæst opdaterer vi værdierne over LCD-skærmen. Det aktuelle klokkeslæt vises på den første linje, og det indstillede tidspunkt, hvor alarmen skal udløses, vises på den anden linje. Koden, der gør det samme, vises nedenfor.
// Vis den aktuelle tid på LCD-skærmen Lcd_Clear (); Lcd_Set_Cursor (1, 1); Lcd_Print_String ("TID:"); 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'); // Vis datoen på LCD-skærmen 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');
Nu har vi vist klokkeslættet og indstillet tid på LCD'et, vi skal kontrollere, om brugeren forsøger at indstille alarmtiden. For at gøre dette skal brugeren trykke på den midterste knap, så vi vil kontrollere, om der trykkes på den midterste knap og skifte en variabel for at gå ind i alarmindstillingstilstand. Den samme knap trykkes igen for at bekræfte, at værdierne er indstillet, og i så fald skal vi komme ud af alarmindstillingstilstand. Så vi bruger nedenstående kodelinje til at ændre status for variablen set_alarm .
// Brug den midterste knap til at kontrollere, om alarmen skal indstilles, hvis (MB == 0 && set_alarm == 0) {// Hvis den midterste knap trykkes, og alarmen ikke er tændt, mens (! MB); // Vent til knappen frigives set_alarm = 1; // start indstilling af alarmværdi } hvis (MB == 0 && set_alarm == 1) {// Hvis der trykkes på den midterste knap, og alarmen ikke er slået fra, mens (! MB); // Vent til knappen frigives set_alarm = 0; // stop med at indstille alarmværdi }
Hvis brugeren har trykket på den midterste knap, betyder det, at han prøver at indstille alarmtiden. I dette tilfælde går programmet i alarmsæt-tilstand ved hjælp af ovenstående kode. Inde i alarmindstillingen, hvis brugeren trykker på venstre eller højre knap, betyder det, at vi er nødt til at flytte markøren til venstre eller højre. For at gøre dette øger vi simpelthen forøgelsen af værdien af positionen, hvor markøren skal placeres
hvis (LB == 0) {// Hvis der trykkes på venstre knap, mens (! LB); // Vent til knappen slippes pos--; // Flyt derefter markøren til venstre } hvis (RB == 0) {// Hvis der trykkes på højre knap mens (! RB); // Vent til knappen frigives pos ++; // Flyt markøren til højre }
Mens du bruger en trykknap med en mikrocontroller eller mikroprocessor, er der et almindeligt problem at tackle. Dette problem kaldes som switchbouncing. Når der trykkes på knappen, kan det give støjende impulser til MCU / MPU, som måske falsker MCU'en for flere poster. Dette problem kan løses ved at tilføje en kondensator over kontakten eller ved at bruge en forsinkelsesfunktion, så snart der trykkes på knappen. Denne type løsning kaldes afbouncing. Her har vi brugt et stykke loop til at holde programmet på plads, indtil knappen slippes. Dette er ikke den bedste løsning for afvisning, men for os fungerer det fint.
mens (! RB);
I lighed med venstre og højre knap har vi også de øvre og nedre knapper, som kan bruges til at øge eller mindske værdien for alarmtid. Koden til at gøre det samme vises nedenfor. Bemærk, at hvert tegn i den indstillede alarmtid adresseres af matrixens indeksværdi. Dette var, at vi let kan få adgang til det krævede tegn, hvis værdier skal ændres.
hvis (UB == 0) {// Hvis der trykkes på den øverste knap, mens (! UB); // Vent til knappen frigives alarm_val ++; // Forøg den pågældende kulværdi } hvis (BB == 0) {// Hvis der trykkes på den nederste knap, mens (! UB); // Vent til knappen frigives alarm_val--; // Reducer den pågældende char-værdi }
Når alarmtiden er indstillet, vil brugeren trykke på den midterste knap igen. Derefter kan vi begynde at sammenligne den aktuelle tid med den indstillede tid. Sammenligningen ved at kontrollere, om hvert enkelt tegn i det aktuelle tidspunkt er lig med tegnet på den indstillede tid. Hvis værdierne er ens, udløser vi alarmen ved at indstille trigger_alarm- variablen ellers sammenligner vi bare, indtil den bliver lige.
// IF alarm er indstillet Kontroller, om den indstillede værdi er lig med den aktuelle værdi, hvis (set_alarm == 0 && alarm_val == hour_1 && alarm_val == hour_0 && alarm_val == min_1 && alarm_val == min_0) trigger_alarm = 1; // Tænd udløseren, hvis værdien matcher
Hvis alarmen er indstillet, skal vi bippe en summer for at advare brugeren om alarm. Dette kan gøres ved blot at skifte summer med et regelmæssigt interval som vist nedenfor.
hvis (trigger_alarm) {// Hvis alarm udløses // Bip summeren BUZZ = 1; __forsink_ms (500); BUZZ = 0; __forsink_ms (500); }
Simulation:
Dette program kan også simuleres ved hjælp af proteus-softwaren. Genopret bare det kredsløb, der er vist ovenfor, og indlæs hex-filen i PIC. Hex-koden for dette projekt kan findes i ZIP-filen, der er linket her. Et skærmbillede taget under simuleringen er vist nedenfor
Simuleringen bliver meget nyttig, når du prøver at tilføje nye funktioner til projektet. Du kan også bruge I2C debugger-modulet til at kontrollere, hvilke data der går ind og kommer ud gennem I2C-bussen. Du kan prøve at trykke på knapperne og også indstille alarmtiden. Når den indstillede tid er lig med den aktuelle tid, går summeren højt.
Arbejde med digitalt vækkeur ved hjælp af PIC16F877A:
Byg kredsløbet på brødbrættet, hent koden fra downloadlinket, og kompilér det ved hjælp af MplabX- og XC8-kompilatoren. Hvis du har downloadet koden fra ZIP-filen, der er angivet her, skal du ikke have noget problem med at kompilere den, da headerfiler allerede er vedhæftet.
Efter kompilering skal du uploade programmet til din hardware ved hjælp af PicKit3-programmøren. Forbindelsen til at forbinde pickit-programmøren til PIC IC er også vist i kredsløbsdiagrammet. Når programmet er uploadet, skal du se introduktionsskærmen og derefter det viste tidspunkt kan du bruge trykknapperne til at indstille alarmtiden. Min hardwareopsætning, når den er tændt, ser sådan ud nedenfor.
Når alarmtiden stemmer overens med det aktuelle tidspunkt, vil summeren bippe for at alarmere brugeren. Det komplette arbejde kan findes i videoen nedenfor. Projektet har en overflod af muligheder at bygge videre på. RTC-modulet kan holde styr på ethvert tidspunkt og dato, så du kan udføre en planlagt opgave til enhver tid / dato. Du kan også tilslutte et vekselstrømsapparat som en blæser eller lys og planlægge det til at tænde eller slukke, når det er nødvendigt. Der er stadig meget mere, du kan bygge videre på dette projekt. Lad mig vide, hvilken idé du kommer til at tænke på som en opgradering til dette projekt, og jeg vil med glæde høre fra dig.
Håber du forstod projektet og lærte noget nyttigt af processen. Hvis du er i tvivl om dette projekt, skal du bruge kommentarsektionen til at sende dem eller bruge fora til teknisk hjælp.
Komplet PIC-kode med headerfiler kan findes her