Bitverarbeitung

OP #1747400
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
Moderator Persönliche Seite #1747415
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).
OP #1747445
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
#1747456
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.
OP #1747478
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
OP #1747515
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
Moderator Persönliche Seite #1747530
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).
OP #1747562
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.
Gast #1748947
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.
#1748973
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.
1
  //3. Version (aus dem tutorial)
2
  ADCSRA |= (1<<ADSC);  // eine ADC-Wandlung 
3
  uint8_t val = ADCSRA;
4
  while (val & (1<<ADSC))
5
    val = ADCSRA; // auf Abschluss der Konvertierung warten
6
}

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.
Gast #1748994
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

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