Hallo zusammen. Ich würde gerne ab einer bestimmten Spannung, durch ein
Poti mittels Spannungsteiler erzeugt, eine LED anschalten und bei
unterschreiten wieder abschalten.
Zu diesem Thema gibt es mehrere Forenbeiträge.
Ich habe mir ein Steckboard mit einem Attiny 13 aufgebaut. Der Poti ist
an ADC0 (PB5) angeschlossen, die LED an PB4.
Die Spannung des Potis überwache ich parallel mit einem Multimeter.
Die Led geht bei Verstellen des Potentiometers ab einer Spannung von ca
>2.2V an.
Leider ist es egal welchen Wert ich für ADCH eingebe, der Ausgang
schaltet stets bei der Spannung 2,2V. Kann mir jemand helfen? Was mache
ich falsch?
Ich habe folgenden Code benutzt, nachdem ich etwas hin und her probiert
habe:
HildeK schrieb:> Bist du sicher, dass du den Reset-Pin (ADC0) als AD-Eingang nutzen> willst?
Das würde auf jeden Fall auch erklären warum sich der Wert nicht ändert,
wenn der Reset korrekt an einem 10k Pullup hängt :-)
Ich denke aber der 2. Fehler ist die Zeile (0 << MUX0), wobei eine 0
verodern auch nicht unbedingt sehr viel Sinn macht :-)
Besser so:
ADMUX |= (1 << MUX0);
Schau mal was ich gerade noch gegoogelt habe:
https://www.adnbr.co.uk/articles/adc-and-pwm-basics
Florian schrieb:> Du shiftest für MUX0 und MUX1 eine 0 ins ADMUX ???>> ADMUX |= (0 << MUX1); // ADC0> ADMUX |= (0 << MUX0);>> ist das denn richtig?
Jein.
Es wird keine Null geschrieben, wenn eine Eins drin stünde. Dann geht
das so nicht!
Per Default steht jedoch eine Null drin, aber wenn das Statement so mal
im Code steht, ist es leicht, aus der Null eine Eins zu machen.
Machen manche, um den Zustand zu verdeutlichen.
>ADMUX|=(1<<ADLAR);// Left adjust ADC result to allow easy 8 bit
5
>reading
Das hier ist großer Unfug. Die ersten 3 Befehle haben gar keinen Effekt.
Initial solltest du einmal einen Wert direkt nach ADMUX schreiben und
dabei alle Bits, die gesetzt sein müssen, entsprechend verodern. So wie
du es darüber für ADCSRA gemacht hast.
Atmel garantiert, daß der Pin 10% von VCC nach unten gehen darf, ohne
einen Reset auszulösen. Alles darunter ist tabu, es sei denn du
deaktivierst die Reset Funktion in den Fuses. Aber dann geht ISP auch
nicht mehr.
Das ist zumindest der Wert, den ich im Kopf habe. Genaues kannst du dem
DB entnehmen.
Stefan U. schrieb:> Das ist zumindest der Wert, den ich im Kopf habe.
Was du so alles im Kopf hast.
Laut Datenblatt ist Input High Voltage für den Reset 0,9V - Vcc+0,5V
Allerdings mit dem Zusatz "Not tested in production". Was immer das für
den tatsächlichen Wert bedeuten mag. Aber mit Vcc-10% liegst du völlig
daneben.
Hallo zusammen. Vielen Dank für die ganzen Antworten, wirklich sehr nett
und vor allen Dingen hilfreich.
Habe noch einmal einen anderen Beispielcode gefunden welchen ich benutzt
habe. Anfangs zeigte sich das gleiche Phänomen wie beim anderen Code. Es
lag tatsächlich am ADC0 welcher auf dem RESET Pin liegt. Habe den Code
auf ADC3 umgeschrieben und es hat sofort funktioniert.
Code sieht nun wie folgt aus:
1
#include<avr\io.h>
2
#include<util/delay.h>
3
unsignedintxx=0;
4
5
6
/////////////////////
7
//Poti ADC
8
/////////////////////
9
10
uint16_treadADC(uint8_tchannel)
11
{
12
uint8_ti;
13
uint16_tresult=0;
14
// die Versorgungsspannung AVcc als Referenz wählen:
15
ADMUX=(0<<REFS0);
16
// Set the ADC input to PB2/ADC3
17
ADMUX|=(1<<MUX0)|(1<<MUX1);
18
// Set the prescaler to clock/128 & enable ADC
19
ADCSRA|=(1<<ADPS1)|(1<<ADPS0)|(1<<ADEN);
20
21
ADCSRA|=(1<<ADSC);
22
while(ADCSRA&(1<<ADSC));
23
24
for(i=0;i<3;i++)
25
{
26
// Eine Wandlung
27
ADCSRA|=(1<<ADSC);
28
// Auf Ergebnis warten...
29
while(ADCSRA&(1<<ADSC));
30
31
result+=ADCW;
32
33
// ADC wieder deaktivieren
34
ADCSRA&=~(1<<ADEN);
35
36
result/=3;
37
38
returnresult;
39
}
40
}
41
42
main(void)
43
{
44
DDRB|=(1<<PINB4);// Set LED1 as output
45
while(1)
46
{
47
48
ADCSRA|=(1<<ADSC);
49
uint16_tresult=readADC(3);//Auslesen der analogen Spannungen an Pin 2,
Thomas Eckmann schrieb:
> Laut Datenblatt ist Input High Voltage für den Reset 0,9V - Vcc+0,5V
Dass heisst, alles ab 0,9V aufwärts ist garantiert High. Das bezieht
sich auf die Nutzung des Pins als I/O Pin.
Aber schau mal nach "RESET Pin Threshold Voltage". Das ist 0.2*VCC bis
0.9*VCC. Damit garantiert kein Reset ausgelöst wird, muss die Spannung
demnach höher als 0,9*VCC sein. Das sind die von mir genannten 10%
unterhalb VCC.
Siehe auch Kapitel 8.2.2 "External Reset" Figure 8.4 "External Reset
During Operation". Das Diagramm zeigt unmissverständlich, dass der Reset
ausgelöst wird, wenn die Spannung am Reset Pin unter VRST fällt. Und das
ist die eben genannte "RESET Pin Threshold Voltage".
Martin schrieb:> // die Versorgungsspannung AVcc als Referenz wählen:> ADMUX = (0<<REFS0);
Lass diesen Unsinn irgendwohin Nullen zu schieben wo eh schon Nullen
drin stehen.
Stefan U. schrieb:> Aber schau mal nach "RESET Pin Threshold Voltage". Das ist 0.2*VCC bis> 0.9*VCC.
Threshold heißt Schwellwert, also der Punkt wo RESET intern zwischen H
und L wechselt. Und der liegt irgendwo zwischen diesen Extremwerten. Der
typische Wert bei 5V Betriebsspannung liegt allerdins bei ca. 2,2V.
Siehe Diagramm.
Stefan U. schrieb:> Damit garantiert kein Reset ausgelöst wird, muss die Spannung> demnach höher als 0,9*VCC sein.
Genau. Deswegen sind die Schaltungen, die RESET als Analogeingang
oberhalb 2,2V nutzen eigentlich Pfusch.
M. K. schrieb:> Lass diesen Unsinn irgendwohin Nullen zu schieben wo eh schon Nullen> drin stehen.
Das ist nur in fertigem Code Unsinn, nicht unbedingt aber in Code, der
der Evaluierung dient.
Aber klar, wenn man sich mit der Peripherie schon sehr gut auskennt und
es deshalb kaum noch was zu evalieren gibt, mutet es natürlich wie
kompletter Unsinn an.
AAABER: sobald man mal wieder mit einer neuen, unbekannten Peripherie
konfrontiert wird, fällt man doch sehr schnell wieder darauf zurück.
Sicher nicht für jedes verschissene Bit, aber eben für die, deren genaue
Wirkungsweise man nach Lektüre des DB doch lieber selber noch mal
überprüft, weil das DB gewisse "Interpretationsspielräume" läßt...
Wem das noch niemals so gegangen ist, der ist kein Programmierer,
sondern ein C&P-Idiot, der noch niemals selbst die Leistung vollbracht
hat, irgendeine Hardware anzuknoten, sondern immer nur die Leistungen
anderer genassauert hat...
Stefan U. schrieb:> Dass heisst, alles ab 0,9V aufwärts ist garantiert High. Das bezieht> sich auf die Nutzung des Pins als I/O Pin.
Du solltest einfach mal ins Datenblatt gucken, anstatt hier irgendwas
umherzuplappern, was du meinst, im Kopf zu haben.
Input High Voltage ist 0,6V/0,7V - Vcc+0,5V, je nach Vcc.
c-hater schrieb:> Das ist nur in fertigem Code Unsinn, nicht unbedingt aber in Code, der> der Evaluierung dient.
Nein, das ist hier an der Stelle schlicht Unsinn, auch in der
Evaluierung.
c-hater schrieb:> Aber klar, wenn man sich mit der Peripherie schon sehr gut auskennt und> es deshalb kaum noch was zu evalieren gibt, mutet es natürlich wie> kompletter Unsinn an.
Dafür muss man sich nicht gut mit der Peripherie auskennen sondern nur
das Datenblatt lesen. Da hat man ja auch die Bezeichner her.
c-hater schrieb:> AAABER: sobald man mal wieder mit einer neuen, unbekannten Peripherie> konfrontiert wird, fällt man doch sehr schnell wieder darauf zurück.> Sicher nicht für jedes verschissene Bit, aber eben für die, deren genaue> Wirkungsweise man nach Lektüre des DB doch lieber selber noch mal> überprüft, weil das DB gewisse "Interpretationsspielräume" läßt...
Nur läßt es hier absolut keine Interpretation zu sondern ist eindeutig.
c-hater schrieb:> Wem das noch niemals so gegangen ist, der ist kein Programmierer,> sondern ein C&P-Idiot, der noch niemals selbst die Leistung vollbracht> hat, irgendeine Hardware anzuknoten, sondern immer nur die Leistungen> anderer genassauert hat...
Genau so sieht das Verschieben der Null aus: Da weiß jemand nicht was er
da tut, ist also völliger Unsinn. Und nur darauf hab ich hingewiesen.
c-hater schrieb:> Sicher nicht für jedes verschissene Bit
Wie kannst du so ein armes Bit, daß treu und brav seinen Dienst tut, als
verschissen bezeichnen?
Das ist ein Bit-Mobbing!
M. K. schrieb:> Martin schrieb:>> // die Versorgungsspannung AVcc als Referenz wählen:>> ADMUX = (0<<REFS0);>> Lass diesen Unsinn
Ja.
> irgendwohin Nullen zu schieben wo eh schon Nullen> drin stehen.
Das auch, aber das ist nicht der Punkt.
Ich habe es oben schon einmal geschrieben, aber offensichtlich haben das
einige nicht verstanden (insbesondere die nicht, die mir dafür -1
gegeben haben).
1. Man kann sich hier nicht darauf verlassen, daß ADMUX auf 0x00
steht. Selbst wenn das der Default nach Power-On Reset ist - wer
garantiert uns denn, daß der µC frisch aus dem Reset kommt? Der kann ja
genausogut vom BOD oder Watchdog resettet worden sein.
2. einzelne Bits zu setzen oder zu löschen ist genau dann richtig, wenn
a) die anderen Bits wirklich egal sind; z.B. weil es in dem Register nur
das eine Bit gibt, oder
b) man weiß, daß die anderen Bits den gewünschten Wert haben; z.B. weil
man den ADC vorher schon initialisiert hat und hier wirklich nur noch
den MUX umschalten will, oder
c) man die anderen Bits unabhängig vom derzeitigen Zustand gezielt nicht
anfassen will; z.B. um einen einzelnen Pin zu setzen.
keins davon ist hier gegeben. Darüber hinaus ist die derzeitige
Codesequenz
1
ADMUX=(0<<REFS0);
2
// Set the ADC input to PB2/ADC3
3
ADMUX|=(1<<MUX0)|(1<<MUX1);
auch noch länger (Codegröße und Ausführungszeit) als das bessere
1
// internal reference
2
// ADC input to PB2/ADC3
3
ADMUX=(1<<MUX0)|(1<<MUX1);
hier könnte man auf der rechten Seite noch alle 0-Bits entsprechend
aufzählen, wenn man es übersichtlicher findet (finde ich zwar nicht,
aber über Geschmack soll man nicht streiten)
Stefan U. schrieb:> Aber schau mal nach "RESET Pin Threshold Voltage". Das ist 0.2*VCC bis> 0.9*VCC. Damit garantiert kein Reset ausgelöst wird, muss die Spannung> demnach höher als 0,9*VCC sein. Das sind die von mir genannten 10%> unterhalb VCC.
Ja, jetzt sehe ich es auch, da bin ich schon öfter drüber gestolpert.
Betrachtet die Beträge von mir zu diesem Thema als nicht geschrieben.
Axel S. schrieb:> 1. Man kann sich hier nicht darauf verlassen, daß ADMUX auf 0x00> steht. Selbst wenn das der Default nach Power-On Reset ist - wer> garantiert uns denn, daß der µC frisch aus dem Reset kommt? Der kann ja> genausogut vom BOD oder Watchdog resettet worden sein.
Der Reset ist ja egal, nach einem Reset gelten die Initial/Values und
auf das Datenblatt muss man sich nun schon verlassen können.
> Ja, jetzt sehe ich es auch, da bin ich schon> öfter drüber gestolpert.
Wie meinst du das? Wenn Dir diese Eigenart des Reset Pins bereits öfters
Schwierigkeiten bereitet hat, warum hast du dann bis gerade eben
mehrfach meiner Erklärung trotz Bezug zum Datenblatt widersprochen?
Ich meine, sowas tust du doch bestimmt nicht ohne Überzeugung. Und senil
wirkst du auch keineswegs. Deswegen irritiert mich diese Satz sehr.
Wie kommt es zu dem plötzlichen Sinneswandel?
ich hatte das mit dem Reset bislang so verstanden:
Wenn der Resetpin High war, muss er aufgrund seiner breiteren Hysterese
auf < 0.2Vcc runtergezogen werden, um einen Reset auszulösen. War der
Resetpin low, muss er bis mindestens 0.9Vcc hochgezogen werden, um die
Hysterese nach oben zu überwinden und den Resetstatus zu beenden...
Das bedeutet nicht, dass der Bereich zwischen 0.2Vcc und 0.9Vcc instabil
oder undefiniert wäre. Nur der spannungsmässige Störabstand wird mit
zunehmender Nähe zur unteren Schaltschwelle eben kleiner.
Ja, so habe ich das auch verstanden. Wenn ich den Eingang also auch
analog nutze aud z.B. von 5V auf 3V runter ziehe, kann der Reset Impuls
nicht beendet werden, weil 3V kleiner als 0.9*VCC ist.