A/D Wandler defekt gibt nur 1023 aus

OP #2309402
Lesenswert?

Hallo zusammen,

ich wollte ebend auf meinem selbst gebauten Controllerboard, siehe Bild

Meinen schon vor Monaten auf den STK500 Board erstellten und 
funktionsfähigen Code zum Laufen bringen.
Der Code lief damals auf einem Atmega8.

Jetzt habe ich nur einen einzigen Atmega32 und da zeigt der Code für den 
Analogen Potiwert ständig nur 1023 an.

Habt ihr eine Idee woran das liegen könnte.
anbei auch der Code

Das merkwürdige ist, das wenn ich die Potispannung von beispielsweise 
1,5V auf den PIN0 an PORT A lege  ADMUX = 0x01;   dann messe ich am 
Eingangsport des ADC 0V, obwohl ich 1,5V anlege. die habe ich auch 
vorher gemessen und die sind da.

im Eingangsmodus funktioniert der PORT A problemlos.
Ist der code nicht in Ordnung (bitteeinmal drüber schauen) oder der 
Prozessor.


Viele GRüße und noch einen schönen Abend wünscht Matthias.
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <stdlib.h>
4
#define LCD_Port PORTB
5
#include "E:\Eigene Dateien\Dropbox\Atmel AVR\AVR Programme\1aVorlagen\lcd_tools.c"
6

7

8

9
#define F_CPU 4000000UL // Systemtakt in Hz - Definition als unsigned long beachten 
10
                         // Ohne ergeben sich unten Fehler in der Berechnung
11

12

13

14
int main(void)
15
{
16

17
DDRD=0xff;  
18
DDRB=0xff; //PORT für LCD_Port aktivieren
19

20
double  result = 0;
21
char buffer[20];
22
ADMUX = 0x01;        // Kanal waehlen (ADC1)  
23
 _delay_ms(100); 
24
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0);      // Frequenzvorteiler: setzen auf 32 (4 MHz / 32 = 125 kHz) und ADC aktivieren 
25
// ADCSRA &=~(1<<ADPS1);   //zur Sicherheit   
26

27
  
28
    
29
  ADMUX |= (1<<REFS0) ;     // externe Spannung nutzen 
30
  // ADMUX &=~(1<<REFS1);      // zur Sicherheit externe Refrerenzspannung nutzen 
31

32
  ADCSRA |= (1<<ADSC);                // eine ADC-Wandlung und danach wird das Bit wieder auf Null gesetzt
33
  while ( ADCSRA & (1<<ADSC) );       // auf Abschluss der Konvertierung warten , warten bis die Wandlung durchgeführt iwst und bit wieder auf Null
34
  result = ADCW;            // Wert abholen
35
  
36

37
lcd_ini();
38
/*
39
lcd_gotopos(1,1);
40
lcd_writetext("Spannung PIN 1=");
41
lcd_gotopos(1,19); lcd_writetext("V");
42

43
*/
44

45
while(1)
46
  {
47

48
  ADMUX = 0x01;        // Kanal waehlen (ADC1)     ?? 
49

50
    ADCSRA |= (1<<ADSC);                // eine ADC-Wandlung und danach wird das Bit wieder auf Null gesetzt
51
    while ( ADCSRA & (1<<ADSC) );       // auf Abschluss der Konvertierung warten , warten bis die Wandlung durchgeführt ist und bit wieder auf Null
52
    result = ADCW;            // Wert abholen
53

54
  
55
  
56
  // dtostrf (5*result/1024.0, 4,1, buffer);    lcd_writetext(buffer);
57
  lcd_gotopos(4,15); lcd_writezahl(result);
58

59
PORTD ^= ( 1 << PB6 );     // Toggle PB0 z.B. angeschlossene LED, die LED blinkt, das funktioniert, also wird der code mehrmals abgearbeitet
60
 _delay_ms(700); 
61

62

63
  }
64

65

66
return 0;
67

68
}
Angehängte Dateien:
OP #2309446
Lesenswert?

Hubert G. schrieb:
> ADMUX = 0x01  ist ADC1 auf PORTA1

Hallo Hubert,

danke für den Tipp.

Ja, ich habe sogar alle PORT A Pins durchprobiert, kein Erfolg.  PIN1 
auf PORT A müßte das sein, =anschlussPIN40 vom dem Atmega32.

Habe mich wohl mißverständlich ausgedrückt, aber kein PIN von PORT A 
funktioniert, leider.

Vielleicht noch eine Idee?
Ansonsten scheint der Code wohl in Ordnung zu sein, sonst hättest Du 
bestimmt noch was gesagt.
Viele Grüße,

Matthias.
OP #2309457
Lesenswert?

Hallo zusammen,

danke für Eure Hilfe.

anbei ein Foto von meinem Schaltplan.
selbst wenn ich mich um einen PIN vertuhen würde 39 anstatt 40. ich habe 
ja alle PORT A pins auf masse gezogen und es hat sich nichts an der LCD 
Ausgabe getan.

zur Sicherheit habe ich auch noch eine LED auf PRTD mit in dieser 
Messschleife vom POIRTA blinken lassen, um sicher zu gehen, das diese 
schleife überhaupt wiederholt abgearbeitet wird.

ich fahre jetzt schnell zu conrad und hole mir einen weiteren Chip 
Atmega32 für 7,5€ :-(  ist dort sehr teuer

muss jetzt schnell los.

kann aber von unterwegs jederzeit eure Mails lesen.

bis nachher
Angehängte Dateien:
Gast #2309463
Lesenswert?

Hubert G. schrieb:
> Ralf G. (ralg) schrieb:
>> PORTA??
>
> Beim Mega32 ist der ADC auf PORTA, zumindest steht es in meinem
> Datenblatt so.
Ja, hatte etwas nachlässig den Eröffnungsthread gelesen. Ich ging beim 
'Tausch' von etwas pinkompatiblem aus :-(

Also:
ADMUX-Register sieht für mich auf den ersten Blick völlig anders aus.
#2309494
Lesenswert?

Was sagt dir
1
  ADMUX |= (1<<REFS0) ;     // externe Spannung nutzen 
2

3
  ...
4

5
  while(1)
6
  {
7
   
8
    ADMUX = 0x01;        // Kanal waehlen (ADC1)     ?? 
9

10
    ...

Ich frag mich ja immer wieder, wozu es im Tutorial fertige getestete 
Funktionen gibt, wenn sie dann keiner studiert, wie man die Dinge macht. 
Oder gar, Gott bewahre, einfach die Funktionen aus dem Tut nimmt.
OP #2311417
Lesenswert?

Guten Morgen zusammen,

ich betreibe meinen Atmega32 im free running mode und habe eine Frage 
zur Kanalauswahl.

Ich habe es so verstanden, wenn man keienn Kanal wählen würde

 ADMUX = 0x06;   //Platinenpoti   also nciht diese Zeile,

dann würde der AD Wandler nach und nach alle Kanäle abfragen.

Was ist, wenn ich diese Kanäle aktiviere, weil ich sie in meinem 
Programm brauche
ADMUX |= 0x04;    //Motorpoti
ADMUX |= 0x03;  //shunt
ADMUX |= 0x06;   //Platinenpoti

meines Wissens nach werden dann nur diese Kanäle im free running mode 
durchlaufen, oder irre ich mich da?

jetzt habe ich aber eine Oversampling abfrageschleife so wie hier

result=0;

  for(i=0; i<20;i++)
  {
  //ADCSRA |= (1<<ADATE);
  while (!(ADCSRA & (1<<ADIF)));
  result += ADCW;

  }
result /=20;
dtostrf((double)result, 4,0, texte); lcd_gotopos(3,16); 
lcd_writetexte(texte);


Meine eigentliche Frage lautet, ob in dieser Schleife jetzt nach und 
nach alle 3!!! vorkonfigurierten ADC Kanäle abgefragt und ausgewertet 
werden???
Ich möchte doch in dieser konkreten Schleife jetzt nur einen der drei 
vorgewählten
ADMUX |= 0x04;    //Motorpoti
ADMUX |= 0x03;  //shunt
ADMUX |= 0x06;   //Platinenpoti

Kanäle abfragen.

Muss ich dazu vor dieser SChleife zwei der drei Kanäle deaktivieren? Ich 
denke ja, oder


Ich hoffe, ich konnte mein Anliegen verständlich rüber bringen.

Danke für die Hilfe im Vorraus,

Matthias.
Gast #2311426
Lesenswert?

Matthias H. schrieb:
> ADMUX |= 0x04;    //Motorpoti
> ADMUX |= 0x03;  //shunt
> ADMUX |= 0x06;   //Platinenpoti

Böse. Dein ADMUX sieht danach so aus:
ADMUX = 0x03 | 0x04 | 0x06 = 0x07;
Das willst du sicher nicht.

Meine Empfehlung, kapsle die komplette AD-Wandlung mit Einstellung des 
Kanals in eine Funktion (wie z.B. im Tutorial vorgemacht).
Und dann benutze zum AD-Wandeln nur noch diese Funktion, ohne in den 
Registern wild rumzuschreiben.

Übrigends gibt ADMUX immer den aktuellen Kanal an, da kann man nix 
voreinstellen, was der ADC als nächstes machen soll.
:-)
OP #2311449
Lesenswert?

Magnus Müller schrieb:
> Auch wenns jetzt nicht mit deinem eigentlichen Problem zu tun hat...
>
> Hast du dir eigentlich beim Layouten mal darüber Gedanken gemacht wie du
> deine Anschlussleitungen in die Schraubklemmen gesteckt bekommst?
>
> http://www.mikrocontroller.net/attachment/118664/DSCF1935.jpg
>
> Gruß,
> Magnetus



Guten Morgen Magnetus,

das war mein absolut erstes Layout. Da war es mir dann egal, wenn ich 
nciht überall 100%igen Zugang habe. Die Zeit war dann auch knapp und die 
Fläche begrenzt. Um ein wenig zu programmieren, dafür reicht das Board 
allemal. Ich muss dazu nicht an alle optionalen Schraubklemmen gelangen. 
:-)

Das nächste Board wird weitaus verbessert werden. Zum einen wird eine 5V 
Referenzspannungsquelle an den ADC angeschlossen.

Auch wird da Boadlayout hinsichtlicht einer taktung von 16MHZ optimiert 
werden müssen. Ich denke da an die Masseverlegung siehe Bild.
mehr kann ich Dir zu dem Bild gar nicht so sagen. Die darf wohl nur von 
einer Seite rein in den uC.

Viele Grüße,

Matthias.
Angehängte Dateien:
OP #2311452
Lesenswert?

Hallo,

danke ich werde die Routine vom Tutorial verwenden.

so sähe das wohl aus, wenn ich alle gleihczeitig aktivieren würde.

ADMUX = (1<<REFS0) ;     // interne Spannung nutzen
ADMUX |= 0x04;    //Motorpoti
ADMUX |= 0x03;  //shunt
ADMUX |= 0x06;   //Platinenpoti

da hatte ich noch zu wenig ERfahrung. Jetzt ist mir klar, dank Deines 
Tipps, das man immer nur einen aktivieren kann!!

Sonst kommt eine ganz andere Konfiguration raus. :-)


Viele GRüße,

Matthias.
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren