Hallo,
ich möchte die interne Spannungsreferenz meines Atmega8 auf extern
unmstellen.
Das Datenblatt (S.206) lässt mich leider nicht schlau werden :-(
Muss ich dazu fuses umstellen oder gibt es eine programmcode anweisung?
Ich benutze das EasyAvr5a Board von Mikroelektronika und programmiere in
mikro Pascal...
Spielt es keine rolle, was an Aref anliegt, wenn intern aktiv? auf
meinem board messe ich nämlich 5V gegen masse.
Ich habe auch das pollin board und könnte im notfall auch mit basic
arbeiten.
thx
Hallo,
der Link erklärt ihm leider auch nicht, woher die weit verbreitete
Unsitte, selnst bei Demoboard-Desihnern, kommt, Aref extern an Vcc zu
legen.
Am Aref-Pin liegt die jeweils eingestellte referenzspannung, also Vcc,
2,56V oder eben eine externe nach Wunsch des Users.
Atmel empfihlt einen 100n Kondensator von Aref gegen GND um Stärungen zu
verringern.
Logischerweise gibt es über die internen MosFet-Schalter des AVR einen
Kurzschlu, wenn z.B. Aref auf den internen 2,56V steht und von außen 4V
anliegen. Das wird auf Dauern dem AVR nicht gefallen und bringt
selbstverständlich auch unsinnige Ergebnisse einer Wandlung.
Ich kann nur jedem empfehlen, sein Board darauf zu kontrollieren und
falls an Aref eine direkte Verbindung zur Betriebsspannung besteht,
diese aufzutrennen-
Gruß aus Berlin
Michael
> der Link erklärt ihm leider auch nicht, woher die weit verbreitete> Unsitte, selnst bei Demoboard-Desihnern, kommt, Aref extern an Vcc zu> legen.
Beim AT90S4433 war das noch sinnvoll. Und aus Gewohnheit bleiben einige
Board-Designer dabei, es wird ja bekanntlich mehr kopiert als
entwickelt.
Guten Rutsch,
~
Danke für eure antworten ...
dann läuft es also auf das problem hinaus, das ich nicht weis, wie ich
es meinem compiler klar machen soll, das ich Aref extern beziehen will.
Mein programm sieht derzeit so aus:
program pulsweitenmodulation;
var x: short;
var data : word;
begin
ddrb := $ff;
portb := $00000;
///// KEINE FUNKTION ERKENNBAR //////
// ADMUX - The ADC multiplexer Selection Register
MUX0 := 0; // Analog Channel and Gain Selection Bits
MUX1 := 1; // Analog Channel and Gain Selection Bits
MUX2 := 2; // Analog Channel and Gain Selection Bits
MUX3 := 3; // Analog Channel and Gain Selection Bits
//MUX4 := 4; // Reference Selection Bit 2
ADLAR := 5; // Left Adjust Result
REFS0 := 6; // Reference Selection Bit 0
REFS1 := 7; // Reference Selection Bit 1
admux := $5; // binary 101 --> 0000101 ?
///// KEINE FUNKTION ERKENNBAR //////
x := 1;
while true do begin
portb.0 := 1;
vdelay_ms(x);
portb.0 := 0;
vdelay_ms(50-x);
data:=Adc_Read(13);
if data < 300 then
begin
x := x+1;
portb.1 := 0;
end
else begin
portb.1 := 1;
end;
end;
end.
Der bereich in "keine funktion erkennbar" hab ich durch ewiges
rumstöbern in den mikroe foren gefunden. Bringen tut es nix.
Sobald ich ein weitere spannung, die von vcc abweicht an Aref hänge
fließt von Vcc nach Aref ein strom, was dem atmega wahrscheinlich kein
langes leben beschert.
Sind hier keine mikro Pascal programmierer ?
Hi
>Sind hier keine mikro Pascal programmierer ?
Wahhrscheinlich nicht so richtig.
> REFS0 := 6; // Reference Selection Bit 0> REFS1 := 7; // Reference Selection Bit 1> admux := $5; // binary 101 --> 0000101 ?
Aber du bringst hier etwas durcheinander. REFS0/REFS1 sind Bits in
ADMUX.
Erstens können Bits nur 1 oder 0 sein, und mit 'ADMUX=xyz' überschreibst
du alle vorhergehenden Einstellungen.
Ich weiss nicht, wie sich das 'micropascal' zu 'normalen Pascal'
verhält., aber du solltest dich mal über Shift-Operatoren und logische
Verknüpfungen informieren.
MfG Spess
Die refsel-Bits, 6 und 7 in admux müssen gesetzt sein, wenn die interne
ref-Spannung von 2,56 V gewünscht ist.
Bei der Zuweisung admux = $5 wird die Spannung als ref genutzt, die
extern angelegt sein muss und der ADC5-Eingang ist zugeschaltet.
Es müsste also m.E. ADMUX = $C5 heißen.
Siehe manual S.206
Doch doch, das ist mir klar, das sie bits von admux sind.
aber genau so hab ichs ja bei mikroe gefunden ...
und wenn admux := xyz alles überschreibt dürfte es ja keinen einfluss
haben.
ich bin davon ausgegangen, dass man erst sagen muss, was admux alles
beinhaltet, quasi definieren muss.
man sagt
REFS1 := 7; // Reference Selection Bit 1
76543210
admux: 00000101
bit an stelle 7 (von admux) ist dabei REFS1, welches den wert 0 trägt...
aber vielleicht denk ich mir das gerade nur so zurecht und alles ist
falsch :-(
Hi
Ich habe das 'micro pascal' mal kurz überflogen. Scheint noch schlimmer
als BASCOM zu sein. Wenn du mit Programmieren nicht in einer Sackgasse
enden willst, vergiss es.
MfG Spess
Die Tabelle aus dem Datenblatt zeigt die "Schalterwirkung" der REFS-Bits
in ADMUX.
Könnte es sein, dass Du noch Probleme mit Bits und Bytes hast?
Also das I/O-Register (das Byte) heißt ADMUX, die darin enthaltenen Bits
haben die im Datenblatt angegebenen Namen. Jedes Bit verkörpert dabei
einen Schalter (zur Steuerung der Hardware). Wenn Du einen Schalter
verstellen willst, dann musst Du darauf achten, dass die anderen nicht
beeinflusst werden. Alternativ setzt Du alle Bits auf einmal, indem Du
den entsprechenden Wert (0..255) in das Register schreibst. Die
wertigkeit der einzelnen Bits im Byte sollte Dir bekannt sein
(1,2,4,8,16,32,84,128), wenn nicht, dann solltest Du mal bei Wikipedia
nachschlagen. Falls doch, dann entschuldige ich mich vorsorglich... ;-)
Pascal machen hier Wenige, die Meisten machen C, ich bevorzuge ASM.
Guten Rutsch...
~
Meine Antwort steht anscheinend so weit unten, dass ich die Frage nicht
mehr wusste, sorry.
Damit man die extern angelegte referenz hat, muss Bit 6 und Bit7 von
ADMUX
gelöscht sein und eben an den Vref- Anschluss muss die externe vref auch
angelegt sein im admux muss also $5 stehen
Irgendetwas stimmt in den Pascal-Zeilen nicht:
Zwischen den // wird erstmal festgelegt, welche Nummern die
verschiedenen Bits haben, nicht welche Werte.
admux := $5 gibt m.E. dem Compiler an, dass die Adresse $5 die des
Registers admux ist, (admux hat aber eine ganz andere Adresse beim
atmega8 ).
Doch doch, ich denke das ist mir klar.
das Admux hat 8 bits.
Und die versuche ich zu konfigurieren.
Laut den tabellen im datenblatt und hier auf mikrocontrollernet denke
ich das
7 6 5 4 3 2 1 0
REFS1 REFS2 ADLAR - MUX3 MUX2 MUX1 MUX0
0 0 0 0 0 1 0 1
für Aref extern und ADC5 (Pin C5) richtig wäre... ist das soweit ok?
schade :-( ich hab es erst neu mit pascal gekauft.
HI
>admux := $5 gibt m.E. dem Compiler an, dass die Adresse $5 die des>Registers admux ist, (admux hat aber eine ganz andere Adresse beim>atmega8 ).
Also ich benutze Pascal in Form von Turbo Pascal und Delphi seit Jahren.
Den Ausdruck: 'admux := $5 ' würde ich jeder Zeit als Inhalt des
Speicherplatzes ADMUX=$5 ansehen.
MfG Spess
OK, aber wenn die Zuweisung von $5 an admux keine Wirkung hat, vermute
ich eben, dass dem Kompiler die Adresse von admux nicht richtig
zugewiesen ist.
und der Wert von $5 eben überall landet, nur nicht in admux.
Aber übrigens: Allen ein schönes neues Jahr und Tschüss, jetzt geh ich
feiern.
Ich habe das problem isoliert.
Die funktion adc_read resettet die bits von ADMUX auf einen
voreingestellten wert, bei dem z.B. die Interne Referenz aktiv ist.
wenn ich
ADMUX.7 := 0;
ADMUX.6 := 0;
ADMUX.5 := 0;
//ADMUX.4 := 0;
ADMUX.3 := 0;
ADMUX.2 := 1;
ADMUX.1 := 0;
ADMUX.0 := 1;
schreibe und adc_read rausnehme, liegt an Aref keine interne spannung
mehr an (habs gemessen)
leider kann man die funktionen nicht manipulieren, zumindest kenne ich
keinen weg dazu, ich habe nur den maschinencode aber der ist mir zu
komplex dazu.
Hi
Was mir noch aufgefallen ist: 'data:=Adc_Read(13);'
Laut Manual wird adc_read der Channel als Parameter übergeben. Der
ATMega8 hat aber nur 8 ADC-Channel, also 0...7. Die ADC-Bibliothek des
MicroPascal ist ja mehr als minimalistisch. An deiner Stelle würde ich
2-3 Funktionen mit Inline-Assembler machen und das Ganze ist gegessen.
MfG Spess
Vieleicht solltest Du nicht nur mit vorgefertigten Bausteinen arbeiten,
sondern mit eigenen Unterprogrammen?
Eine Funktion wie
1
data:=Adc_Read(13);
wäre mir sowiso suspekt, da sie dank Busywait den Programmablauf
blockiert. Denn die vorgefertigte Funktion muss ja dem ADC die
Messquelle einstellen, den ADC starten, das Ende der Wandlung abwarten
und das Ergebnis zurückliefern. Das würde mir zu lange dauern und
wertvolle Rechenzeit verplempern.
Dem ADC teilt man über ADMUX mit, was er messen (wandeln) soll, dann
wendet man sich wieder der Tagesordnung zu und erledigt andere
anstehende Aufgaben. Erst wenn der ADC fertig ist, liest man ihn (also
seine Register ADCL und ADCH) aus, gibt ihm die nächste Messaufgabe und
kehrt zur Tagesordnung zurück. Das Synchronisieren (melden, dass der ADC
fertig ist) kann durch den ADC-Interrupt erfolgen, aber auch durch einen
sowiso laufenden Timer. Während der ADC-Wandlung kann das Programm dann
andere Dinge erledigen, anstatt auf der Stelle zu treten und zu warten,
bis der ADC fertig ist.
In ASM könnte ich Dir Beispiele liefern, in PASCAL aber nicht. Ich würde
allerdings auch nicht auf die Idee kommen, den AVR (mit den knappen
Reccourcen) in einer maschinenfernen Hochsprache wie PASCAL oder BASIC
programmieren zu wollen. Selbst in (relativ maschinennahem) C ist neben
Kenntnissen der AVR-Architektur schon etwas ASM-Wissen erforderlich,
wenn das Programm einigermaßen effizient sein soll.
~
Du meinst, ich kann in den normalen pascal code assembler code
schreiben?
hast du ein beispiel dazu?
ich hab mich mit dem maschinencode nicht lange auseinandergesetz weil
ich schon in TP programmieren konnte und bisher auch alles recht schnell
zielführend war.
bei meinen programmen und ihrer geringen komplexität ist die
codestruktur glaube ich noch ausreichend.
Leider habe ich keine zeit jetzt ASM zu lernen deswegen werde ich daran
nicht mehr weiterarbeiten können bzw es über einen Op-Amp lösen und
hoffen das Mikro Elektronika eine neue libary entwickelt.
kann man eigentlich das tutorial hier gepackt runterladen?
Hi
>Du meinst, ich kann in den normalen pascal code assembler code...
Ja dafür gibt es die asm-Direktive.
Ich habe mir mal den von ADC_READ erzeugten Assemblercode angesehen. Das
Funktionsargument wird komplett an ADCMUX übergeben. Die Auswahl der
Referenz liesse sich hier einbinden. So in der Art:
data:=adc_read(Channel+(ref shl 6));
MfG Spess