- Nødvendige materialer:
- Forutsetninger:
- Kretsdiagram:
- Programmering for vekkerklokke:
- Simulering:
- Arbeid med digital vekkerklokke ved bruk av PIC16F877A:
Den digitale revolusjonen startet i 1950 endrer alle eksisterende mekaniske og analoge elektroniske strukturer til digitale datamaskiner. Siden veksten av digital elektronikk har vært eksponentiell, er det i dag nesten umulig for en person å motstå å bruke noe elektronisk utstyr. Fra og med vekkerklokken som vekker deg og brødristeren som serverer deg frokost, er alt et bidrag fra digital elektronikk. Tenker på alle disse er det veldig spennende å programmere våre egne ting som kan gjøre enkle, men nyttige oppgaver, som vekkerklokken vi skal bygge i dette prosjektet med PIC Microcontroller. Vi har tidligere bygd vekkerklokke med andre mikrokontrollere:
- Raspberry Pi vekkerklokke ved hjelp av RTC-modul DS1307
- Arduino-basert digital klokke med alarm
- Vekkerklokke ved hjelp av ATmega32 Microcontroller
Denne vekkerklokken har en 16x2 LCD-skjerm som viser gjeldende tid og innstilt tid. Vi bruker få trykknapper for å stille alarmtiden når det er nødvendig. Nåværende tid vil holdes på sporet ved hjelp av DS3231 RTC-modulen, og vi vil bruke IIC-kommunikasjon for å få disse verdiene fra RTC-modulen. Vi har allerede lært om RTC-modulen og hvordan vi kan grensesnitt den med PIC. Så det anbefales å lese gjennom den veiledningen, vi hopper over det meste av informasjonen som er dekket i den veiledningen.
Nødvendige materialer:
- Brødbrett - 2Nr
- PIC16F877A
- 5V strømkilde - forsyningsmodul
- 20 MHz krystall
- 33pf kondensator - 2Nos
- DS3231 RTC-modul
- 16 * 2 LCD-skjermmodul
- 10K POTTE
- 10k og 1K motstand
- Trykknapper - 5Nr
- Summer
- Koble ledninger
Forutsetninger:
Dette prosjektet krever at du vet noen få grunnleggende om PIC-mikrokontrolleren og hvordan du programmerer den. Vi vil bruke GPIO, LCD-skjerm og RTC-modul for dette prosjektet. Så det er bedre å lære å bruke disse modulene på forhånd. Følgende lenker vil hjelpe deg å lære det samme
- Skriver ditt første program med PIC Microcontroller
- Grensesnitt LCD med PIC
- I2C-kommunikasjon ved bruk av PIC
- DS3231 RTC-grensesnitt med PIC
Kretsdiagram:
Kretsskjemaet for dette PIC-baserte vekkerklokke-prosjektet er vist nedenfor, som ble opprettet ved hjelp av proteus-programvaren. Den vil også bli brukt til simulering videre i dette prosjektet.
De fem trykknappene vil fungere som en inngang for å stille alarmen til ønsket tid. Så den ene enden av alle trykknappene er koblet til bakken og de andre endene er koblet til PORTB-pinnen. Den interne trekkmotstanden vil bli brukt på disse pinnene for å unngå at pinnene flyter. Summeren vil fungere som en utgang og vil gi oss et pip når alarmen blir utløst og er koblet til PORT S-pinnen. Gjeldende tid holdes alltid i sporet av DS3231 RTC-modulen som PIC mottar dataene fra via I2C-bussen, slik at SCL- og SDA-pinnene på RTC-modulen er koblet til SCL og SDA-pinnen til PIC-kontrolleren. En LCD-skjerm er festet til PORTD på PIC, som brukes til å vise gjeldende tid og innstilt tid. Lær mer om bruk av DS3231 RTC-modul med PIC her.
Hele kretsen kan bygges over et brødbrett. Siden det er et par dusin ledninger å koble til, så bare ha tålmodighet og sørg for at tilkoblingene er riktige. Min maskinvareoppsett så ut som dette nedenfor når jeg var ferdig med tilkoblingene
Jeg har brukt en brødbrettmodul og 12V adapter for å drive modulen. Dette er min kilde til + 5V forsyningsspenning. Også må jeg bruke to brødbrett for å holde kretsen ren. Du kan også lodde hele kretsen til et perf-kort hvis du ønsker å lage et mer robust prosjekt.
Programmering for vekkerklokke:
Hele PIC-programmet for dette vekkerklokke-prosjektet finner du nederst på denne siden. Dette prosjektet krever også tre biblioteker for bruk av LCD, I2C og RTC med PIC. Den komplette koden med overskriftsfiler kan lastes ned fra ZIP-filen her og kan åpnes ved hjelp av MPLABX etter utpakking. Lenger nedenfor forklarer jeg bare hovedfilen som små utdrag. Du kan falle tilbake til de ovennevnte opplæringene hvis du vil vite hvordan toppfiler fungerer.
Før vi går inn i hovedprogrammet, må vi definere pinnene vi har brukt med mer meningsfylt navn. På denne måten vil det være enkelt å bruke dem under programmering. Pinnene som er definert i vårt program er vist nedenfor
// Definer LCD-pinnene #define RS RD2 // Reset pin of LCD #define EN RD3 // Aktiver pin på LCD #define D4 RD4 // Data bit 0 of LCD #define D5 RD5 // Data bit 1 of LCD #define D6 RD6 // Databit 2 i LCD #definer D7 RD7 // Databit 3 i LCD // Definer knapper #definer MB RB1 // Midtre knapp #definer LB RB0 // Venstre knapp #definer RB RB2 // Høyre knapp # definere UB RB3 // Øvre knapp #definer BB RB4 // Bunnknapp // Definer Buzz #definer BUZZ RD1 // Buzzer er koblet til RD1
Inne i hovedfunksjonen vi starter med å erklære input og output pins. I prosjektet vårt brukes PORTB til trykknapper som er en inngangsenhet, så vi setter pinnene som innganger, og PORTD brukes til LCD og summer, så vi setter pinnene som utgang. Også en pinne skal aldri være flytende, noe som betyr at I / O-pinnene alltid skal være koblet til enten jord eller til + 5V-spenningen. I vårt tilfelle for trykknappene vil ikke pinnene være koblet til noe når knappen ikke trykkes, så vi bruker en intern opptrekksmotstand som setter pinnen til High når den ikke er i bruk. Dette gjøres ved hjelp av kontrollregistrene som vist nedenfor
TRISD = 0x00; // Lag port D-pinner som outptu for LCD-grensesnitt TRISB = 0xFF; // Brytere er erklært som inngangspinner OPTION_REG = 0b00000000; // Aktiver pull up- motstand på port B for brytere BUZZ = 0; // Slå av summer
Siden vi har LCD- og I2C-headerfilen knyttet til hovedprogrammet, kan vi starte LCD-initialiseringen ved å ringe en enkel funksjon. Det samme kan også gjøres for I2C-initialisering. Her starter vi I2C-kommunikasjonen ved 100 kHz siden RTC-modulen fungerer med 100 kHz.
Lcd_Start (); // Initialiser LCD-modul I2C_Initialize (100); // Initialiser I2C Master med 100KHz klokke
Funksjonen nedenfor brukes til å stille inn tid og dato på RTC-modulen, når tid og dato er satt, fjern denne linjen. Annet hver gang du starter programmet vil tid og dato bli satt igjen og igjen
// Fjern linjen nedenfor når tid og dato er satt for første gang. Set_Time_Date (); // angi tid og dato på RTC-modulen
For å indikere at programmet starter, viser vi et lite intro-skjermbilde som viser navnet på prosjektet og nettstedsnavnet som vist nedenfor
// Gi en intro-melding på LCD-skjermen 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);
Neste inne i mens sløyfen vi trenger å lese gjeldende tid og dato fra RTC-modulen, kan dette gjøres ved å bare ringe funksjonen nedenfor.
Update_Current_Date_Time (); // Les gjeldende dato og klokkeslett fra RTC-modulen
Når du ringer til funksjonen ovenfor, oppdateres variablene sek, min og time med gjeldende verdi. For å vise dem på LCD-skjermen, må vi dele dem opp i individuelle tegn ved hjelp av koden nedenfor.
// Del den i røyke for å vises på lcd røye sec_0 = sek% 10; char sec_1 = (sek / 10); røye min_0 = min% 10; røye min_1 = min / 10; røye time_0 = time% 10; røye time_1 = time / 10;
Deretter oppdaterer vi verdiene over LCD-skjermen. Gjeldende klokkeslett vises på første linje, og den innstilte tiden alarmen skal utløses på, vises på den andre linjen. Koden som gjør det samme er vist nedenfor.
// Vis gjeldende tid på LCD-skjermen 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'); // Vis datoen på LCD-skjermen 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');
Nå har vi vist klokkeslettet og angitt tid på LCD-skjermen. Vi må sjekke om brukeren prøver å stille alarmtiden. For å gjøre dette må brukeren trykke på den midterste knappen, så vi vil sjekke om den midterste knappen trykkes og bytte en variabel for å gå inn i alarminnstillingsmodus. Den samme knappen vil bli trykket igjen for å bekrefte at verdiene er satt, og i så fall må vi komme ut av alarminnstillingsmodus. Så vi bruker nedenstående kodelinje for å endre statusen til variabelen set_alarm .
// Bruk midtknappen for å sjekke om alarmen må stilles inn hvis (MB == 0 && set_alarm == 0) {// Hvis den midterste knappen trykkes og alarmen ikke er slått på mens (! MB); // Vent til knappen slippes set_alarm = 1; // start innstilling av alarmverdi } hvis (MB == 0 && set_alarm == 1) {// Hvis den midterste knappen trykkes og alarmen ikke er slått av mens (! MB); // Vent til knappen slippes set_alarm = 0; // stopp innstillingen av alarmverdien }
Hvis brukeren har trykket på den midterste knappen, betyr det at han prøver å stille alarmtiden. I dette tilfellet går programmet inn i alarminnstillingsmodus ved hjelp av koden ovenfor. Inne i alarminnstillingsmodus hvis brukeren trykker på venstre eller høyre knapp, betyr det at vi må flytte markøren til venstre eller høyre. For å gjøre dette øker vi bare verdien av posisjonen der markøren må plasseres
hvis (LB == 0) {// Hvis venstre knapp trykkes mens (! LB); // Vent til knappen slippes pos--; // Flytt deretter markøren til venstre } hvis (RB == 0) {// Hvis høyre knapp trykkes mens (! RB); // Vent til knappen slippes pos ++; // Flytt markøren til høyre }
Mens du bruker en trykknapp med en mikrokontroller eller mikroprosessor, er det et vanlig problem å takle. Dette problemet kalles bryterhopp. Når du trykker på knappen, kan det gi støyende impulser til MCU / MPU som kan falske MCU for flere oppføringer. Dette problemet kan løses ved å legge til en kondensator over bryteren eller ved å bruke en forsinkelsesfunksjon så snart knappetrykket oppdages. Denne typen løsninger kalles avsprette. Her har vi brukt en stund- loop for å holde programmet på plass til knappen slippes. Dette er ikke den beste løsningen, men for oss vil den fungere helt fint.
mens (! RB);
I likhet med venstre og høyre knapp har vi også de øvre og nedre knappene som kan brukes til å øke eller redusere verdien av alarmtid. Koden for å gjøre det samme er vist nedenfor. Legg merke til at hvert tegn i den innstilte alarmtiden adresseres av indeksverdien til matrisen. Dette var at vi enkelt kan få tilgang til ønsket tegn hvis verdier må endres.
hvis (UB == 0) {// Hvis øvre knapp trykkes mens (! UB); // Vent til knappen slippes alarm_val ++; // Øk den spesielle røyeverdien } hvis (BB == 0) {// Hvis nedre knapp trykkes mens (! UB); // Vent til knappen slippes alarm_val--; // Reduser den aktuelle røyeverdien }
Når alarmtiden er innstilt, vil brukeren trykke på den midterste knappen igjen. Da kan vi begynne å sammenligne gjeldende tid med den angitte tiden. Sammenligningen ved å sjekke om hvert enkelt tegn i gjeldende tid er lik karakteren til den angitte tiden. Hvis verdiene er like, utløser vi alarmen ved å sette trigger_alarm- variabelen ellers sammenligner vi bare til den blir lik.
// HVIS alarm er satt Sjekk om den innstilte verdien er lik gjeldende verdi hvis (set_alarm == 0 && alarm_val == hour_1 && alarm_val == hour_0 && alarm_val == min_1 && alarm_val == min_0) trigger_alarm = 1; // Slå på utløseren hvis verdien samsvarer
Hvis alarmen er innstilt, må vi pippe lyden for å varsle brukeren om alarm. Dette kan gjøres ved å bare bytte summeren med jevne mellomrom som vist nedenfor.
if (trigger_alarm) {// Hvis alarm utløses // Piper summeren BUZZ = 1; __forsink_ms (500); BUZZ = 0; __forsink_ms (500); }
Simulering:
Dette programmet kan også simuleres ved hjelp av proteus-programvaren. Bare opprett kretsen som er vist ovenfor, og last inn hex-filen i PIC. Hex-koden for dette prosjektet finner du i ZIP-filen som er lenket her. Et skjermbilde tatt under simuleringen er vist nedenfor
Simuleringen blir veldig nyttig når du prøver å legge til nye funksjoner i prosjektet. Du kan også bruke I2C feilsøkingsmodulen for å sjekke hvilke data som kommer inn og kommer ut gjennom I2C-bussen. Du kan prøve å trykke på knappene og også stille inn alarmtid. Når den innstilte tiden er lik gjeldende tid, vil summeren gå høyt.
Arbeid med digital vekkerklokke ved bruk av PIC16F877A:
Bygg kretsen på brødplaten, få koden fra nedlastningskoblingen og kompiler den ved hjelp av MplabX og XC8 kompilator. Hvis du har lastet ned koden fra ZIP-filen som er gitt her, bør du ikke ha noe problem med å kompilere den siden topptekstfilene allerede er vedlagt.
Etter å ha samlet, last opp programmet til maskinvaren din ved hjelp av PicKit3-programmereren. Forbindelsen for å koble pickit-programmereren til PIC IC er også vist i kretsskjemaet. Etter at programmet er lastet opp, bør du se introskjermen, og deretter tiden som vises, kan du bruke trykknappene til å stille inn alarmtid. Maskinvareoppsettet mitt når det er strøm, ser slik ut nedenfor.
Når alarmtiden samsvarer med gjeldende tid, vil summeren begynne å pippe for å alarmere brukeren. Komplett arbeid finner du i videoen nedenfor. Prosjektet har en mengde muligheter å bygge på. RTC-modulen kan holde oversikt over hvilket som helst tidspunkt og dato, slik at du kan utføre en planlagt oppgave når som helst. Du kan også koble til et vekselstrømsapparat som en vifte eller lys og planlegge at det skal slås PÅ eller AV når det er nødvendig. Det er fortsatt mye mer du kan bygge videre på dette prosjektet. Gi meg beskjed om hvilken idé du kommer til å tenke på som en oppgradering til dette prosjektet, og jeg vil gjerne høre fra deg.
Håper du forsto prosjektet og lærte noe nyttig fra prosessen. Hvis du er i tvil i dette prosjektet, bruk kommentarseksjonen til å legge dem ut, eller bruk forumene for teknisk hjelp.
Komplett PIC-kode med headerfiler finner du her