Dit is onze 9e tutorial over het leren van PIC-microcontrollers met MPLAB en XC8. Tot nu toe hebben we veel eenvoudige tutorials behandeld, zoals aan de slag gaan met MPLABX, LED knipperen met PIC, Timers in PIC, interfacing LCD, interfacing 7-segment etc. Als je een absolute beginner bent, bezoek dan de volledige lijst met PIC-tutorials hier en begin met leren.
In deze tutorial leren we hoe we ADC kunnen gebruiken met onze PIC-microcontroller PICF877A. Bij de meeste Microcontroller-projecten is er een ADC (analoog naar digitaal converter) in betrokken, omdat dit een van de meest gebruikte manieren is om gegevens uit de echte wereld te lezen. Bijna alle sensoren zoals temperatuursensor, fluxsensor, druksensor, stroomsensoren, spanningssensoren, gyroscopen, versnellingsmeters, afstandssensor en bijna elke bekende sensor of transducer produceert een analoge spanning van 0V tot 5V op basis van de aflezing van de sensoren. Een temperatuursensor kan bijvoorbeeld 2,1V afgeven bij een temperatuur van 25 ° C en tot 4,7 V bij een temperatuur van 60 ° C. Om de temperatuur van de echte wereld te kennen, hoeft de MCU alleen de uitgangsspanning van deze temperatuursensor af te lezen en deze te relateren aan de werkelijke temperatuur. Daarom is ADC een belangrijk werkinstrument voor MCU-projecten en laten we zien hoe we het kunnen gebruiken op onze PIC16F877A.
Bekijk ook onze vorige artikelen over het gebruik van ADC in andere microcontrollers:
- Hoe ADC te gebruiken in Arduino Uno?
- Raspberry Pi ADC-zelfstudie
- Koppeling tussen ADC0808 met 8051 Microcontroller
ADC in PIC Microcontroller PIC16F877A:
Er zijn veel soorten ADC beschikbaar en elk heeft zijn eigen snelheid en resolutie. De meest voorkomende typen ADC's zijn flash, opeenvolgende benadering en sigma-delta. Het type ADC dat in PIC16F877A wordt gebruikt, wordt de opeenvolgende benadering ADC of afgekort SAR genoemd. Dus laten we wat meer leren over SAR ADC voordat we het gaan gebruiken.
Opeenvolgende benadering ADC: De SAR ADC werkt met behulp van een comparator en enkele logische gesprekken. Dit type ADC gebruikt een referentiespanning (die variabel is) en vergelijkt de ingangsspanning met de referentiespanning met behulp van een comparator en het verschil, dat een digitale uitgang zal zijn, wordt opgeslagen uit de meest significante bit (MSB). De snelheid van de vergelijking is afhankelijk van de klokfrequentie (Fosc) waarop de PIC werkt.
Nu we wat basiskennis over ADC kennen, kunnen we onze datasheet openen en leren hoe we de ADC op onze PIC16F877A MCU kunnen gebruiken. De PIC die we gebruiken heeft 10-bit 8-kanaals ADC. Dit betekent dat de outputwaarde van onze ADC 0-1024 (2 ^ 10) zal zijn en dat er 8 pinnen (kanalen) op onze MCU zijn die analoge spanning kunnen lezen. De waarde 1024 wordt verkregen door 2 ^ 10 aangezien onze ADC 10 bit is. De acht pinnen die de analoge spanning kunnen aflezen staan vermeld in de datasheet. Laten we naar de onderstaande afbeelding kijken.
De analoge kanalen AN0 tot AN7 worden voor u uitgelicht. Alleen deze pinnen kunnen analoge spanning lezen. Dus voordat we een ingangsspanning lezen, moeten we in onze code aangeven welk kanaal moet worden gebruikt om de ingangsspanning te lezen. In deze tutorial zullen we kanaal 4 gebruiken met een potentiometer om de analoge spanning op dit kanaal af te lezen.
De A / D-module heeft vier registers die moeten worden geconfigureerd om gegevens van de invoerpinnen te lezen. Deze registers zijn:
• A / D-resultaat hoog register (ADRESH)
• A / D-resultaat laag register (ADRESL)
• A / D-besturingsregister 0 (ADCON0)
• A / D-besturingsregister 1 (ADCON1)
Programmering voor ADC:
Het programma voor het gebruik van ADC met PIC Microcontroller is heel eenvoudig, we hoeven alleen maar deze vier registers te begrijpen en dan is het lezen van elke analoge spanning eenvoudig. Initialiseer zoals gewoonlijk de configuratiebits en laten we beginnen met de leegte main ().
Binnen de void main () moeten we onze ADC initialiseren met behulp van het ADCON1-register en het ADCON0-register. Het ADCON0-register heeft de volgende bits:
In dit register moeten we de ADC-module aanzetten door ADON = 1 te maken en de A / D Conversion Clock aanzetten door de bits ADCS1 en ADCS0 bits te gebruiken, de rest wordt voorlopig niet gezet. In ons programma is de A / D-conversieklok geselecteerd als Fosc / 16, je kunt je eigen frequenties proberen en zien hoe het resultaat verandert. Volledige details beschikbaar op pagina 127 van de datasheet. Daarom zal ADCON0 als volgt worden geïnitialiseerd.
ADCON0 = 0b01000001;
Nu heeft het ADCON1-register de volgende bits:
In dit register moeten we A / D Result Format Select bit hoog maken bij ADFM = 1 en ADCS2 = 1 maken om de Fosc / 16 opnieuw te selecteren. De andere bits blijven nul omdat we van plan zijn de interne referentiespanning te gebruiken. Volledige details beschikbaar op datasheet pagina 128. Daarom zullen we ADCON1 als volgt instellen.
ADCON1 = 0x11000000;
Nu, na het initialiseren van de ADC-module in onze hoofdfunctie, gaan we naar de while-lus en beginnen we met het lezen van de ADC-waarden. Om een ADC-waarde te lezen, moeten de volgende stappen worden gevolgd.
- Initialiseer de ADC-module
- Selecteer het analoge kanaal
- Start ADC door Go / Done een beetje hoog te maken
- Wacht tot het Go / DONE-bit laag is
- Haal het ADC-resultaat op uit het ADRESH- en ADRESL-register
1. Initialiseer de ADC-module: we hebben al geleerd hoe we een ADC moeten initialiseren, dus we noemen deze onderstaande functie om de ADC te initialiseren
De ongeldige ADC_Initialize () -functie is als volgt.
ongeldig ADC_Initialize () {ADCON0 = 0b01000001; // ADC ON en Fosc / 16 is geselecteerd ADCON1 = 0b11000000; // Interne referentiespanning is geselecteerd}
2. Selecteer het analoge kanaal: Nu moeten we selecteren welk kanaal we gaan gebruiken om de ADC-waarde te lezen. Laten we hier een functie voor maken, zodat we gemakkelijk kunnen schakelen tussen elk kanaal binnen de while- lus.
unsigned int ADC_Read (unsigned char channel) {// **** Het kanaal selecteren ** /// ADCON0 & = 0x11000101; // Wissen van de kanaalselectiebits ADCON0 - = kanaal << 3; // De vereiste bits instellen // ** Kanaalselectie voltooid *** ///}
Het te selecteren kanaal wordt binnen het variabele kanaal ontvangen. In de rij
ADCON0 & = 0x1100101;
De vorige kanaalselectie (indien aanwezig) wordt gewist. Dit wordt gedaan door de bitwise en operator “&” te gebruiken. De bits 3, 4 en 5 worden gedwongen 0 te zijn, terwijl de andere in hun vorige waarden blijven staan.
Vervolgens wordt het gewenste kanaal geselecteerd door het kanaalnummer driemaal naar links te verschuiven en de bits in te stellen met de bitsgewijze of operator "-".
ADCON0 - = kanaal << 3; // De vereiste bits instellen
3. Start ADC door Go / Done bit hoog te maken: Zodra het kanaal is geselecteerd, moeten we de ADC-conversie starten door simpelweg GO_nDONE bit hoog te maken:
GO_nDONE = 1; // Initialiseert A / D-conversie
4. Wacht tot de Go / DONE-bit laag wordt: De GO / DONE-bit blijft hoog totdat de ADC-conversie is voltooid, daarom moeten we wachten tot deze bit weer laag wordt. Dit kan gedaan worden door een while- lus te gebruiken.
terwijl (GO_nDONE); // Wacht tot de A / D-conversie is voltooid
5. Haal het ADC-resultaat op uit het ADRESH- en ADRESL-register: Als de Go / DONE-bit weer laag wordt, betekent dit dat de ADC-conversie is voltooid. Het resultaat van de ADC is een 10-bits waarde. Omdat onze MCU een 8-bits MCU is, wordt het resultaat opgesplitst in de bovenste 8-bits en de onderste 2-bits. Het bovenste 8-bit resultaat wordt opgeslagen in het register ADRESH en het onderste 2-bit wordt opgeslagen in het register ADRESL. Daarom moeten we deze bij de registers optellen om onze 10-bits ADC-waarde te krijgen. Dit resultaat wordt geretourneerd door de functie zoals hieronder weergegeven:
terug ((ADRESH << 8) + ADRESL); // Retourneert resultaat
De volledige functie die wordt gebruikt om het ADC-kanaal te selecteren, de ADC te activeren en het resultaat te retourneren, wordt hier weergegeven.
unsigned int ADC_Read (unsigned char channel) {ADCON0 & = 0x11000101; // Wissen van de kanaalselectiebits ADCON0 - = kanaal << 3; // De vereiste bits instellen __delay_ms (2); // Verwervingstijd om de houdcondensator GO_nDONE = 1 te laden; // Initialiseert A / D-conversie terwijl (GO_nDONE); // Wacht tot A / D-conversie om de retour te voltooien ((ADRESH << 8) + ADRESL); // Retourneert resultaat}
Nu hebben we een functie die de kanaalselectie als invoer neemt en ons de ADC-waarde retourneert. Daarom kunnen we deze functie rechtstreeks binnen onze while- lus aanroepen, aangezien we de analoge spanning van kanaal 4 in deze tutorial lezen, zal de functieaanroep als volgt zijn.
i = (ADC_Read (4)); // sla het resultaat van adc op in "i".
Om de output van onze ADC te visualiseren, hebben we een soort displaymodules nodig, zoals de LCD of het 7-segment. In deze tutorial gebruiken we een 7-segment display om de output te verifiëren. Als je wilt weten hoe je 7-segment met foto gebruikt, volg dan de tutorial hier.
De volledige code wordt hieronder gegeven en het proces wordt aan het einde ook uitgelegd in de video.
Hardware instellen en testen:
Zoals gewoonlijk simuleer je de code met Proteus voordat je daadwerkelijk met onze hardware meegaat, het schema van het project wordt hieronder weergegeven:
Verbindingen van de 4-cijferige displaymodule met zeven segmenten met PIC-microcontroller zijn hetzelfde als het vorige project, we hebben zojuist een potentiometer toegevoegd aan pin 7, het analoge kanaal 4. Door de pot te variëren, wordt een variabele spanning naar de MCU gestuurd die wordt gelezen door de ADC-module en weergegeven op de 7-segment display Module. Bekijk de vorige tutorial voor meer informatie over een 4-cijferig 7-segment display en de interface met PIC MCU.
Hier hebben we hetzelfde PIC Microcontroller-bord gebruikt dat we hebben gemaakt in de LED-knipperende zelfstudie. Na het verzekeren van de verbinding, upload het programma naar PIC en je zou een output als deze moeten zien
Hier hebben we de ADC-waarde uit de pot gelezen en geconverteerd naar de werkelijke spanning door de 0-1024-uitgang in kaart te brengen als 0-5 volt (zoals weergegeven in het programma). De waarde wordt vervolgens weergegeven op het 7-segment en geverifieerd met de multimeter.
Dat is het, nu zijn we klaar om alle analoge sensoren op de markt te gebruiken, ga je gang en probeer dit en als je zoals gewoonlijk problemen hebt, gebruik dan het commentaargedeelte, we helpen je graag verder.