PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ADC-Pin Pullup aktivieren



demmy
19.04.2017, 18:46
Hallo zusammen,

ich habe eben versucht an einem ADC-Pin eines Atmega328p den internen Pullup zu aktivieren und mittels des Bascom-Befehls GetAdc anschließend den ADC-Wert auszulesen.
Man sollte doch davon ausgehen, dass man dann den Wert 1024 zurück bekommt. Ich bekomme allerdings flatternde Werte, wie wenn der Pin offen hängt.
Kann es sein, dass der Befehl GetAdc den Pullup wieder ausschaltet bevor er mit dem Messen anfängt?

Ich hoffe Ihr habt eine Idee wieso das so ist?

Viele Grüße

oberallgeier
19.04.2017, 18:56
.. ADC-Pin eines Atmega328p den internen Pullup .. Man sollte doch davon ausgehen, dass man dann den Wert 1024 zurück bekommt ..Maximaler Rückgabewert ist 1023.

Ich kann kein Bascom, aber schließ doch mal einen Widerstand, sagen wir mal so 10k bis 40k an den entsprechenden Pin gegen Vcc (5V oder 3,3V). Das ist ein "externer" Pullup. Dann solltest Du die 1023 sehen . . .


.. habt eine Idee wieso das so ist? ..Da gibts einige Möglichkeiten (die meisten habe ich schon hinter mir): falsche Initialisierung des ADCs (denke an die Mindest-Samplezeit - siehe Dokumentation), Pin als Ausgang deklariert, falscher Pin abgefragt, Pin falsch abgefragt (Abfrage benutzt den Namen z.B. PINB, PB4 und nicht PORTB, PB4) und leider noch etliche mehr :-/

demmy
19.04.2017, 20:01
Hi,

ich habe jetzt mal einen externen widerstand angeschlossen und jetzt sehe ich auch die 1023.
Bei der Aktivierung des internen pullups bin ich mir absolut sicher das ich das richtig gemacht habe!
Bei den benachbarten Pins ist der pullup auch an wie es sein soll.

Klebwax
19.04.2017, 22:51
Ich sehe da zwei Möglichkeiten:

1. Der Prozessor läßt es nicht zu, daß der Pullup aktiviert ist, wenn der Pin auf analog geschaltet wird. Das sollte ein Blick in das Datenblatt klären.

2. Bascom schaltet den Pullup ab, wenn der ADC aktiviert wird. Ob das im Bascom Manual steht?

MfG Klebwax

Searcher
20.04.2017, 07:21
Hallo demmy,
ich habe ein BASCOM-Miniprogram mit den beiden Kommandos CONFIG ADC und GETADC kompiliert und den Maschinencode angeschaut. Der Pullup-Widerstand wird da nicht angefaßt.

In den schematischen Zeichnungen im Datenblatt kann ich auch nicht erkennen, daß durch die HW automatisch bei Messung der interne Pullup-Widerstand abgeschaltet werden könnte (kann ich natürlich nicht richtig interpretiert haben und trotzdem sein).

Um Dein Programm wirklich auszuschließen, poste es doch mal hier. Wenn es nicht zu umfangreich ist, könnte ich es auf einem ATMega88 mal laufen lassen, der ja bis auf die Speichergröße gleich ist.

Welche BASCOM Version ist es und welche genaue Bezeichnung hat der µC?
Ist AVCC mit Spannung versorgt und der betreffende ADC-Pin gänzlich unbeschaltet?

Gruß
Searcher

oberallgeier
20.04.2017, 08:49
Noch ne Frage: welche Plaltine (Schaltung?) benutzt Du und welchen ADC-Pinn genau? Atmega328p als SMD? Der hat ja ADC6 und ADC7 verfügbar die beim PDIP NICHT zur Verfügung stehen.


.. ich habe jetzt mal einen externen widerstand angeschlossen und jetzt sehe ich auch die 1023 ..Wie wärs, wenn Du jetzt als externes Signal für den ADC-Pinn einen Spannunsteiler baust - so etwa 50 % Vcc, danach nochn Test mit rund 30% Vcc und Dir danach den ADC-Wert ausgeben lässt. Das sollte sinnvolle Ergebnisse bringen - wenn "alles" korrekt läuft.

Anm.: ich hatte schon Controller so krank bekommen, dass die liefen - aber nicht mehr zu flashen waren, dass man sie flashen konnte, aber EINZELNE Pinne tatens nicht bzw. nicht korrekt usw usf. Die Tests könnten so einen Fehler eingrenzen oder aufdecken.

Weiter mit nem Test von eben.
Ich benutzte hier als IDE AVR Studio 4.18 Build 700. Aktuell ein Test mit (m)einer Servotester-Software, in C, für nanoclone 328p/20 MHz (!!) mit Poti 10K auf ADC7 zum Variieren der Servoposition. Initialisierung - in C!
// ================================================== =========================== =
// === Initialisierung fuer ADC/mega328/ADC7 MIT Interrupt free running
// === ADC7/PC7 auf 10 Bit, fertige Wandlung ###>>> löst Interrupt aus
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ADC0_i10free (void) // Init m328/ADC7, 10 Bit, free runn. Interrupt
{ // Kanal 0 <=> Temperatur RN VNRN-VN2
// - - - - - - - - - - - - - - - Datenblatt 8271C-AVR-08/10
ADMUX |= (1<<MUX2)|(1<<MUX1)|(1<<MUX0); // 264
ADMUX |= (1<<REFS0); // Referenzspannung ist AVcc S 263
//
ADCSRA |= (1<<ADEN); // ADC Enable 264
ADCSRA |= (1<<ADSC); // starte gleich die erste Wandlung 264
ADCSRA |= (1<<ADIE); // ADC Interrupt Enable 265
ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); // Prescal clock/128 265
ADCSRA |= (1<<ADATE); // Auto Triggering Enable 265
// es wird bei clock 20 Mhz mit ca. 80 µs getriggert
// genauer: ca 12 Zyklen in 1 ms <=> 1200 Hz
In_adc = 0; // Durchlaufzähler ADC zum Kanalumschalten
} // Ende von void ADC_in_10free(void)
// ================================================== =========================== =Und dabei war es beim Test von eben unerheblich, ob ich den Pinn bei Programmbeginn auf 1/1 (DDRC7 = 1 / PORTC7 = 1 <=> Ausgang mit Pullup) oder 0/0 (DDRC7 = 0/ PORTC7 = 0 <=> Eingang ohne Pullup) oder 0/1 (DDRC7 = 0/ PORTC1 = 0 <=> Eingang mit Pullup) stellle - das LCD zeigt stets die richtigen ADC-Werte an und der Servo läuft unabhängig von der Pininitialisierung immer sinngemäss richtig.

......https://dl.dropbox.com/s/y3i8m4gjdlr75nk/Servotester_2822-33proz.JPG?dl=0

demmy
20.04.2017, 13:30
Hallo zusammen,

vielen Dank für euere Rückmeldungen.
Die Lösungen des Problems war ebenso so banal wie einfach. Ich habe gestern Abend das Datenblatt des µC nochmal durchgelesen und musste, wie oberallgeier auch schon geschrieben hat, feststellen, dass es in der SMD-Version zwei Pins zusätzlich gibt. Nämlich genau ADC6 und ADC7.
Diese beiden Pins sind wirklich reine ADC-Pins und haben keinen Pullup. Und natürlich hatte ich genau einen dieser beiden Pins in der Mangel. :-D

Ich habe jetzt mal einen der übrigen ADC-Pins verwendet und siehe da, es funktioniert alles!

Mit der Hilfe des Pullups sollte es jetzt möglich sein zu bestimmen ob ein Sensor angeschlossen ist oder nicht.

Vielen Dank nochmal für eure Unterstützung!

oberallgeier
21.04.2017, 16:09
.. in der SMD-Version zwei Pins zusätzlich .. ADC6 und ADC7 ..Datenblatt lesen klingt ja schon mal gut. Bitte beachte u.a.:
1.1.9 ADC7:6 (TQFP and QFN/MLF Package Only)
In the TQFP and QFN/MLF package, ADC7:6 serve as analog inputs to the A/D converter.
These pins are powered from the analog supply and serve as 10-bit ADC channels.und
23.9.5 DIDR0 – Digital Input Disable Register 0
• Bits 7:6 – Reserved
These bits are reserved for future use. To ensure compatibility with future devices, these bits
must be written to zero when DIDR0 is written.
..
Note that ADC pins ADC7 and ADC6 do not have digital input buffers, and therefore do not
require Digital Input Disable bits.

Peter(TOO)
22.04.2017, 21:51
Hallo demmy,

Für mehr als grobe Tests kann man den PullUp aber nicht brauchen.

Zwischen Minimal- und Maximal-Wert des Widerstands liegt ein Faktor 2x.
Der Widerstand ist enorm Temperaturabhängig.

MfG Peter(TOO)

oberallgeier
23.04.2017, 09:58
Hi demmy!

.. Für mehr als grobe Tests kann man den PullUp aber nicht brauchen ..Der interne PullUp lässt sich verhältnismässig einfach messen.

Vorbereitung :
a) Nimm einen (beispielsweise) 10 kΩ - Widerstand
b) Wenn Genaugikeit gewünscht: messe den Widerstandswert genau
c) Programmiere den zu prüfenden Pinn als Eingang mit PullUp
d) Der zu prüfende Pinn ist ansonsten UNBESCHALTET zu lassen!
e) Starte den Controller

Messung :
f) Messung GND gegen Prüfpinn - Beispiel 5,00 V
g) Verbinde GND mit Prüfpinn über den Widerstand aus a)
h) Messung GND gegen Prüfpinn über Widerstand. Beispiel 1,101V

Auswertung:
Behauptung: der Spannungsabfall über internen Pullup und über Widerstand "a)" ist 5,00 V, siehe f). Die Spannungsdiffernenz "f)" - "h)" ist der Spannungsabfall des internen Pullups <=> Reihenschaltung der Widerstände.

U(PullUp) = 5,00V - U(Widerstand 10k) = 5,00V - 1,101V = 3,899V
I(Widerstand 10k) = U/R(10k) , hier: 1,101V/10kΩ
R(PullUp) = U(PU) / I (10k) => 3,899V / (1,101V/10k) = 35k4

Der interne Pullup bei Messbedingungen betrug bei meinem Beispiel 35 kΩ (Messung PU von PINB2 eines mega328/nanoclone-20MHz bei Raumtemperatur).

Peter(TOO)
24.04.2017, 01:55
Hallo Geier,

Wie man einen unbekannten Widerstand mit Hilfe einer Spannungsquelle, eines Referenz-Widerstandes und einem Voltmeter bestimmen kann, weiss ich schon seit 50 Jahren :-)

Allerdings vergisst du dabei, dass so ein PullUp kein Widerstand, sondern ein entsprechend dimensionierter FET ist.
Der Widerstand ist recht temperaturabhängig. Die Chiptemperatur hängt also auch davon ab, was an den Ports direkt neben dem PullUp so los ist. Muss da ein Ausgang viel Strom liefern, erwärmt sich der Chip lokal.

Hinzu kommt noch, das der On-Widerstand eines FETs auch noch von der angelegten Spannung abhängt, also nicht konstant ist.
Versuche deine Messung auch einmal mit unterschiedlichen Widerständen, wie z.B. 1k und 100k und nicht nur mit einem 10k.

MfG Peter(TOO)

oberallgeier
24.04.2017, 14:27
.. Wie man einen unbekannten Widerstand .. bestimmen kann ..Ohh, Peter, tut mir leid, Adressats meines Beitrags war der TO demmy. Bitte entschuldige mich, dass ich das so missverständlich geschrieben habe, dass Du als Adressat verstanden werden konntest. Das war keinesfalls so - im Gegenteil - ich bin ja selbst oft Nutzer von Deinem umfangreichen Wissen. Das mit dem FET ist mir (aber erst seit einigen Jahren) bekannt, soweit ich das als (Elektronik)Newbie als bekannt bezeichnen kann *gg*.


.. Versuche deine Messung auch einmal mit unterschiedlichen Widerständen, wie z.B. 1k und 100k und nicht nur mit einem 10k ..Jaa, wieder mal Futter für meinen Testhunger und meinen Wissensdurst. Danke.