Forum: Mikrocontroller und Digitale Elektronik ATmega 8 Problem mit ADC und Uart


von J. Hebeler (Gast)


Lesenswert?

Folgender Code soll von den ersten 3 ADC des Mega8 den 8-Bit wert lesen 
und diesen dann per Uart an meinem PC sendet. Dort kommen aber nur 3 
Fragezeichen an. Entweder habe ich einen Fehler im Code oder einen 
Fehler im Zeichensatz des Testprogramms.
1
#define F_CPU 16000000
2
#define ADC0 0
3
#define ADC1 (1 << MUX0)
4
#define ADC2 (1 << MUX1)
5
6
7
#include <avr/io.h>
8
#include <avr/interrupt.h>
9
#include <stdio.h>
10
#include <stdlib.h>
11
12
char ADCConvert8Bit(char channel)
13
{
14
  ADMUX &= ~((1 << MUX0) | ( 1 << MUX1) | (1 << MUX2) | (1 << MUX2) | (1 << MUX3));
15
  ADMUX |= channel;
16
  ADCSRA |= (1 << ADSC);
17
  while(ADCSRA & (1 << ADSC)){}
18
  return ADCW;
19
}
20
21
void SendData(char data)
22
{
23
  while(!(UCSRA & (1 << UDRE)));
24
  UDR = data;
25
}
26
27
int main(void)
28
{
29
  DDRC = 0;
30
  DDRD = (1 << PD1);
31
  PORTC = 0;
32
  PORTD = 0;
33
  DDRB = 0xff;
34
  PORTB = 0;
35
  char X = 0, Y = 0, Z = 0, result = 0;
36
37
  ADMUX = (1 << REFS1) | (1 << REFS0) | (1 << ADLAR);
38
  ADCSRA = (1 << ADEN);
39
40
  ADCSRA |= (1<<ADSC);
41
  while (ADCSRA & (1<<ADSC) ) {}
42
  result = ADCW;
43
44
  UCSRB = (1 << TXEN);
45
  UBRRL = 51;
46
47
  while(1)
48
  {
49
    X = ADCConvert8Bit(ADC0);
50
    Y = ADCConvert8Bit(ADC1);
51
    Z = ADCConvert8Bit(ADC2);
52
    SendData('X');
53
    SendData('Y');
54
    SendData('Z');
55
    SendData(X);
56
    SendData(Y);
57
    SendData(Z);
58
  }
59
60
61
  return 0;
62
}
Ich denke es ist mal wieder ein dummer Fehler, der mir nicht auffallen 
will...
Ich hoffe man kann mir helfen und bedanke mich mal für Hilfe im voraus 
;)

MfG J. Hebeler

von Thomas E. (thomase)


Lesenswert?

J. Hebeler schrieb:
> SendData('X');
>
>     SendData('Y');
>
>     SendData('Z');
>
>     SendData(X);
>
>     SendData(Y);
>
>     SendData(Z);

Die ersten 3 Zeichen sind Ascii-Zeichen, die dein PC auch versteht.
Die letzten sind irgendwelche Zahlenwerte(Hex), die er versucht als 
Ascii zu interpretieren, aber meistens nicht versteht.

Da musst du jeweils zwei Ascii-Zeichen draus machen.

mfg.

von Spess53 (Gast)


Lesenswert?

Hi

>  return ADCW;

Bei ADLAR=1 ist nur ADCH relevant.

>void SendData(char data)
>{
>  while(!(UCSRA & (1 << UDRE)));
>  UDR = data;
>}

Und du meinst, das das dir einen Wert in ASCII ausgibt?

MfG Spess

von J. Hebeler (Gast)


Lesenswert?

>>Ascii zu interpretieren, aber meistens nicht versteht.
Ist mir klar, sollte aber zumindest bei Wertänderung des ASCII Zeichens 
am Computer bewirken, der zeigt mir aber nur Fragezeichen an. Wenn das 
das Problem wäre, würde ich anstelle der ASCII-Zeichen schnell die 
Hexwerte ausgeben lassen.
>>Und du meinst, das das dir einen Wert in ASCII ausgibt?
Es werden Daten binär übertragen, es ist mir egal ob es ASCII Zeichen 
sind.
Ich will mir nur nicht stundenlang mit Debugging verbringen, um dann 
einen einfachen Fehler in der Firmware zu Korrigieren.

MfG J. Hebeler.

von Karl H. (kbuchegg)


Lesenswert?

Die Buchstaben XYZ kommen?

von Karl H. (kbuchegg)


Lesenswert?

Was hast du an den ADC Eingängen hängen?

von J. Hebeler (Gast)


Lesenswert?

>>Die Buchstaben XYZ kommen?
Die kommen Normal an, und danach noch ???, also so in etwa:
XYZ???XYZ???XYZ???XYZ???XYZ???

von J. Hebeler (Gast)


Lesenswert?

>>Was hast du an den ADC Eingängen hängen?
Nen Accelerometer, Spannung ist auch da.

von Marco U. (Gast)


Lesenswert?

Zum Wandeln der Int Werte in ASCII Code kannst du die Funktion
itoa(int,char*,Basis); aus der stdlib.h hernehmen.

PS: Deklariere deine result Variable mal als INT oder uint8_t.

von spess53 (Gast)


Lesenswert?

Hi

>Zum Wandeln der Int Werte in ASCII Code kannst du die Funktion
>itoa(int,char*,Basis); aus der stdlib.h hernehmen.

Dazu müsste er von 'char ADCConvert8Bit(char channel)' erst mal 
vernünftige Werte bekommen:

>return ADCW;

Er hat mit ADLAR=1 auf linksbündig gestellt. Der Compiler übergibt aber 
(nach meiner Simulation) an 'SendData(X)' ADCL und nicht ADCH.

MfG Spess

von J.Hebeler (Gast)


Lesenswert?

>>Dazu müsste er von 'char ADCConvert8Bit(char channel)' erst mal
vernünftige Werte bekommen:
Jop, hab ich auch getestet, ich hatte es zuerst mit ADCH, dann hab ich 
in eurem Tut ADCW gelesen, das Probiert, hat halt auch net funktioniert, 
jetzt wieder auf ADCH umgestellt.
Hab jetzt mein Testprogramm aufm PC umgeschrieben, das es mir nur noch 
die Zahlenwerte der chars ausgibt. Sehe das XYZ und 3 mal 255 ankommt.
Kann es sein, das die Interne Refernez falsch gewählt ist, bzw falsch 
angesteuert?
Ich habe Signalpegel von 1,6 - 2,3V gemessen und habe an AREF ein C=100n 
gegen GND geschaltet.

MfG J.Hebeler

von spess53 (Gast)


Lesenswert?

Hi

ADMUX = (1 << REFS1) | (1 << REFS0) | (1 << ADLAR);

stellt die 2,56V Referenz ein.

>Sehe das XYZ und 3 mal 255 ankommt. Kann es sein, das die Interne Refernez
>falsch gewählt ist, bzw falsch angesteuert?

Das ist allerdings ein Indiz, das die Eingansspannung >= Vref ist.
Nimm doch einfach mal VCC als Referenz.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Nimm dir doch einfach mal die ADC Routinen aus dem
AVR-GCC-Tutorial

Immer diese Rumraterei.

von spess53 (Gast)


Lesenswert?

Hi

Noch was: Auch wenn du nur 8 Bit haben willst, sind 16MHz für den 
ADC-Takt wesentlich zu schnell. Stell mal den Prescaler ein.

MfG Spess

von J. Hebeler (Gast)


Lesenswert?

>>Noch was: Auch wenn du nur 8 Bit haben willst, sind 16MHz für den
ADC-Takt wesentlich zu schnell. Stell mal den Prescaler ein.

Hab ich jetzt mal gemacht

>>Das ist allerdings ein Indiz, das die Eingansspannung >= Vref ist.
Nimm doch einfach mal VCC als Referenz.
Jop, hab ich jetzt auch gemacht, es kommen jetzt andere werte an, Ich 
muss die aber erst gescheit aufbereiten, ansonsten kann ich nicht 
verifizieren, das es die richtigen sind.
Danke für die Hilfe.

von J. Hebeler (Gast)


Lesenswert?

Ja, es funktioniert jetzt. Nochmal der Finale Quellcode, für alle die 
das gleiche Problem haben:
1
#define F_CPU 16000000
2
#define ADC0 0
3
#define ADC1 (1 << MUX0)
4
#define ADC2 (1 << MUX1)
5
6
7
#include <avr/io.h>
8
#include <avr/interrupt.h>
9
#include <stdio.h>
10
#include <stdlib.h>
11
12
char ADCConvert8Bit(char channel)
13
{
14
  ADMUX &= ~((1 << MUX0) | ( 1 << MUX1) | (1 << MUX2) | (1 << MUX2) | (1 << MUX3));
15
  ADMUX |= channel;
16
  ADCSRA |= (1 << ADSC);
17
  while(ADCSRA & (1 << ADSC)){}
18
  return ADCH;
19
}
20
21
void SendData(char data)
22
{
23
  while(!(UCSRA & (1 << UDRE)));
24
  UDR = data;
25
}
26
27
int main(void)
28
{
29
  DDRC = 0;
30
  DDRD = (1 << PD1);
31
  PORTC = 0;
32
  PORTD = 0;
33
  DDRB = 0xff;
34
  PORTB = 0;
35
  char X = 0, Y = 0, Z = 0;
36
  uint16_t result = 0;
37
38
  ADMUX = (1 << REFS0) | (1 << ADLAR);
39
  ADCSRA = (1 << ADEN) | (1 << ADPS1);
40
41
  ADCSRA |= (1<<ADSC);
42
  while (ADCSRA & (1<<ADSC) ) {}
43
  result = ADCW;
44
45
  UCSRB = (1 << TXEN);
46
  UBRRL = 51;
47
48
  while(1)
49
  {
50
    X = ADCConvert8Bit(ADC0);
51
    Y = ADCConvert8Bit(ADC1);
52
    Z = ADCConvert8Bit(ADC2);
53
    SendData('X');
54
    SendData('Y');
55
    SendData('Z');
56
    SendData(X);
57
    SendData(Y);
58
    SendData(Z);
59
  }
60
61
62
  return 0;
63
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.