PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : bräuchte mal hilfe zu diesem ADC-Code...



LC-HC
19.02.2006, 19:51
Hi, ich versuch grade den A/D Wandler in meinem ATmega 8 zum laufen zu bringen. K ist eine vergleichskonstante, die falls überschritten, mittels if/else verzweigung in main() die led an PB.1 zum leuchten zu bringen. Was aber passiert, ist ein ganz schwaches leuchten in jedem betriebszustand und ein etwas stärkeres leuchten bei voll aufgedrehtem poti. Allerding steigt die leuchtstärke nicht stetig, sondern sprunghaft kurz vor erreichen der poti-endstellung. Kann mir da jemand weiter helfen ?
hier auf jedenfall erst mal der code:

// Includes:
#include <avr/io.h>
#include <util/delay.h>


// Definition der ADC Register ADCSRA und ADMUX:
// ADCSRA:
#define ADEN 7
#define ADSC 6
#define ADFR 5
#define ADIF 4
#define ADIE 3
#define ADPS2 2
#define ADPS1 1
#define ADPS0 0
// ADMUX:
#define REFS1 7
#define REFS0 6
#define ADLAR 5
// ... leer ...
#define MUX3 3
#define MUX2 2
#define MUX1 1
#define MUX0 0


// Prototypenfunktionen:
void io_init(void);
int adc_init(void);




int main(void)
{
int k = 0;
io_init(); // I/O init
adc_init(); // ADC init

PORTB = 0x00;

for(;;)
{
if(adc_init() > k)
PORTB |= (1<<1);
else
{
PORTB ^= (1<<1);
}

}

return 0;
}

void io_init(void)
{
DDRC = 0xFF;
DDRB = 0x00;
}


int adc_init(void)
{
int i;
int result = 0;



// interne Referenzspannung , Freerunning
ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADFR) |(1<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS0);

// Ergebnis der Umsetzung links ausgerichtet
ADMUX = 0x00 | (1<<ADLAR);



/* eigentliche Messung ( arithmet. Mittelwert aus 2 Messungen ) */

for( i = 0; i < 2; i++)
{
//ADCSRA |= (1<<ADSC);
//while ( ADCSRA & (1<<ADSC));
result += ADCH;
}

result /= 2;

return result;
}


Danke schonmal für alle antworten.

mfg,
LC

askazo
19.02.2006, 20:19
DDRB = 0x00;

The DDxn bit in the DDRx Register selects the direction of this pin. If DDxn is written
logic one, Pxn is configured as an output pin. If DDxn is written logic zero, Pxn is configured
as an input pin.

Du hast den kompletten Port B als Eingang konfiguriert. Wenn Du eine LED ansteuern willst, musst Du schon den entsprechenden Port-Pin als Ausgang setzten.

PS: Warum konfigurierst Du beim Auslesen der Messwerte den ADC immer wieder neu? Ist zum einen ziemlich verwirrend, wenn eine Routine namens ADC_Init einen Messwert zurückgibt, zum anderen auch unsauber programmiert...

askazo

LC-HC
19.02.2006, 20:33
Verstehe, du meinst also so:


// Prototypenfunktionen:
void io_init(void);
void adc_init(void);
int adc_data(void);



int main(void)
{
int k = 0x4;
io_init(); // I/O init
adc_init(); // ADC init



for(;;)
{
if(adc_data() > k)
PORTB |= (1<<1);
else
{
PORTB ^= (1<<1);
}

}

return 0;
}

void io_init(void)
{
DDRC = 0x00;
DDRB = 0xFF;
}


void adc_init(void)
{
int i;
int result = 0;



ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADFR) |(1<<ADIF) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS0);


ADMUX = 0x00 | (1<<ADLAR);
}



int adc_data(void)
{
/* eigentliche Messung ( arithmet. Mittelwert aus 2 Messungen ) */

for( i = 0; i < 2; i++)
{
result += ADCH;
}

result /= 2;

return result;
}

?

Hab´s mal ausprobiert. Natürlch hab ich die ports falsch konfiguriert, aber der effekt ist der gleihe, nur dass die LED-leuchtstärke so ist, wie sie sein soll.

(PS: wie kann man denn hier "Code" einfügen ?)

LC-HC
19.02.2006, 21:03
OK, hab´s jetzt. es lag offensichtlich an der for() - Schleife.

Thx.

askazo
20.02.2006, 09:08
Ah ja, in die for-Schleife hatte ich noch gar nicht reingeschaut.
mit
PORTB ^= (1<<1);
hast Du die LED quasi dauernd aus- und eingeschaltet.
Naja, hast Du ja selbst gefunden...

Code kann man übrigens mit
[code ]Mein Code[/code ] (Leerzeichen in den Klammern weglassen!)
einfügen.

Gruß,
askazo