- Material som krävs:
- Förutsättningar:
- Kretsschema:
- Programmering för väckarklocka:
- Simulering:
- Arbeta med digital väckarklocka med PIC16F877A:
Den digitala revolutionen som startade 1950 förändrade alla befintliga mekaniska och analoga elektroniska strukturer till digitala datorer. Eftersom tillväxten av digital elektronik har varit exponentiell är det idag nästan omöjligt för en person att motstå att använda någon elektronisk utrustning. Från och med väckarklockan som väcker dig och brödrosten som serverar frukost, är allt ett bidrag från digital elektronik. Med tanke på alla dessa är det verkligen spännande att programmera våra egna saker som kan göra enkla men ändå användbara uppgifter, som väckarklockan som vi ska bygga i detta projekt med PIC Microcontroller. Vi har tidigare byggt väckarklocka med andra mikrokontroller:
- Raspberry Pi väckarklocka med RTC-modul DS1307
- Arduino-baserad digital klocka med larm
- Väckarklocka med ATmega32 Microcontroller
Denna väckarklocka har en 16x2 LCD-display som visar aktuell tid och inställd tid. Vi använder några tryckknappar för att ställa in alarmtiden när det behövs. Den aktuella tiden kommer att hållas i spår med DS3231 RTC-modulen och vi kommer att använda IIC-kommunikation för att hämta dessa värden från RTC-modulen. Vi har redan lärt oss om RTC-modulen och hur man gränssnitt den med PIC. Så det rekommenderas att du läser igenom den självstudien, vi kommer att hoppa över det mesta av informationen i den självstudien.
Material som krävs:
- Brödbräda - 2Nr
- PIC16F877A
- 5V strömkälla - Matningsmodul
- 20 MHz kristall
- 33pf kondensator - 2Nos
- DS3231 RTC-modul
- 16 * 2 LCD-skärmmodul
- 10K POT
- 10k och 1K motstånd
- Tryckknappar - 5Nr
- Summer
- Anslutande ledningar
Förutsättningar:
Detta projekt kräver att du känner till några grunder om PIC-mikrokontrollern och hur du programmerar den. Vi kommer att använda GPIO, LCD-skärm och RTC-modul för detta projekt. Så det är bättre att lära sig att använda dessa moduler i förväg. Följande länkar hjälper dig att lära dig samma sak
- Skriva ditt första program med PIC Microcontroller
- Gränssnitts LCD med PIC
- I2C-kommunikation med PIC
- DS3231 RTC-gränssnitt med PIC
Kretsschema:
Kretsschemat för detta PIC-baserade väckarklockaprojekt visas nedan, som skapades med proteus-programvaran. Den kommer också att användas för simulering vidare i detta projekt.
De fem tryckknapparna fungerar som en ingång för att ställa in larmet under önskad tid. Så den ena änden av alla tryckknappar är ansluten till jord och de andra ändarna är anslutna till PORTB-stift, internt uppdragningsmotstånd kommer att användas på dessa stift för att undvika att stiften flyter. Summern fungerar som en utgång och ger oss ett pip när larmet utlöses och är anslutet till PORT S-stiftet. Den aktuella tiden hålls alltid i spår av DS3231 RTC-modulen från vilken PIC tar emot data via I2C-buss, så SCL- och SDA-stiften på RTC-modulen ansluts till SCL och SDA-stift på PIC-styrenheten. En LCD-skärm är ansluten till PORTD på PIC som används för att visa aktuell tid och inställd tid. Läs mer om hur du använder DS3231 RTC-modul med PIC här.
Hela kretsen kan byggas över en brödbräda. Eftersom det finns några dussin ledningar att ansluta så ha bara tålamod och se till att anslutningarna är korrekta. Min hårdvaruuppsättning såg ut så här nedan när jag var klar med anslutningarna
Jag har använt en breadboard-modul och 12V-adapter för att driva modulen. Detta är min källa till + 5V matningsspänning. Jag måste också använda två brödbrädor för att hålla kretsen ren. Du kan också löda hela kretsen till ett perfekt kort om du vill göra ett mer robust projekt.
Programmering för väckarklocka:
Det fullständiga PIC-programmet för detta väckarklockaprojekt finns längst ner på denna sida. Detta projekt kräver också tre bibliotek för att använda LCD, I2C och RTC med PIC. Den fullständiga koden med rubrikfiler kan laddas ner från ZIP-filen här och kan öppnas med MPLABX efter extrahering. Längre nedan förklarar jag bara huvudfilen som små utdrag. Du kan falla tillbaka till ovanstående handledning om du vill veta hur rubrikfilerna fungerar.
Innan vi går in i huvudprogrammet måste vi definiera stiften som vi har använt med mer meningsfullt namn. På så sätt blir det enkelt att använda dem under programmeringen. Stiften som definieras i vårt program visas nedan
// Definiera LCD-stift # definiera RS RD2 // Återställ stift på LCD # definiera EN RD3 // Aktivera stift på LCD # definiera D4 RD4 // Databit 0 på LCD # definiera D5 RD5 // Databit 1 på LCD # definiera D6 RD6 // Databit 2 på LCD # definiera D7 RD7 // Databit 3 på LCD // Definiera knappar # definiera MB RB1 // Mittknappen # definiera LB RB0 // Vänster knapp # definiera RB RB2 // Höger knapp # definiera UB RB3 // Övre knapp #definiera BB RB4 // Nedre knapp // Definiera Buzz # definiera BUZZ RD1 // Summer är ansluten till RD1
Inne i huvudfunktionen vi börjar med att förklara ingångs- och utgångsstift. I vårt projekt används PORTB för tryckknappar som är en ingångsenhet så vi ställer in deras stift som ingångar och PORTD används för LCD och summer så vi ställer in deras stift som Output. Ett stift ska aldrig lämnas flytande, vilket betyder att I / O-stiften alltid ska anslutas till antingen jord eller till + 5V-spänningen. I vårt fall för tryckknapparna kommer stiften inte att vara anslutna till någonting när knappen inte trycks in, så vi använder ett internt uppdragsmotstånd som sätter stiftet till High när det inte används. Detta görs med hjälp av kontrollregistret enligt nedan
TRISD = 0x00; // Gör port D-stift som outptu för LCD-gränssnitt TRISB = 0xFF; // Omkopplare deklareras som ingångsstift OPTION_REG = 0b00000000; // Aktivera pull up Resistor på port B för switchar BUZZ = 0; // Vänd på summer
Eftersom vi har LCD- och I2C-huvudfilen kopplad till huvudprogrammet kan vi starta LCD-initialiseringen genom att anropa en enkel funktion. Samma sak kan också göras för I2C-initialisering. Här startar vi I2C-kommunikationen vid 100 kHz eftersom RTC-modulen fungerar med 100 kHz.
Lcd_Start (); // Initiera LCD-modul I2C_Initialize (100); // Initiera I2C Master med 100KHz klocka
Funktionen nedan används för att ställa in tid och datum på RTC-modulen, när tid och datum har ställts in tar du bort denna rad. Annars varje gång du startar programmet kommer tid och datum att ställas in om och om igen
// Ta bort under linje när tid och datum är satt för första gången. Set_Time_Date (); // ställa in tid och datum på RTC-modulen
För att indikera att programmet startar visar vi en liten introduktionsskärm som visar projektets namn och webbplatsens namn som visas nedan
// Ge ett introduktionsmeddelande 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"); __fördröja_ms (1500);
Nästa inuti while- slingan måste vi läsa aktuell tid och datum från RTC-modulen, detta kan göras genom att bara ringa nedanstående funktion.
Update_Current_Date_Time (); // Läs aktuellt datum och tid från RTC-modulen
Om du ringer till ovanstående funktion uppdateras variablerna sek, min och timme med det aktuella värdet. För att visa dem på LCD-skärmen måste vi dela upp dem i enskilda tecken med hjälp av koden nedan.
// 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;
Därefter uppdaterar vi värdena över LCD-skärmen. Den aktuella tiden visas på den första raden och den inställda tiden då alarmet måste utlösas visas på den andra raden. Koden som gör detsamma visas nedan.
// Visa aktuell tid på LCD-skärmen 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'); // Visa datum 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 visat tiden och ställt in tiden på LCD: n, vi måste kontrollera om användaren försöker ställa in alarmtiden. För att göra detta måste användaren trycka på mittknappen, så vi kontrollerar om mittknappen trycks in och växlar en variabel för att gå in i alarminställningsläge. Samma knapp kommer att tryckas igen för att bekräfta att värdena är inställda och i så fall måste vi komma ur larminställningsläget. Så vi använder nedanstående kodrad för att ändra status för variabeln set_alarm .
// Använd mittknappen för att kontrollera om alarm måste ställas in om (MB == 0 && set_alarm == 0) {// Om mittknappen trycks in och alarmet inte är påslaget medan (! MB); // Vänta tills knappen släpps set_alarm = 1; // börja ställa in alarmvärde } om (MB == 0 && set_alarm == 1) {// Om mittknappen trycks in och alarmet inte stängs av medan (! MB); // Vänta tills knappen släpps set_alarm = 0; // sluta ställa in alarmvärde }
Om användaren har tryckt på mittknappen betyder det att han försöker ställa in alarmtiden. I detta fall går programmet in i larminställningsläge med koden ovan. Inom alarminställningsläget om användaren trycker på vänster eller höger knapp betyder det att vi måste flytta markören åt vänster eller höger. För att göra detta ökar vi helt enkelt minskningen av positionens värde där markören måste placeras
if (LB == 0) {// Om vänster knapp trycks in medan (! LB); // Vänta tills knappen släpps pos--; // Flytta sedan markören till vänster } om (RB == 0) {// Om höger knapp trycks ned medan (! RB); // Vänta tills knappen släpps pos ++; // Flytta markören till höger }
När du använder en tryckknapp med en mikrokontroller eller mikroprocessor finns det ett vanligt problem att ta itu med. Detta problem kallas brytare studsande. Det är när knappen trycks in kan det ge bullriga pulser till MCU / MPU som kan förfalska MCU för flera poster. Detta problem kan lösas genom att lägga till en kondensator över strömbrytaren eller genom att använda en fördröjningsfunktion så snart knapptrycket upptäcks. Denna typ av lösning kallas avstängning. Här har vi använt en stund slinga för att hålla programmet på plats tills knappen släpps. Detta är inte den bästa lösningen för studsande, men för oss kommer det att fungera bra.
medan (! RB);
På samma sätt som vänster och höger knapp har vi även de övre och nedre knapparna som kan användas för att öka eller minska värdet på alarmtiden. Koden för att göra detsamma visas nedan. Observera att varje tecken i den inställda larmtiden adresseras av matrisens indexvärde. Detta var att vi enkelt kan komma åt den önskade karaktären vars värden måste ändras.
if (UB == 0) {// Om den övre knappen trycks in medan (! UB); // Vänta tills knappen släpps alarm_val ++; // Öka det specifika teckenvärdet } om (BB == 0) {// Om den nedre knappen trycks ned medan (! UB); // Vänta tills knappen släpps alarm_val--; // Minska det specifika rödvärdet }
När alarmtiden är inställd kommer användaren att trycka på mittknappen igen. Då kan vi börja jämföra den aktuella tiden med den inställda tiden. Jämförelsen genom att kontrollera om varje enskilt tecken i aktuell tid är lika med den inställda tidens karaktär. Om värdena är lika utlöser vi alarmet genom att ställa in trigger_alarm- variabeln, annars jämför vi bara tills det blir lika.
// OM larm är inställt Kontrollera om inställt värde är lika med aktuellt värde om (set_alarm == 0 && alarm_val == hour_1 && alarm_val == hour_0 && alarm_val == min_1 && alarm_val == min_0) trigger_alarm = 1; // Slå på avtryckaren om värdet matchar
Om larmet är inställt måste vi pipa summern för att varna användaren om larm. Detta kan göras genom att helt enkelt växla summern med ett regelbundet intervall som visas nedan.
if (trigger_alarm) {// Om larm utlöses // Pip summern BUZZ = 1; __fördröja_ms (500); BUZZ = 0; __fördröja_ms (500); }
Simulering:
Detta program kan också simuleras med proteus-programvaran. Skapa bara kretsen som visas ovan och ladda hex-filen i PIC. Hexkoden för detta projekt finns i ZIP-filen som är länkad här. En skärmdump som tagits under simuleringen visas nedan
Simuleringen blir mycket användbar när du försöker lägga till nya funktioner i projektet. Du kan också använda I2C-felsökningsmodulen för att kontrollera vilka data som går in och kommer ut genom I2C-bussen. Du kan försöka trycka på knapparna och också ställa in alarmtiden. När den inställda tiden är lika med den aktuella tiden kommer summern att bli hög.
Arbeta med digital väckarklocka med PIC16F877A:
Bygg kretsen på panelen, hämta koden från nedladdningslänken och kompilera den med MplabX- och XC8-kompilatorn. Om du har laddat ner koden från ZIP-filen som tillhandahålls här, borde du inte ha några problem att kompilera den eftersom rubrikfilerna redan är bifogade.
Efter att ha kompilerat, ladda upp programmet till din hårdvara med PicKit3-programmeraren. Anslutningen för att ansluta pickit-programmeraren till PIC IC visas också i kretsschemat. Efter att programmet har laddats upp ska du se introduktionsskärmen och sedan den tid som visas kan du sedan använda tryckknapparna för att ställa in alarmtiden. Min hårdvaruuppsättning när den drivs ser ut så här nedan.
När larmtiden överensstämmer med den aktuella tiden kommer summern att börja pipa för att larma användaren. Hela arbetet hittar du i videon nedan. Projektet har en mängd alternativ att bygga på. RTC-modulen kan hålla koll på valfri tid och datum, så att du kan utföra en schemalagd uppgift när som helst / datum som krävs. Du kan också ansluta en AC-apparat som en fläkt eller lampa och schemalägga att den ska PÅ eller AV när det behövs. Det finns fortfarande mycket mer du kan bygga på det här projektet, låt mig veta vilken idé du kommer att tänka på som en uppgradering till det här projektet och jag hör gärna av dig.
Hoppas att du förstod projektet och lärde dig något användbart från processen. Om du är osäker på det här projektet, använd kommentarsektionen för att lägga upp dem eller använd forumen för teknisk hjälp.
Komplett PIC-kod med rubrikfiler finns här