- Vereiste materialen:
- Voorwaarden:
- Schakelschema:
- Programmering voor wekker:
- Simulatie:
- Werking van digitale wekker met behulp van PIC16F877A:
De digitale revolutie die in 1950 begon, verandert alle bestaande mechanische en analoge elektronische structuren in digitale computers. Aangezien de groei van digitale elektronica exponentieel is geweest, is het tegenwoordig bijna onmogelijk voor een persoon om weerstand te bieden aan het gebruik van elektronische apparatuur. Te beginnen met de wekker die je wakker maakt en de broodrooster die je ontbijt serveert, alles is een bijdrage van digitale elektronica. Als we aan al deze dingen denken, is het echt opwindend om onze eigen dingen te programmeren die eenvoudige maar nuttige taken zouden kunnen uitvoeren, zoals de wekker die we in dit project gaan bouwen met PIC Microcontroller. We hebben eerder een wekker gebouwd met andere microcontrollers:
- Raspberry Pi-wekker met RTC-module DS1307
- Arduino gebaseerde digitale klok met alarm
- Wekker met ATmega32 Microcontroller
Deze wekker heeft een 16x2 LCD-display waarop de huidige tijd en de ingestelde tijd worden weergegeven. We zullen een paar drukknoppen gebruiken om de alarmtijd in te stellen wanneer dat nodig is. De huidige tijd wordt bijgehouden met behulp van de DS3231 RTC-module en we zullen IIC-communicatie gebruiken om deze waarden uit de RTC-module te halen. We hebben al geleerd over de RTC-module en hoe deze met PIC te communiceren. Het wordt dus aanbevolen om die tutorial door te lezen, we zullen de meeste informatie die in die tutorial wordt behandeld overslaan.
Vereiste materialen:
- Broodplank - 2 nrs
- PIC16F877A
- 5V stroombron - voedingsmodule
- 20 MHz kristal
- 33pf condensator - 2 nrs
- DS3231 RTC-module
- 16 * 2 LCD-weergavemodule
- 10K POT
- 10k en 1K weerstand
- Drukknoppen - 5 nrs
- Zoemer
- Draden aansluiten
Voorwaarden:
Dit project vereist dat u enkele basiskennis over de PIC-microcontroller kent en hoe u deze programmeert. We zullen GPIO's, LCD-scherm en RTC-module gebruiken voor dit project. Het is dus beter om van tevoren te leren hoe u deze modules kunt gebruiken. De volgende links zullen u helpen hetzelfde te leren
- Je eerste programma schrijven met PIC Microcontroller
- Interfaces LCD met PIC
- I2C-communicatie met behulp van PIC
- DS3231 RTC-interface met PIC
Schakelschema:
Het schakelschema voor dit op PIC gebaseerde wekkerproject wordt hieronder weergegeven, dat is gemaakt met behulp van de proteus-software. Het zal ook worden gebruikt voor simulatie verderop in dit project.
De vijf druktoetsen fungeren als input voor het instellen van het alarm voor de gewenste tijd. Dus het ene uiteinde van alle drukknoppen is verbonden met aarde en de andere uiteinden zijn verbonden met de PORTB-pin, een interne pull-up-weerstand wordt op deze pinnen gebruikt om te voorkomen dat de pinnen zweven. De zoemer fungeert als uitgang en geeft een pieptoon wanneer het alarm wordt geactiveerd en is verbonden met de PORT S-pin. De huidige tijd wordt altijd bijgehouden door de DS3231 RTC-module waarvan de PIC de gegevens ontvangt via de I2C-bus, dus de SCL- en SDA-pinnen van de RTC-module zijn verbonden met de SCL- en SDA-pin van de PIC-controller. Aan de PORTD van de PIC is een LCD-scherm bevestigd dat wordt gebruikt om de huidige tijd en de ingestelde tijd weer te geven. Lees hier meer over het gebruik van de DS3231 RTC-module met PIC.
Het volledige circuit kan over een breadboard worden gebouwd. Aangezien er een paar dozijn draden zijn om aan te sluiten, dus heb geduld en zorg ervoor dat de verbindingen correct zijn. Mijn hardware-installatie zag er hieronder ongeveer zo uit toen ik klaar was met de verbindingen
Ik heb een breadboard-module en een 12V-adapter gebruikt om de module van stroom te voorzien. Dit is mijn bron van + 5V voedingsspanning. Ook moet ik twee breadboards gebruiken om het circuit schoon te houden. Je kunt ook het hele circuit op een perf-board solderen als je een robuuster project wilt maken.
Programmering voor wekker:
Het volledige PIC-programma voor dit Alarm Clock-project vindt u onderaan deze pagina. Dit project vereist ook drie bibliotheken voor het gebruik van LCD, I2C en RTC met PIC. De volledige code met header-bestanden kan hier worden gedownload vanuit het ZIP-bestand en kan na het uitpakken worden geopend met MPLABX. Verderop leg ik het belangrijkste c-bestand alleen uit als kleine fragmenten. U kunt terugvallen op de hierboven genoemde tutorials als u wilt weten hoe de headerbestanden werken.
Voordat we naar het hoofdprogramma gaan, moeten we de pinnen definiëren die we hebben gebruikt met een meer betekenisvolle naam. Op deze manier zijn ze gemakkelijk te gebruiken tijdens het programmeren. De pinnen die in ons programma zijn gedefinieerd, worden hieronder weergegeven
// Definieer de LCD-pinnen #define RS RD2 // Reset pin van LCD #define EN RD3 // Activeer pin van LCD #define D4 RD4 // Data bit 0 van LCD #define D5 RD5 // Data bit 1 van LCD #define D6 RD6 // Data bit 2 van LCD #define D7 RD7 // Data bit 3 van LCD // Define Buttons #define MB RB1 // De middelste knop #define LB RB0 // Linkerknop #define RB RB2 // Rechter knop # definieer UB RB3 // Bovenste knop #define BB RB4 // Onderste knop // Definieer Buzz #define BUZZ RD1 // Zoemer is verbonden met RD1
Binnen de hoofdfunctie beginnen we met het declareren van de invoer- en uitvoerpinnen. In ons project wordt de PORTB gebruikt voor drukknoppen, wat een invoerapparaat is, dus we stellen hun pinnen in als invoer en PORTD wordt gebruikt voor LCD en zoemer, dus we stellen hun pinnen in als uitgang. Ook mag een pin nooit zweven, wat betekent dat de I / O-pinnen altijd moeten worden verbonden met aarde of met de + 5V-spanning. In ons geval voor de drukknoppen worden de pinnen nergens mee verbonden als de knop niet wordt ingedrukt, dus gebruiken we een interne pull-up-weerstand die de pin op hoog zet wanneer deze niet in gebruik is. Dit gebeurt met behulp van de controleregisters zoals hieronder weergegeven
TRISD = 0x00; // Maak poort D-pinnen als uitgang voor LCD-interfacing TRISB = 0xFF; // Schakelaars worden gedeclareerd als invoerpinnen OPTION_REG = 0b00000000; // Schakel de pull- upweerstand in op poort B voor schakelaars BUZZ = 0; // Zet de zoemer uit
Omdat we het LCD- en I2C-headerbestand hebben gekoppeld aan het hoofdprogramma, kunnen we de LCD-initialisatie starten door een eenvoudige functie aan te roepen. Hetzelfde kan ook worden gedaan voor I2C-initialisatie. Hier beginnen we met de I2C-communicatie op 100 kHz, aangezien de RTC-module met 100 kHz werkt.
Lcd_Start (); // Initialiseer LCD-module I2C_Initialize (100); // Initialiseer I2C Master met een klok van 100 kHz
De onderstaande functie wordt gebruikt om de tijd en datum op de RTC-module in te stellen, verwijder deze regel zodra de tijd en datum zijn ingesteld. Anders worden elke keer dat u het programma start, de tijd en datum steeds opnieuw ingesteld
// Verwijder de regel daaronder eenmaal tijd en datum is vastgesteld voor de eerste keer. Set_Time_Date (); // stel tijd en datum in op de RTC-module
Om aan te geven dat het programma aan het opstarten is, tonen we een klein introductiescherm met de naam van het project en de naam van de website zoals hieronder weergegeven
// Geef een introbericht op de LCD Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String ("Wekker"); Lcd_Set_Cursor (2,1); Lcd_Print_String ("-Circuit Digest"); __delay_ms (1500);
Vervolgens moeten we binnen de while- lus de huidige tijd en datum uit de RTC-module lezen, dit kan gedaan worden door gewoon de onderstaande functie aan te roepen.
Update_Current_Date_Time (); // Lees de huidige datum en tijd van de RTC-module
Door de bovenstaande functie aan te roepen, worden de variabelen sec, min en uur bijgewerkt met de huidige waarde. Om ze op het LCD-scherm weer te geven , moeten we ze opsplitsen in afzonderlijke tekens met behulp van de onderstaande code.
// Splits het in char om weer te geven op lcd char sec_0 = sec% 10; char sec_1 = (sec / 10); char min_0 = min% 10; char min_1 = min / 10; char hour_0 = uur% 10; char hour_1 = uur / 10;
Vervolgens werken we de waarden bij via het LCD-scherm. De huidige tijd wordt weergegeven op de eerste regel en de ingestelde tijd waarop het alarm moet worden geactiveerd wordt weergegeven op de tweede regel. De code die hetzelfde doet, wordt hieronder weergegeven.
// Geef de huidige tijd weer op het LCD-scherm Lcd_Clear (); Lcd_Set_Cursor (1, 1); Lcd_Print_String ("TIME:"); Lcd_Print_Char (uur_1 + '0'); Lcd_Print_Char (uur_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'); // Geef de datum weer op het LCD-scherm 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 hebben we de tijd weergegeven en de ingestelde tijd op het LCD-scherm, we moeten controleren of de gebruiker de alarmtijd probeert in te stellen. Om dit te doen, moet de gebruiker op de middelste knop drukken, dus we zullen controleren of de middelste knop is ingedrukt en schakelen tussen een variabele om naar de alarminstellingsmodus te gaan. Dezelfde knop wordt nogmaals ingedrukt om te bevestigen dat de waarden zijn ingesteld en in dat geval moeten we uit de alarminstelmodus komen. Dus gebruiken we de onderstaande regel code om de status van de variabele set_alarm te wijzigen .
// Gebruik de middelste knop om te controleren of het alarm moet worden ingesteld if (MB == 0 && set_alarm == 0) {// Als de middelste knop is ingedrukt en het alarm niet is ingeschakeld terwijl (! MB); // Wacht tot de knop wordt vrijgegeven set_alarm = 1; // begin met het instellen van de alarmwaarde } if (MB == 0 && set_alarm == 1) {// Als de middelste knop is ingedrukt en het alarm niet is uitgeschakeld terwijl (! MB); // Wacht tot de knop wordt losgelaten set_alarm = 0; // stop met instellen van alarmwaarde }
Als de gebruiker op de middelste knop heeft gedrukt, betekent dit dat hij probeert de alarmtijd in te stellen. In dit geval gaat het programma naar de alarminstellingsmodus met behulp van de bovenstaande code. Als de gebruiker in de alarminstellingsmodus op de linker- of rechterknop drukt, betekent dit dat we de cursor naar links of rechts moeten verplaatsen. Om dit te doen, verhogen of verlagen we eenvoudig de waarde van de positie waarop de cursor moet worden geplaatst
if (LB == 0) {// Als de linkerknop wordt ingedrukt terwijl (! LB); // Wacht tot de knop wordt losgelaten pos--; // Verplaats vervolgens de cursor naar links } if (RB == 0) {// Als de rechterknop wordt ingedrukt terwijl (! RB); // Wacht tot de knop wordt vrijgegeven pos ++; // Verplaats cursor naar rechts }
Bij het gebruik van een drukknop met een microcontroller of microprocessor is er één veelvoorkomend probleem dat moet worden aangepakt. Dit probleem wordt switch bouncing genoemd. Dat is wanneer de knop wordt ingedrukt, het kan luidruchtige pulsen geven aan de MCU / MPU die de MCU kunnen vervalsen voor meerdere vermeldingen. Dit probleem kan worden opgelost door een condensator over de schakelaar toe te voegen of door een vertragingsfunctie te gebruiken zodra de druk op de knop wordt gedetecteerd. Dit type oplossing wordt de-bouncing genoemd. Hier hebben we een while- lus gebruikt om het programma op zijn plaats te houden totdat de knop wordt losgelaten. Dit is geen beste de-bouncing-oplossing, maar voor ons werkt het prima.
terwijl (! RB);
Net als de linker- en rechterknop hebben we ook de bovenste en onderste knoppen die kunnen worden gebruikt om de waarde van de alarmtijd te verhogen of te verlagen. De code om hetzelfde te doen, wordt hieronder weergegeven. Merk op dat elk teken van de ingestelde alarmtijd wordt geadresseerd door de indexwaarde van de array. Hierdoor hebben we gemakkelijk toegang tot het vereiste teken waarvan de waarden moeten worden gewijzigd.
if (UB == 0) {// Als de bovenste knop wordt ingedrukt terwijl (! UB); // Wacht tot de knop wordt vrijgegeven alarm_val ++; // Verhoog die specifieke char-waarde } if (BB == 0) {// Als de onderste knop wordt ingedrukt terwijl (! UB); // Wacht tot knop wordt losgelaten alarm_val--; // Verlaag die specifieke tekenwaarde }
Zodra de alarmtijd is ingesteld, drukt de gebruiker opnieuw op de middelste knop. Dan kunnen we beginnen met het vergelijken van de huidige tijd met de ingestelde tijd. De vergelijking door te controleren of elk karakter van de huidige tijd gelijk is aan het karakter van de ingestelde tijd. Als de waarden gelijk zijn, activeren we het alarm door de variabele trigger_alarm in te stellen , anders vergelijken we totdat deze gelijk wordt.
// ALS alarm is ingesteld Controleer of de ingestelde waarde gelijk is aan de huidige waarde if (set_alarm == 0 && alarm_val == hour_1 && alarm_val == hour_0 && alarm_val == min_1 && alarm_val == min_0) trigger_alarm = 1; // Schakel de trigger in als de waarde overeenkomt
Als het alarm is ingesteld, moeten we de zoemer laten piepen om de gebruiker te waarschuwen voor alarm. Dit kan gedaan worden door simpelweg de zoemer in een regelmatig interval te schakelen, zoals hieronder getoond.
if (trigger_alarm) {// Als alarm wordt geactiveerd // Pieptoon de zoemer BUZZ = 1; __delay_ms (500); BUZZ = 0; __delay_ms (500); }
Simulatie:
Dit programma kan ook worden gesimuleerd met behulp van de proteus-software. Maak gewoon het hierboven getoonde circuit opnieuw en laad het hex-bestand in de PIC. De hex-code voor dit project is te vinden bij het ZIP-bestand dat hier naar gelinkt is. Hieronder ziet u een schermafdruk die tijdens de simulatie is gemaakt
De simulatie wordt erg handig wanneer u probeert nieuwe functies aan het project toe te voegen. U kunt ook de I2C-debuggermodule gebruiken om te controleren welke gegevens binnenkomen en naar buiten komen via de I2C-bus. U kunt proberen op de knoppen te drukken en ook de alarmtijd instellen. Als de ingestelde tijd gelijk is aan de huidige tijd, gaat de zoemer hoog.
Werking van digitale wekker met behulp van PIC16F877A:
Bouw het circuit op het breadboard, haal de code op via de downloadlink en compileer het met behulp van MplabX en XC8-compiler. Als u de code uit het hier verstrekte ZIP-bestand hebt gedownload, zou u geen probleem moeten hebben met het compileren ervan, aangezien de header-bestanden al zijn bijgevoegd.
Na het compileren uploadt u het programma naar uw hardware met behulp van de PicKit3-programmeur. De verbinding om de pickit-programmeur aan te sluiten op PIC IC wordt ook weergegeven in het schakelschema. Nadat het programma is geüpload, zou u het introscherm moeten zien en vervolgens de tijd die wordt weergegeven. U kunt vervolgens de druktoetsen gebruiken om de alarmtijd in te stellen. Mijn hardware-instellingen bij stroom zien er als volgt uit.
Wanneer de alarmtijd overeenkomt met de huidige tijd, begint de zoemer te piepen om de gebruiker te alarmeren. De volledige werking is te vinden op de onderstaande video. Het project heeft een overvloed aan opties om op voort te bouwen. De RTC-module kan elke tijd en datum bijhouden, zodat u een geplande taak op elk gewenst moment / datum kunt uitvoeren. U kunt ook een AC-apparaat zoals een ventilator of licht aansluiten en plannen dat het AAN of UIT gaat wanneer dat nodig is. Er is nog veel meer dat je op dit project kunt voortbouwen, laat me weten welk idee in je opkomt als upgrade van dit project en ik hoor graag van je.
Ik hoop dat je het project hebt begrepen en iets nuttigs hebt geleerd van het proces. Als je twijfels hebt over dit project, gebruik dan de commentaarsectie om ze te plaatsen of gebruik de forums voor technische hulp.
Volledige PIC-code met headerbestanden is hier te vinden