www.mikrocontroller.net

Forum: Compiler & IDEs Bitverarbeitung


Autor: Christian P. (sarstein)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen

Folgende Ausgangssituation:
MCU: ATtiny25, ca. 8Mhz mit internen Oscillator
Winavr:20090313
AVR-Studio: 4.18, SP2, Simulator2

Ich möchte den A/D-Wandler benutzen und das Ende der Wandlung abfragen.
Hier die relevanten Codeschnipsel:

#include  <avr/io.h>
....
init:
ADMUX  = 0b00100000; //left adjust, channel0 select
ADCSRA = 0b00000110; //125KHZ sample rate at 8MHz
....
ADCSRA |= _BV(ADEN); //enable ADC, bit7 of ADCSRA
....
ADCSRA |= _BV(ADSC); //start conversion, bit6 of ADCSRA
loop_until_bit_is_clear(ADCSRA,ADSC); //das geht nicht

alternativ hab ich versucht:
do
{
   tmp = ADCSRA; //tmp ist als lokale uint8_t variable zuvor definiert
   tmp &= 0x40;
}
while(tmp); //geht auch nicht

Folgendes Verhalten:
Im Simulator kann man beobachten, dass das ADSC bit gesetzt wird und 
nach ein paar loops wieder auf 0 geht.
Die SW bleibt aber im makro loop_until_.. hängen.
Im Datenblatt und im AVR-Simulator sind für Register ADCSRA 2 Adressen 
angegeben: 0x6 und 0x26. Im generierten Assemblercode wird 0x26 
verwendet, wogegen man im memory I/O Fenster des AVR-Simulators auf 
Adresse 0x6 die Veränderung des ADSC bit verfolgen kann. Auf Adresse 
0x26 passiert nichts.

Wo steckt da der Wurm?


Es gibt im AVR-Studio noch einen weiteren Punkt der seltsam ist:

In der Konfigurationseinstellung gebe ich 8MHz Takt an, der Simulator 
sagt aber nur 1MHz, im generierten makefile steht aber auch 8Mhz drin. 
Hat das etwa mit der Auswahl der Taktquelle zu tun?

Hat da einer von euch eine Idee die mir hilft? Schon mal danke im 
Voraus.
Christian

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian P. schrieb:
> Wo steckt da der Wurm?

Im Simulator?

Schau dir mal an, was im realen Silizium passiert.

Der Unterschied zwischen beiden Adressierungsarten ist eine
grundsätzliche Eigenheit der klassischen (nicht-Xmega) AVRs, darüber
solltest du dich mal im Datenblatt kundig machen, bevor du da
irgendwas mutmaßt.  Offenbar hast du auch die Optimierung
ausgeschaltet.

> im generierten makefile steht aber auch 8Mhz drin.

Das Makefile konfiguriert rein gar nichts, das teilt nur einigen
Routinen bzw. Makros (und zwar denen in <util/delay.h> und
<util/setbaud.h>) mit, von welcher CPU-Frequenz sie bei ihren
Rechnungen ausgehen sollen.  Dass diese CPU-Frequenz eingestellt
ist, darum musst du dich separat kümmern (per Fuses bzw. CLKPR).

Autor: Christian P. (sarstein)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg

Danke für die rasche Antwort. Habe noch kein reales Si.

Von unterschiedlichen Zugriffen auf I/O-Adressen des AVR habe ich schon 
gehört, aber aus dem Datenblatt bin ich da auch nicht wirklich schlauer 
geworden. Der wahre Überblick fehlt mir da noch.
In bin davon ausgegangen, daß der Winavr-Compiler das richtig macht und 
man den Simulator für so einfache Routinen nutzen kann, ehe man die HW 
am Tisch hat.

Die Optimierung habe ich tatsächlich abgeschaltet. Wollte das erst 
während des Projektverlaufes optimieren.

Gibt es keinen Weg das ohne Si zu testen?

Gruß
Christian

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian P. schrieb:

> Gibt es keinen Weg das ohne Si zu testen?

Du kannst im Simulator immer noch händisch auf jedes Bit in jedem 
Register draufklicken und es so von 0 auf 1 bzw. umgekehrt stellen. Dann 
ein paar mal F10, bis das Programm an die Stelle kommt, an der das Bit 
abgefragt wird, und schon sollte die Schose wieder laufen.

Einzig wenn es darum geht, dass irgendein Timer eine PWM generiert und 
daher ein Pin eigentlich bei bestimmten Zählerständen toggeln sollte, so 
hat der Simulator so manchesmal seine liebe Not damit.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> alternativ hab ich versucht:

Was ist falscg daran, die ADC Routine aus dem AVR-GCC-Tutorial als 
Ausgangspunkt zu nehmen?

Autor: Christian P. (sarstein)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Karl Heinz

Das Bit setzen & löschen im Sim. geht ja alles, einzig die Warteschleife 
will nicht. Weder der vorgegebene macro, noch die umständliche, 
selbstgestrickte do..while. Das Muster im Tutorial kannte ich nicht, 
probier ich mal.

Übrigens bei eingeschalteter Optimierung (Os anstatt ursprünglich O0) 
steht im Disassembler dann die Adresse 0x6 anstatt 0x26. Funktionieren 
tut das aber trotzdem nicht.

Danke, bis bald
Christian

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian P. schrieb:

> Übrigens bei eingeschalteter Optimierung (Os anstatt ursprünglich O0)
> steht im Disassembler dann die Adresse 0x6 anstatt 0x26.

Da macht der COmpiler den Zugriff anders. Kümmere dich nicht darum.
Im Debugger mit einer optimierten Variante durchzusteppen ist .... mutig

Autor: Christian P. (sarstein)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da bin ich noch mal

Also auch das Beispiel aus dem Tutor mag der Sim. nicht. Mit & ohne 
Optimierung bleibt da die SW in der Schleife
while (ADCSRA & (1<<ADSC) );
hängen. Da kann ich mit dem ADSC bit machen was ich will. Da scheint 
Atmel im Sim. noch einen bug zu haben. Jörg hat auch schon sowas 
angedeutet.

Der "Übermut" resuldiert daher, dass ich nur den code für die Funktion 
herauskopiert habe, um damit mal zu experimentieren.

Wenn ich noch mutiger wäre, würde ich das ganze in assembler schreiben. 
Bei der relativ überschaubaren Aufgabe könnte man das fast wagen. Aber 
es drängt die Zeit und es mangelt an Erfahrung.

Noch mal danke für die Unterstützung.

Christian

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du den "Simulator V2" benutzt?  Den müsste es doch für einen
ATtiny25 geben, oder?  (Sorry, ich habe kein AVR Studio hier.  No
Gates, no Windows.)

Der sollte zumindest den Digitalteil ordentlich simulieren.  Ansonsten
die errata notes zum AVR Studio genau lesen, ich glaube mich zu
erinnern, dass die bekannten Probleme in der Simulation in der Regel
auch dokumentiert worden sind.

Christian P. schrieb:
> Wenn ich noch mutiger wäre, würde ich das ganze in assembler schreiben.

Das bringt dir auch nichts, wenn es nur der Simulator falsch
simuliert.  Du kannst dem bisschen C-Code, das hinter "loop_until_..."
steht schon zutrauen, dass der Compiler das korrekt compiliert.  Da
bringt auch ein ebenfalls korrekt geschriebener Assemblercode keine
Änderung (wenn du ihn erstmal bis zu diesem Punkt hast).

Autor: Christian P. (sarstein)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg,

ja ich hab's mit Sim.V2 probiert, steht auch in meinem 1. thread. Auch 
die Studioversion ist die aktuellste. Der ATtiny25 ist mit dabei. Winavr 
gibt es in einer neueren Version. Bei dem trivialen code kann es 
eigentlich daran nicht liegen.
Die Mühe, vielmehr die Zeit die Atmel error lists durchzulesen habe ich 
mir noch nicht genommen. Vielleicht wird das ja heute meine 
Bettlektüre;-).

Also das mit dem Assembler überleg ich mir auch noch. Wahrscheinlich 
krieg ich da kalte Füsse.

Gruß
C.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian P. schrieb:
> ja ich hab's mit Sim.V2 probiert, steht auch in meinem 1. thread.

Sorry, hatte ich überlesen.  Dann sollte es allerdings auch
funktionieren.

Poste mal vollständigen, compilierbaren Code.

Autor: Christian P. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg

Anbei der auf die ADC-Anwendung reduzierte code.
Ich hab mit allen Optimierungsstufen alle 3 Varianten probiert. Im SimV2 
wird bit ADSC->0, aber er bleibt in der Abfrageschleife hängen.

Gruß
C.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann man den ADC (oder andere HW-Komponenten) initialisieren, wenn sie 
nicht aktiviert sind? Auf AVR hatte ich da mal irgendwo ein Problem, daß 
ich nach nem Sleep was konfirgurierte bevor ich das Modul aktivierte. 
UART oder Timer, vielleicht ist es beim ADV ja auch sowas?

Autor: Christian P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Johan

Der ADC wird mit dem Setzen des ADEN bits im ADCSRA Register aktiviert 
und mit dem Setzen von ADSC im selben Register gestartet.
Läßt sich im Simulator nachvollziehen.

Das Problem ist der deadlock bei der Abfrage von ADSC.

Gruß
C.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
init() wird doch vor ENABLE_ADC gemacht. Wie auch immer, wenn's geht ist 
ja ok.

Autor: Christian P. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Korrektur des sourcecodes.
Ich hatte im vorangehenden posting die variable tmp nicht definiert. 
Ohne der funktioniert Version2 der Abfrageschleife nicht.

C.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also:
Der generierte Code sieht richtig aus.
Ich denke das ist ein Fehler im Simulator.
Auf der GUI sieht man zwar, das das Bit gelöscht wird, dem Code wird es 
aber ständig als gesetzt präsentiert.
  //3. Version (aus dem tutorial)
  ADCSRA |= (1<<ADSC);  // eine ADC-Wandlung 
  uint8_t val = ADCSRA;
  while (val & (1<<ADSC))
    val = ADCSRA; // auf Abschluss der Konvertierung warten
}

val hat immer einen Wert von 196 == 0xC6 == ADSC ist gesetzt, unabhängig 
davon ob man händisch den Haken aus dem ADCSRA Register rausmacht oder 
nicht.

Autor: Christian P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servus Karl Heinz

Ich hab jetzt noch mal mehrfach die Initialisierungsreihenfolge 
verändert, aber das Ergebnis bleibt unbefriedigend. Mal sehen wie ich 
das den Atmelkameraden mitteilen kann.

Bleibt nur noch der Test an der realen HW.

Trotzdem euch allen herzlichen Dank für die Mühe und noch einen schönen 
Fußballabend.

Gruß
Christian

Autor: Christian P. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei mir im Sim. ändert sich der Wert im ADCSRA schon von C6 auf 86, aber 
aus der Schleife kommt er trotzdem nicht raus.

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.