mikrocontroller.net

Forum: Compiler & IDEs ADC mit mega32 funktioniert nicht


Autor: S. Lehner (slehner)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo alle zusammen,

seit etwa 3 Monaten programmiere ich jetzt den mega32 und habe soweit 
alle Funktionen in Betrieb nehmen können dich ich brauche (I2C, UART, 
PORTS) Nun möchte ich über den ADC gerne eine Spannung einlesen. Im 
Internet habe ich bereits auch ein beispiel gefunden und teilweise etwas 
angepasst. Ich poste euch erstmal den Code der Funktion und dann den 
Programmteil, der diese aufruft. Der Wert soll über Port C ausgegeben 
werden. (oder testweise und die unteren 8 Bit. Es wäre super wenn mir 
jemand helfen könnte und nen Fehler in dem Code findet.

Funktion:
uint16_t ReadChannel(uint8_t mux)
{
  uint8_t i;
  uint16_t result = 0; //Initialisieren wichtig, da lokale Variablen
  uint8_t temp;
  
  ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);   // requenzvorteiler
                          // setzen auf 8 (1) und ADC aktivieren (1)
  ADMUX = mux; // Kanal waehlen
  //ADMUX |= (1<<REFS1) | (1<<REFS0); // interne Referenzspannung nutzen
  ADMUX |= (1<<REFS0);
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
  also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
  ADCSRA |= (1<<ADSC); // eine ADC-Wandlung

  while ( ADCSRA & (1<<ADSC) )   {
                  //konvertierung abwarten
                  }


  /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
  for(i=0;i<4;i++)
  {
    ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
    while ( ADCSRA & (1<<ADSC) ) 
    {
    ; // auf Abschluss der Konvertierung warten
    }

    result += ADCL; // Wandlungsergebnisse aufaddieren
    temp = ADCH;
  }
  ADCSRA &= ~(1<<ADEN); // ADC deaktivieren (2)
  result /= 4; // Summe durch vier teilen = arithm. Mittelwert
  return result;
}

aufrufender Programmteil:
uint16_t adcval;
  uint8_t ausgabe;
  for(;;){
    adcval = ReadChannel(0); /* MUX-Bits auf 0b0000 -> Channel 0 */
    //adcval = ReadChannel(2); /* MUX-Bits auf 0b0010 -> Channel 2 */
    DDRB = 0xFF;
    ausgabe = adcval | 0xFF;
    PORTB = ausgabe;
    delayloop16(16000);
    }

  

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>   ausgabe = adcval | 0xFF;

Sollte da statt des | nicht ein & stehen? Sonst wird immer 0xff an den
Port gegeben.

Autor: Joerg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...oder ein "^", um die Bits umzudrehen, falls es um low-active-LEDs 
geht
(Und war da nicht was mit PORTC und JTAG...)
hth. Jörg

Autor: S. Lehner (slehner)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Wandlung vom ADC funktioniert. Das Problem war ein anderen, nähmlich 
die Ausgabe. Ich möchte die 16bit Zahl ausgeben und dabei macht er 
verrückte Sachen. Ich glaube dass ich die zahl nicht anständig ich 8 bit 
Variablen aufteilen kann. Weiß jemand wie man das macht? Ich habe es nun 
mit folgendem probiert und es klappt nicht(Die Ausgabe über die serielle 
Schnittstelle funktioniert mit bytes bereits):
    zahl = AD_in();      // uint_16
    unsigned char tausender = (unsigned char) (zahl/1000) & 0x00FF;
    unsigned char hunderter = (unsigned char) (mod(zahl,1000)/100) & 0x00FF;
    unsigned char zehner = (unsigned char) (mod(zahl,100)/10)& 0x00FF;
    unsigned char einer = (unsigned char) mod(zahl,10) & 0x00FF;
    //PORTB = zahl_l;
    
    USART_transmit(tausender+48);
    
    USART_transmit(hunderter+48);
    USART_transmit(zehner+48);
    USART_transmit(einer+48);
    USART_transmit(45);// -

  

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann in dem geposteten Programmteil keinen Fehler erkennen. Der
Fehler liegt entweder in USART_transmit (aber du schreibst, dass die
Ausgabe einzelner Zeichen schon funktioniert) oder die Funktion mod
tut nicht das Erwartete.

Was wird denn verrücktes ausgegeben? Wird wenigstens das '-' am Ende
angezeigt?

Woher kommt überhaupt die mod-Funktion? Hast du die selbst
geschrieben? Sonst gibt es für solche Dinge in C auch den
Modulooperator '%'.

Die "& 0x00FF" kannst du dir sparen. Sie haben keinen Effekt.

Autor: S. Lehner (slehner)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke für die Idee mit dem % Operator, den hab ich ganz vergessen.


Die Ausgabe funktioniert auch inzwischen. Der Fehler lag darin, dass ich 
die Stromversorgung des Atmels vor dem UART Anschluss angeschlossen habe 
und dadurch das Hyperterminal mitten im Byte angefangen hat das die 
Zeichenkette aufzunehmen. Deshalb wurden auch wirre Zeichen ausgegeben

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
????

Das muß man jetzt aber nicht verstehen, oder?

Falls du das meinst, was ich glaube, zu verstehen (aber eigentlich nicht 
glauben kann): Ein Reset-Taster kostet nur ein paar Cent, und ist Gold 
wert.

Oliver

Autor: S. Lehner (slehner)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja Oliver das stimmt. Es ist ein Projekt von 3 Leuten und ich 
programmiere den Atmel nur. Die Elektronik mach ich nicht. Mit wäre es 
auch lieber gewesen nicht bei jedem überspielen den Programmes den 
Stromstecker ziehen zu müssen und anschließend den Programmerstecker 
abziehen zu müssen. (Von der Masse des Oszis ganz zu schweigen) Aber das 
war dem Elektroniker zu viel Arbeit...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.