Problem med att använda Analog ingång på PIC
Problem med att använda Analog ingång på PIC
Håller på med ett projekt där jag ska ta in en batterispänningsnivå på analoga ingången på picen för att varna när den går låg. Resultatet skriver jag ut på en display men problemet är att resultatet blir 0 hela tiden, jag har debuggat och kollat vad resultat ADRESH och ADRESL innehåller men jag får ut att de innehåller 0. Min programkod:
//ADCON0 Kontrollerar operationerna i AD-Modulen
//ADCON1 Configurerar funktionerna för portarna
ADCON0=00000001;
ADCON1=01001110;
Void BatteryCheck(void)
{
static int Counter=0, Value=0,Temp;
static char FirstPart=0, SecondPart=0;
++counter; //Räknare räknas upp
if(Counter==1000)
{
if(ADCON0 && 0b00000100)
{
FirstPart=ADRESH;
SecondPart=ADRESL;
Temp=FirstPart;
Temp<<=8;
Value=(Temp|SecondPart);
}
Counter=0;
printNumber(Value,0,0,NEW_NUMBER); //Skriv ut ByteValue som ett nummer på Column 0, Rad 0
}
}
//ADCON0 Kontrollerar operationerna i AD-Modulen
//ADCON1 Configurerar funktionerna för portarna
ADCON0=00000001;
ADCON1=01001110;
Void BatteryCheck(void)
{
static int Counter=0, Value=0,Temp;
static char FirstPart=0, SecondPart=0;
++counter; //Räknare räknas upp
if(Counter==1000)
{
if(ADCON0 && 0b00000100)
{
FirstPart=ADRESH;
SecondPart=ADRESL;
Temp=FirstPart;
Temp<<=8;
Value=(Temp|SecondPart);
}
Counter=0;
printNumber(Value,0,0,NEW_NUMBER); //Skriv ut ByteValue som ett nummer på Column 0, Rad 0
}
}
RE: Analog ingång
Ja, den kommer även att driva MCUn. Jag satte AN0 till ingång på trisregistret.
Trisconfigurationen
Ja, jag håller med dig att det var lite dåligt kommenterat, triskonfigurationen är klar innan, det är ett rätt stort projekt så hela koden är rätt omfattande. Jag ska försöka fixa till den ytterligare imorgon.
Detta är delar av ett projekt som aldrig blev av pga. ändringar av hårdvaran. Gjort för PIC18F4550.
Om detta fungerar som tänkt kan jag inte svara på men det borde vara nära iaf.
Kod: Markera allt
void Initialize_AD(void)
{
ADCON0 = 0b00000001; // Enable AD
ADCON1 = 0b00001101; // AN0 & AN1 as analog
ADCON2 = 0b10100001; // Could need tweaking
TRISA.F0 = true; // Set as input
TRISA.F1 = true; // Set as input
}
I main lade jag sedan:
ADCON0.CHS0 = false; // Select channel 0
ADCON0.GO = true; // Start converting
för att starta omvandlingen och jag kollade på ADCON0.GO om den var klar (='0') eller om den höll på att omvandla (='1')
> Är det någon som vet eller har förslag om hur man enklast använder AN0- ingången utan att använda interrupt för att få ett värde i proportion till spänningen?
"Enklast" ? Vad är det ?
Men i princip är det väl :
Sätt ADC konfiggen så att AN0 är "analog".
Konfigga övriga ADC register efter behov.
Starta (efter specad fördröjning) ADC.
När ADC'n har kört klart (kolla lämplig bit), läs av !
Om du använder interrupt eller inte har helt valfritt,
det har inte så mycket med ADC'n i sig att göra, utan hur
din överripande applikationsstruktur ser ut. Om det i ditt
fall är lämpligare att polla ADC'n så visst, gör det.
Om du tror att du har problem med just ADC'n, så skriv ett
litet test-case som bara testar just de delarna...
"Enklast" ? Vad är det ?

Men i princip är det väl :
Sätt ADC konfiggen så att AN0 är "analog".
Konfigga övriga ADC register efter behov.
Starta (efter specad fördröjning) ADC.
När ADC'n har kört klart (kolla lämplig bit), läs av !
Om du använder interrupt eller inte har helt valfritt,
det har inte så mycket med ADC'n i sig att göra, utan hur
din överripande applikationsstruktur ser ut. Om det i ditt
fall är lämpligare att polla ADC'n så visst, gör det.
Om du tror att du har problem med just ADC'n, så skriv ett
litet test-case som bara testar just de delarna...
Jag har gjort lite ändringar, utifrån tipsen typ även pollningen var helt fel, men såhär ser det ut nu:
Borde kunna fungera 
Kod: Markera allt
//ADCON0 Kontrollerar operationerna i AD-Modulen
//ADCON1 Configurerar funktionerna för portarna
void InitBatteryCheck(void)
{
ADCON0=11000001; //AD CONVERT POWERED UP
ADCON1=01001110; //AN1=ANALOG IN
}
Void BatteryCheck(void)
{
static int Counter=0, Value=0, Temp; //Räknare resultat och tempfil för behandling av resultat
static char FirstPart=0, SecondPart=0; //Variabler för att behandla första och andra delen av resultatet i registrena
if(Counter<1000)
counter++; //Räknare räknas upp
else
Counter=0;
if(!Counter) //För att inte fylla upp bufferten måste vi vänta, dessutom måste en kondensator hinna laddas upp för att kunna läsa av ingången
{
if(ADCON0 & 0b00000000) //Kolla GO-bit ifall den är redå att läsa av från analog ingång
{
FirstPart=ADRESH; //Första 5 bitarna är ADRESH
SecondPart=ADRESL; //Sista 5 bitarna är ADRESL
Temp=FirstPart; //Första 5 bitarna läggs i Temp
Temp<<=8; //Temp skiftas 5 åt vänster
Value=(Temp|SecondPart); //Temp pollas med SecondPart som tillsammans läggs in i ByteValue
}
printNumber(Value,0,0,NEW_NUMBER); //Skriv ut ByteValue som ett nummer på Column 0, Rad 0, egen funktion för displayen... funkar
}
}

Pollning rätt?
Jag undrar fortfarande om jag fått till pollningen rätt ändå nu när jag tänker efter...
kanske måste kolla GO/DONE Biten om den är 0? genom att bara skriva dit den o pröva att den är 0 istället för att polla ut den?
kanske måste kolla GO/DONE Biten om den är 0? genom att bara skriva dit den o pröva att den är 0 istället för att polla ut den?
Go/Done-bit
När jag kollade i databladet för 18F458 var Go/Done-biten statusbiten som clearades av processorn då konverteringen var klar. Jag vet inte, kanske har missuppfattat det hela.