Ich habe hier ein für mich relativ unwitziges Problem. Das Problem tritt
bei allen Vertretern von ATtiny24 bis ATtiny84 auf (mit je 3 fabrikneuen
Controllern getestet).
Was ich möchte:
---------------
Ich möchte einen analogen Wert einlesen (vorzugsweise an PA3 - Channel
3) bei Verwendung der internen Spannungsreferenz einlesen.
Ausgangszustand:
- Nutzung ATtiny44 mit externem Quarz 16MHz mit Ziehkondensatoren 22pF,
Fuses-LO = 0xDE, Fuses-HI = 0xDF
- Nutzung ATtiny44 mit internem 8 MHz Takt, Fuses-LO = 0xE2, Fuses-Hi =
0xDF
- Am ATtiny ist ein TM1637 über PA1 für CLK und PA2 für DIO
angeschlossen (und jaaaaaaaaaaa, ich habe 1000 mal kontrolliert, ob ich
auch nur die Anschlüsse in DDRA verwende). Der TM1637 wird mittels
Bitbanging betrieben, keinerlei Hardware (außer eben den GPIO-Pins)
werden verwendet.
- im ATtiny laufen derzeit keinerlei Timer/Counter und auch kein
Interrupt
C-Funktionen des ADC's:
ADCSRB=0;// ADLAR = 0, ADC wird rechtsbuendig eingelesen
18
}
19
20
uint16_tadc_getvalue(void)
21
{
22
uint16_tresult;
23
24
ADCSRA|=1<<ADSC;// ADC starten
25
while(ADCSRA&(1<<ADSC));// warten bis ADC fertig ist
26
27
// wichtig: erst niederwertiges Byte lesen
28
result=ADCL;
29
result|=(uint16_t)(ADCH<<8);
30
returnresult;
31
}
Und in der Main:
1
adc_init(2,3);
2
3
while(1)
4
{
5
_delay_ms(500);
6
mwert=adc_getvalue();
7
tm16_setdez6digit_nonull(mwert,0);
8
}
Lasse ich den Code mit internem Taktgeber (8MHz) laufen funktioniert
alles wie es soll, lasse ich den Code mit externem Taktgeber laufen,
erhalte ich als Ausgabewert von adc_getvalue immer den Wert 1023
(0x3ff), egal welche Spannung ich anlege.
Initialisiere ich den ADC so, dass er die Vcc als Referenzspannung mit
adc_init(2, 3);
verwenden soll, liefert der ADC in beiden Fällen, externer Quarz und
interner Taktgeber, die erwarteten Werte.
Was mache ich falsch oder woran liegt das, dass ich die interne
Spannungsreferenz bei externem Takt nicht nutzen kann, bei internem Takt
aber schon.
Wieso habe ich dieses Verhalten bei Vcc als Spannungsreferenz nicht?
------------------------------------------------
PS: die letzte Zeit habe ich fast ausschließlich STM32 gemacht und den
ATtiny44 lange nicht mehr angefasst gehabt (bestimmt ein halbes Jahr).
Es kann also sein, dass ich einen äußerst dummen Fehler gemacht habe
(sogar eher wahrscheinlich, denn wenn nicht, würde es laufen).
Gruß,
JJ
Ralph S. schrieb:> Was mache ich falsch oder woran liegt das, dass ich die interne> Spannungsreferenz bei externem Takt nicht nutzen kann, bei internem Takt> aber schon.
Generell wird bei dir der ADC viel zu hoch getaktet. Du benutzt einen
Prescaler mit Teiler 2 und sowohl bei 8MHz und vor allem bei 16 MHz ist
das jenseits dessen, was Microchip vorschreibt, denn mehr als 1Mhz ist
nicht empfohlen.
Die besten Resultate gibts bei 50-200kHz ADC Takt.
Hallo, warum nutzt du nicht ADCW, zum lesen eines 10 bit Ergebnisses?
Was ist mit der korrekten Geschwindigkeit des ADC Wanders - Warum setzt
du die nicht?
Grrrrr, kaum schickt man eine Problemanfrage hier ab, liest seinen
eigenen Thread und dann fällt es einem wie Schuppen von den Augen, das
Problem ist das hier:
Matthias S. schrieb:> Generell wird bei dir der ADC viel zu hoch getaktet. Du benutzt einen> Prescaler mit Teiler 2 und sowohl bei 8MHz und vor allem bei 16 MHz ist> das jenseits dessen, was Microchip vorschreibt, denn mehr als 1Mhz ist> nicht empfohlen.> Die besten Resultate gibts bei 50-200kHz ADC Takt.
Nach dem Abschicken der Anfrage habe ich das auch gesehen gehabt ! Sorry
der Belästigung wegen
Ralph S. schrieb:> #if (F_CPU > 8000000)> ADCSRA = (1 << ADEN) | (1 << ADPS1); // ADC enable> ADPS1= 1; ADPS0, ADPS2 = 0 => adc-clock = F_CPU / 4> #else> ADCSRA = (1 << ADEN) | (1 << ADPS0); // ADC enable> ADPS0= 1; ADPS1, ADPS2 = 0 => adc-clock = F_CPU / 2> #endif
Das ist immer noch viel zu schnell. Bei 8 Mhz tuts ein :32 Teiler und
bei 16MHz dann der :64. Damit bist du bei 250kHz. Immer noch zu schnell,
aber klappt schon besser.
Matthias S. schrieb:> Das ist immer noch viel zu schnell. Bei 8 Mhz tuts ein :32 Teiler und> bei 16MHz dann der :64. Damit bist du bei 250kHz. Immer noch zu schnell,> aber klappt schon besser.
Ich habe jetzt grundsätzlich :64 eingestellt, egal ob der mit 8 oder 16
MHz läuft. Für die Anwendung für den ich den brauche ist das immer noch
schnell genug. Selbst dann, wenn der Tiny mit nur 1 MHz getaktet ist.
Vielen Dank
PS: Datenblatt lesen ist durch nichts zu ersetzen, außer durch noch mehr
Datenblatt lesen ... und zu einem gewissen Prozentsatz das Forum hier
lesen
: - )
Hallo Ralph S.,
ich berechne - lasse berechnen - den passenden Teiler durch einige
Macros.
Dann folgen noch einige Präprozessoranweisungen, die die korrekte
ADC-Frequenz, anhand zweier Randbedingungen, berechnen.
1
#define MIN_ADC_CLOCK (uint32_t)(50000) // see datasheet
2
#define MAX_ADC_CLOCK (uint32_t)(200000) // see datasheet
: - ) wie gesagt, es hat sich alles erledigt. Wer (wie ich) schlicht
nicht auf den Takt des ADC geachtet hat, braucht sich nicht wundern wenn
es nicht funktioniert.
Meine originale Routine war aus einem Softwareprojekt bei dem der Tiny
mit 1 MHZ gelaufen ist (und da hatte das dann logischerweise auch
funktioniert gehabt).
Ich hab mir in meine Sourcen einen wichtigen Vermerk gesetzt und nun
sollte mir so etwas nicht mehr passieren !
Gruß,
JJ
Ralph S. schrieb:> Meine originale Routine war aus einem Softwareprojekt bei dem der Tiny> mit 1 MHZ gelaufen ist (und da hatte das dann logischerweise auch> funktioniert gehabt)
Das ist etwas verwunderlich, weil selbst mit 1MHz der ADC gnadenlos mit
500kHz betrieben worden wäre.
Wir hatten mal darüber hier diskutiert. Erstaunlich war z.B., das bei
Zimmertemperatur sowas durchaus funktionieren kann, aber wenn es kälter
wird, klappts dann nicht mehr - so bei einem Tiny85, der hier zu jeder
Jahreszeit dicht unterm Dach läuft. Ab etwa 0°C stieg der mit 500kHz
getaktete ADC aus.
Matthias S. schrieb:> Das ist etwas verwunderlich, weil selbst mit 1MHz der ADC gnadenlos mit> 500kHz betrieben worden wäre.
Die 500 kHz sind für mich nicht verwunderlich, denn auf Seite 180 des
Datenblatt steht (für ADC Betrieb: single ended channels):
Clock frequency min: 50 kHz
Clock frequency max: 1000 kHz
(ich hab meine alte Dokumentationen gefunden und dort auch gesehen
gehabt, dass dort handschriftlich von mir steht: lt. Datenblatt nicht
mehr als 1 MHz).
Mein "Forscherdrang" jetzt hat jetzt allerdings ergeben (kein Mist, ich
habe es wirklich getestet), dass der ADC sogar noch mit 4 MHz Takt
funktioniert hat (nur eben mit 8 MHz dann nicht mehr).
In meinem Projekt läuft er jetzt mit 1 MHz (und funktioniert dort so
eingestellt auch gut, mit allen mir verfügbaren ATtiny24 bis ATtiny84
getestet).
Aber man kann ja zusätzlich in ADCSRA das Bit ADPS1 setzen, dann läuft
der mit 1/64 F_CPU, was bei 16MHz dann einem ADC-Takt von 250 kHz
entspricht.
(verrückt, welch Thread ein kleiner Fehler nach sich zieht, aber
andererseits bin ich froh, dass anderen sofort etwas auffällt, wenn man
selbst ein Brett vor dem Kopf hat).