Detta är vår 9: e handledning om inlärning av PIC-mikrokontroller med MPLAB och XC8. Hittills har vi täckt många grundläggande handledning som att komma igång med MPLABX, LED blinkar med PIC, Timers i PIC, gränssnitt LCD, gränssnitt 7-segment osv. och börja lära dig.
I den här handledningen lär vi oss hur man använder ADC med vår PIC-mikrokontroller PICF877A. De flesta av Microcontroller-projekten kommer att involvera en ADC (Analog till Digital-omvandlare) i den, eftersom det är ett av de mest använda sätten att läsa data från den verkliga världen. Nästan alla sensorer som temperatursensor, flussensor, trycksensor, strömgivare, spänningssensorer, gyroskop, accelerometrar, avståndssensor och nästan alla kända sensorer eller givare producerar en analog spänning på 0V till 5V baserat på sensornas läsning. En temperatursensor kan till exempel ge ut 2.1V när temperaturen är 25C och gå upp till 4.7 när temperaturen är 60C. För att känna till temperaturen i den verkliga världen måste MCU bara läsa utgångsspänningen för denna temperatursensor och relatera den till den verkliga världstemperaturen. Därför är ADC ett viktigt arbetsverktyg för MCU-projekt och låter oss lära oss hur vi kan använda det på vår PIC16F877A.
Läs också våra tidigare artiklar om användning av ADC i andra mikrokontroller:
- Hur man använder ADC i Arduino Uno?
- Raspberry Pi ADC-handledning
- Gränssnitt ADC0808 med 8051 mikrokontroller
ADC i PIC Microcontroller PIC16F877A:
Det finns många typer av ADC tillgängliga och var och en har sin egen hastighet och upplösning. De vanligaste typerna av ADC är flash, successiv approximation och sigma-delta. Den typ av ADC som används i PIC16F877A kallas kort sagt den successiva approximationen ADC eller SAR. Så låt oss lära oss lite om SAR ADC innan vi börjar använda den.
Successiv approximation ADC: SAR ADC fungerar med hjälp av en komparator och några logiska konversationer. Denna typ av ADC använder en referensspänning (som är variabel) och jämför ingångsspänningen med referensspänningen med hjälp av en komparator och skillnaden, som kommer att vara en digital utgång, sparas från den mest signifikanta biten (MSB). Jämförelsens hastighet beror på klockfrekvensen (Fosc) som PIC arbetar på.
Nu när vi känner till några grunder för ADC, kan vi öppna vårt datablad och lära oss hur man använder ADC på vår PIC16F877A MCU. Den PIC vi använder har 10-bitars 8-kanals ADC. Det betyder att utgångsvärdet för vår ADC kommer att vara 0-1024 (2 ^ 10) och det finns 8 stift (kanaler) på vår MCU som kan läsa analog spänning. Värdet 1024 erhålls av 2 ^ 10 eftersom vår ADC är 10 bitar. De åtta stiften som kan läsa den analoga spänningen nämns i databladet. Låt oss titta på bilden nedan.
De analoga kanalerna AN0 till AN7 är markerade för dig. Endast dessa stift kan läsa analog spänning. Så innan vi läser en ingångsspänning måste vi i vår kod ange vilken kanal som ska användas för att läsa ingångsspänningen. I denna handledning använder vi kanal 4 med en potentiometer för att läsa av den analoga spänningen vid den här kanalen.
A / D-modulen har fyra register som måste konfigureras för att läsa data från ingångsstiften. Dessa register är:
• A / D-resultat högt register (ADRESH)
• A / D-resultat lågt register (ADRESL)
• A / D-kontrollregister 0 (ADCON0)
• A / D-kontrollregister 1 (ADCON1)
Programmering för ADC:
Det program för att använda ADC med PIC Microcontroller är mycket enkel, vi måste bara förstå dessa fyra register och sedan läsa alla analoga spänningen kommer att vara enkla. Initiera som vanligt konfigurationsbitarna och låt oss börja med void main ().
Inuti tomrummet main () måste vi initialisera vår ADC med ADCON1-registret och ADCON0-registret. ADCON0-registret har följande bitar:
I det här registret måste vi slå på ADC-modulen genom att göra ADON = 1 och slå på A / D-omvandlingsklockan med bitarna ADCS1 och ADCS0, resten kommer inte att ställas in för nu. I vårt program är A / D-omvandlingsklockan vald som Fosc / 16, du kan prova dina egna frekvenser och se hur resultatet förändras. Komplett information tillgänglig på databladets sida 127. ADCON0 kommer därför att initieras enligt följande.
ADCON0 = 0b01000001;
Nu har ADCON1-registret följande bitar:
I detta register måste vi göra A / D-resultatformat Välj bit högt med ADFM = 1 och göra ADCS2 = 1 för att välja Fosc / 16 igen. De andra bitarna förblir noll eftersom vi har planerat att använda den interna referensspänningen. Komplett information tillgänglig på datablad sidan 128. Därför kommer ADCON1 att ställa in enligt följande.
ADCON1 = 0x11000000;
Nu efter att ha initierat ADC-modulen i vår huvudfunktion, kan vi komma in i stundslingan och börja läsa ADC-värdena. För att läsa ett ADC-värde måste följande steg följas.
- Initiera ADC-modulen
- Välj den analoga kanalen
- Starta ADC genom att göra Go / Done lite högt
- Vänta tills Go / DONE-biten blir låg
- Få ADC-resultatet från ADRESH- och ADRESL-registret
1. Initiera ADC-modulen: Vi har redan lärt oss hur man initialiserar en ADC så vi kallar det bara nedan för att initialisera ADC
Den ogiltiga ADC_Initialize- funktionen () är följande.
ogiltig ADC_Initialize () {ADCON0 = 0b01000001; // ADC ON och Fosc / 16 har valts ADCON1 = 0b11000000; // Intern referensspänning är vald}
2. Välj den analoga kanalen: Nu måste vi välja vilken kanal vi ska använda för att läsa ADC-värdet. Låter gör en funktion för detta, så att det blir lätt för oss att växla mellan varje kanal inuti medan loop.
osignerad int ADC_Read (osignerad char-kanal) {// **** Välja kanal ** /// ADCON0 & = 0x11000101; // Rensa kanalvalbitar ADCON0 - = kanal << 3; // Ställa in önskade bitar // ** Kanalval slutfört *** ///}
Sedan mottas kanalen som ska väljas inuti den variabla kanalen. I raden
ADCON0 & = 0x1100101;
Det tidigare kanalvalet (om något) raderas. Detta görs genom att använda bitvis och operatören "&". Bitarna 3, 4 och 5 tvingas vara 0 medan de andra kvarstår i sina tidigare värden.
Därefter väljs önskad kanal genom att vänster flytta kanalnumret tre gånger och ställa in bitarna med hjälp av bitvis eller operatören "-".
ADCON0 - = kanal << 3; // Ställa in önskade bitar
3. Starta ADC genom att göra Go / Done bit hög: När kanalen väljs måste vi starta ADC-konverteringen helt enkelt genom att göra GO_nDONE- biten hög:
GO_nDONE = 1; // Initierar A / D-omvandling
4. Vänta tills Go / DONE-biten blir låg: GO / DONE-biten förblir hög tills ADC-konverteringen har slutförts, därför måste vi vänta tills den här biten blir låg igen. Detta kan göras genom att använda en while- slinga.
medan (GO_nDONE); // Vänta tills A / D-konvertering är klar
5. Få ADC-resultatet från ADRESH- och ADRESL-registret: När Go / DONE-biten blir låg igen betyder det att ADC-konverteringen är klar. Resultatet av ADC blir ett 10-bitarsvärde. Eftersom vår MCU är en 8-bitars MCU delas resultatet upp i övre 8-bitars och de nedre 2-bitarna. Det övre 8-bitarsresultatet lagras i registret ADRESH och det nedre 2-bitars lagras i registret ADRESL. Därför måste vi lägga till dessa i register för att få vårt 10-bitars ADC-värde. Detta resultat returneras av funktionen som visas nedan:
retur ((ADRESH << 8) + ADRESL); // Returnerar resultat
Här visas den kompletta funktionen som används för att välja ADC-kanal, utlösa ADC och returnera resultatet.
osignerad int ADC_Read (osignerad char-kanal) {ADCON0 & = 0x11000101; // Rensa kanalvalbitar ADCON0 - = kanal << 3; // Ställa in önskade bitar __fördröjning_ms (2); // Förvärvstid för laddning av kondensatorn GO_nDONE = 1; // Initierar A / D-konvertering medan (GO_nDONE); // Vänta på att A / D-konvertering är fullständig retur ((ADRESH << 8) + ADRESL); // Returnerar resultat}
Nu har vi en funktion som tar kanalvalet som ingång och returnerar oss ADC-värdet. Därför kan vi direkt anropa denna funktion inuti vår while- loop, eftersom vi läser den analoga spänningen från kanal 4 i denna handledning kommer funktionsanropet att vara enligt följande.
i = (ADC_Read (4)); // lagra resultatet av adc i “i”.
För att visualisera utdata från vår ADC behöver vi någon form av displaymoduler som LCD eller 7-segmentet. I denna handledning använder vi en 7-segmentsdisplay för att verifiera utdata. Om du vill veta hur du använder 7-segment med bild följer du handledningen här.
Den fullständiga koden ges nedan och processen förklaras också i videon i slutet.
Installation och testning av hårdvara:
Som vanligt simulera koden med Proteus innan du faktiskt går med vår hårdvara, visas schemat för projektet nedan:
Anslutningar av fyrsiffrig sju segment displaymodul med PIC-mikrokontroller är samma som föregående projekt, vi har precis lagt till en potentiometer till stift 7 som är den analoga kanalen 4. Genom att variera potten kommer en variabel spänning att skickas till MCU som kommer att läsas av ADC-modulen och visas på 7-segmentsdisplaymodulen. Kontrollera föregående handledning för att lära dig mer om fyrsiffrig 7-segment display och dess gränssnitt med PIC MCU.
Här har vi använt samma PIC Microcontroller-kort som vi har skapat i LED-blinkande handledning. Efter att ha garanterat anslutning, ladda upp programmet till PIC och du bör se en utgång som denna
Här har vi läst ADC-värdet från potten och konverterat det till den faktiska spänningen genom att kartlägga 0-1024-utgången som 0-5 volt (som visas i programmet). Värdet visas sedan på 7-segmentet och verifieras med multimeter.
Det är det, nu är vi redo att använda alla analoga sensorer som finns på marknaden, fortsätt och prova detta och om du har några problem som vanligt använder du kommentarsektionen, vi hjälper dig gärna.