#include <stdio.h>
#include "lcd4.h"
#include "io_atmega16.h"
void wait_milliseconds(int);
/*=== main ==============================================
Programmet läser av en potentiometer som är ansluten till den
analoga ingången kanal 0. Värdet skrivs sedan ut på en LCD display.
========================================================*/
int main(void)
{
lcd4 theDisplay; //Structure variable
char s[20];
int value;
double voltage;
// Init of the LCD-display
lcd4_init(&theDisplay,&PORTC,&DDRC,4000,50);
// Init of the ADC
ADCSRA = (ADCSRA & 0xF8) ; //Prescale factor for the A/D
ADCSRA = ADCSRA | (1<<ADEN); //Enable of the A/D
while ( 1 )
{
// 1. READ OF THE ANALOG INPUT CHANNEL 0
ADMUX = (ADMUX & 0xE0) | 0; // Analog input channel 0
ADCSRA = ADCSRA | (1<<ADSC); //A/D start of conversion
while ( (ADCSRA & (1<<ADSC)) != 0 ) //Wait until conversion is done
;
value = (unsigned int) ADC; //10 bits value, max value 1023 and min value 0
// 2. CONVERSION OF THE 10 BITS VALUE (int) TO VOLTAGE VALUE (float)
voltage = 5.0*(value / 1023.0);
// 3. WRITE OF THE VOLTAGE VALUE ON THE LCD-DISPLAY
sprintf( s, "%2.1fV", voltage );
lcd4_cup_row1(&theDisplay);
lcd4_write_string( &theDisplay, s );
}
return 0;
}
Men det händer inget när jag skjuter på potentiometern. Har testat att koppla på alla möjliga sätt. Jag använder en STK500 och har testat med att mata potentiometern från kortet och från annan spänningkälla. Men displayen visar bara ?V hur jag än gör... Något tips till en vilsen kille?
Tack på förhand!
fjodorr
Senast redigerad av fjodorr 15 maj 2007, 21:47:31, redigerad totalt 1 gång.
Först testa jag att koppla in den på PORTAs GND och VTG och sedan en pinne till PA0. Den potentiometern som jag använder har tre pinnar.
Sedan har jag kopplat villt på min exp.platta här hemma. Men ingen framgång där heller... Men som jag förstår det behöver processorn och potentiometern vara kopplad till samma jord. Stämmer det?
Till och börja med - kontrollera att spänningen till ingångsporten verkligen går upp och ned allt eftersom du justerar poten med vanlig multimeter där dess jordpinne är kopplad till samma jord som MCU:n.
fråga nr: 2 - varför visas ett '?' i displayen och inte ett lämpligt värde mellan 0 och 255 - 1024 eller liknande (jag har inte läst igenom koden)
Man får felsöka bit för bit och allt eftersom säkra att det fungerar utifrån och in sas.
Det går inte att köra bigbang-projekt där allthop görs på en gång och sedan tro att allting fungerar direkt.
Som nämt - kolla att spänningen in från poten fungerar, därfter med en liten kodsnutt kontrollera att AD-fungerar och kanske låta dess inlästa värde speglas ut på en 8-bitsport som du enkelt kan kontrollera hög-låg med en multimeter, - när du har fått detta att fungera - då kan du fundera på om displayrutinen arbetar rätt eller matas med rätt värden - ta det bit för bit, du kommer säker hitta en mass löjliga 'varför tänkte jag inte på detta'-fel på vägen
Använder du avr-libc och avr-gcc (och vilken processor? att det var avr talas bara om av att du använder en stk500)
Gör du det har jag för mig att man måste ha med en kompilatorflagga för att aktivera float-conversion i sprintf. Kolla i man-sidan. Att man gör så beror på att det tar ett antal kB med kod för att omvandla från float till char så man vill inte inkludera det mer än nödvändigt.
Float bör, så långt det bara går, undvikas i µC-sammanhang. Du kommer iaf. aldrig att få bättre värde än upplösningen på AD-omvandlaren, alltså kan du skala med ett fast värde.
unsigned long Resultat = (value * 5000) / 1023;
Denna uträkning ger dig värdet i mV och kör med heltal, för att skriva ut det är det bara:
printf("%lu,%04luV",Result / 1000, Result % 1000);
då får du en snygg och prydlig:
3,025V
EDIT:
På detta sätt undviker du hela float-biblioteket och vinner en hel del hastighet, tricket i detta är att FÖRST multiplicera och SEDAN dividera!
Exempel: AD-värde: 377.
Rätt sätt:
377 * 5000 = 1885000
1885000 / 1023 = 1842 (bara heltal räknas ju) = 1,842V
Fel sätt:
377 / 1023 = 0 (bara heltal räknas ju)
0 * 5000 = 0 = 0,000V