Kan inte läsa från AD omvandlaren!

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
fatpo83
Inlägg: 282
Blev medlem: 21 april 2004, 22:42:28
Ort: Sthlm

Kan inte läsa från AD omvandlaren!

Inlägg av fatpo83 »

Jag får konstiga tecken på LCDn när jag försöker läsa från 10bit ADn. Endast AN0 används i pic18f2455. Har jag gjort nåt fel eller? Jag har även försökt läsa av endast ADRESH och ADRESL som är 8bit var och skriva ut i LCDn men samma fel.

Kod: Markera allt

void main (void)									
{
	
	int tal,talH,talL; 
	char data[];
		

	TRISB= 0x00;
	PORTB= 0x00;

	PORTA= 0x00;
	TRISA= 0x03;	//b0000011, RA1 och RA0 input
	ADCON0 = 0x00 ; 	//channel AN0, AD off 
	ADCON1 = 0x0D;     // VSS,VDD, AN0 AN1
	ADCON2 = 0xB7;     //b10110111, right justified, 16TAD, FRC
	ADCON0 = 0x01 ;	//AD ON 

	OpenXLCD(FOUR_BIT & LINES_5X7);	// configure external LCD
	WriteCmdXLCD(BLINK_OFF);	
	putrsXLCD( "1" );  

	while(1) 		
	{

		PORTBbits.RB7 = 1;		//LED indicator
		pic_ad_read(0);
		tal	=	 ADRESL;		/* Getting HSB of CCP1 */
		tal	+= (ADRESH << 8);		/* Getting LSB of CCP1 */
		talH=ADRESH;
		talL=ADRESL;

		delay250Ms(2);

		itoa(tal,data); 			// convert integer to string
		
		WriteCmdXLCD(lcd_rad2);
		putsXLCD(data);										
		PORTBbits.RB7 = 0;	
		delay250Ms(2);
	
	}
}

void pic_ad_read(unsigned char channel)
{
	char i;
	ADCON0 = 0x01; 			//reset channels

	ADCON0 |= (channel<<2);

	for(i=0;i<50;i++);
	ADCON0bits.GO = 1;		//start the conversion
	while(ADCON0bits.GO == 1);
}
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Tydligen har du väl fel med itoa().
Användarvisningsbild
$tiff
Inlägg: 4941
Blev medlem: 31 maj 2003, 19:47:52
Ort: Göteborg
Kontakt:

Inlägg av $tiff »

ska det inte vara:

putsXLCD(itoa(tal,data));


när du ska sriva ut strängen? Så är det i GCC iaf.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Kanske att det kan underlätta att hjälpa om man vet vad de "konstiga tecken" du får på LCDn är för något...
fatpo83
Inlägg: 282
Blev medlem: 21 april 2004, 22:42:28
Ort: Sthlm

Inlägg av fatpo83 »

Nej, itoa() fungerar fint. Jag har tidigare omvandlat tal (int, char) med den funktionen och sparat i en string (här "data"). Sen är det bara att skriva ut den med "putsXLCD(data)".

sodjan, de tecken jag får är typ vågräta linjer med en pixels mellanrum (LCDn är en 5x7). Förstår du?

Det konstiga är också att det första tecknet som skrivs på LCD är vanlig siffra som ändras med samplingen, men de övriga är som beskrivet ovan.

Jag har väl inte gjort fel på initieringen av ADn elller?
Erik_Lind
Inlägg: 97
Blev medlem: 2 maj 2005, 11:25:03

Inlägg av Erik_Lind »

Hur stor blir egentligen:

Kod: Markera allt

char data[]; 
Bör du inte speca hur mycket utrymme den skall tilldelas?
Kan vara så att det inte får plats med ett \0 islutet på strängen och då skriver kanske din LCD rutin ut diverse annat som ligger i minnet.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> "vågräta linjer med en pixels mellanrum..."

Anledningen att jag frågade var att man kanske via teckentabellen för LCD'n kan räkna ut bakvägen vad som faktiskt skickas ut till den.

Är det rätt *antal* tecken, eller kommer det jycket mer än vad det ska ?
Kan du skriva ut någonting alls på LCD'n från samma kod ?
T.ex ettan i "putrsXLCD( "1" );", kommer den ut ?
Hur mycket debugging har du gjort ?
Har du verifierat itoa och LCD rutinen genom att ge "tal" ett hårdkodat värde (alltså inte hämtat från ADC'n) ?
Det är ju centralt att ta reda på om det är ADC'n eller LCD'n du har problem med !!
Har du provat att göra ett enkelt assembler program för att läsa ADC för att verifiera att de delarna är OK ?
Har du kollat assembler koden som genereras för att verifiera att C kompilatorn gör vad du tror ?
Vad är det för C kompilator ?
Är "for(i=0;i<50;i++);" för ADC'ns aqcuisition time (borde i och för sig räcka...) ?
fatpo83
Inlägg: 282
Blev medlem: 21 april 2004, 22:42:28
Ort: Sthlm

Inlägg av fatpo83 »

Felet ligger inte i "char data[]"...det som läggs in dit är 10bitars data fast konverterad till sträng.

Antalet tecken som skrivs på LCDn är rätt, alltså 10st. Anledningen till att jag lade till "putrsXLCD( "1" );" är just att kolla att LCD inte är död. Så det fungerar klockrent. Självaste rutinen "itoa" fungerar fint som jag skrev tidigare.

"for(i=0;i<50;i++);" har jag lagt till i efterhand för säkerhetskull, men annars finns ju "Tad" tiden definierade i ADCON registren. Kompilatorn är C18.

Jag kanske borde ta en titta på assembler koden som genereras.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

10 tecken ? Borde det inte vara max 4 tecken ?
"0000" till "1023" eller något i den stilen ?

Vad förväntar du dig på LCD'n ?
Alltså för att det skall vara "rätt" ?

Jag kanske har missförstått hur itoa() fungerar... :?
fatpo83
Inlägg: 282
Blev medlem: 21 april 2004, 22:42:28
Ort: Sthlm

Inlägg av fatpo83 »

Jag har nu gjort en egen funktion som fixar det. orkar inte felsöka längre.

PS. Det kanske inte ens är värt att använda de inbyggda funktionerna i C18? Trots att man går efter manualen....

tack för alla svar!
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Vadå "fixar det" ? Vad är "det" ?

Vad är det du har ersatt med en egen funktion ?

Vilken funktion i C18 är det som inte är värd att använda ? Och varför inte ?

Vad är det i manualen som inte verkar stämma (det är vad jag läser mellan rederna att du tycker) ?

Det är lite dålig stil (efter ha fått flera att lägga tid på att hjälpa till) inte lämna en förklaring till vad som var orsaken till dina problem med koden...

PS : Jag förstår fortfarande inte varför det skulle bli 10 tecken på LCDn.
fatpo83
Inlägg: 282
Blev medlem: 21 april 2004, 22:42:28
Ort: Sthlm

Inlägg av fatpo83 »

"det" är själva strängkonverteringen (i C18 itoa) felet ligger. Den sträng som konverterats kan inte skrivas ut till lcdn med putsXLCD rutinen; det är just då man får konstiga tecken (men ibland funkar det faktiskt typ 1 på 10) .

Jag skrev ihop nåt snabbt och vips så funkade allt utmärkt:

Kod: Markera allt

void lcd_dec_byte(int val)				

{
	int d,digits=4;
	if (digits > 3)
	{
		d=val/1000;
		val=val%1000;
		WriteDataXLCD(num_to_char(d));
	}
	if (digits > 2)
	{
		d=val/100;
		val=val%100;
		WriteDataXLCD(num_to_char(d));
	}
	if (digits > 1)									
	{
		d=val/10;
		val=val%10;
		WriteDataXLCD(num_to_char(d));
	}
	if (digits > 0)									
	{
		WriteDataXLCD(num_to_char(val));		
	}
}
[/code]
Användarvisningsbild
AndLi
Inlägg: 18274
Blev medlem: 11 februari 2004, 18:17:59
Ort: Knivsta
Kontakt:

Inlägg av AndLi »

vad gör if satserna för nytta?
digits är ju alltid 4! Altså körs alla alltid...

data[] borde definitivt sättas till en längd, om inte minst för att göra koden tydlig, man har ju inte en susning om den är 10 bytes eller 200 bytes när man vill banta programmet.
fatpo83
Inlägg: 282
Blev medlem: 21 april 2004, 22:42:28
Ort: Sthlm

Inlägg av fatpo83 »

Jag är mycket medveten om att if satserna inte hjälper (här). Jag testade nämligen också med olika "digits" först.

Visst ska man alltid begränsa längden, här till data[5], men det funkar ändå...men visst ska man det!
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> "och vips så funkade allt utmärkt..."

OK. Fint !
Och du får ut 10 tecken på LCD'n ?

Du såg inget "mönster" i de ADC värden där itoa varianten fungerade ?
Det måste ju vara *något* som gör att det fungerar ibland och ibland inte...
Skriv svar