www.mikrocontroller.net

Forum: Projekte & Code ADC-Pin auch als Digital-Pin benutzen


Autor: Mehmet Kendi (mkmk)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Servus allerseits

Jetzt, nachdem ich die Lösung gefunden habe, kann ich über mich auch nur 
den Kopf schütteln.
Aber bis es soweit war, gingen 2 Tage verloren.
Hofffe, dass ich jemandem das ersparen kann.
Anfaenglich war
R2  82k
R5  27k
R14 2,2k
Die ADC hat auch wunderbar geklappt. Bis weitere IC's eingebaut wurden, 
die ebenfalls D0 benutzten.
Solange die Spannung nur vermindert wurde, also 4,2V -> 2,7V, stimmten 
die Werte. Sobald es aber wieder nach oben ging (2,7 -> 4,2), zeigten 
die Werte ab ca. 3V den max. Wert von 0x3FF an.

Die Lösung:
1. Widerstaende verkleinern.
2. Vor der Messung D0 auf Ausgang schalten und kurz auf GND ziehen.

PS: Der Sinn der Schaltung ist es die Betriebspannung zu erfassen.
//============================================================================
// ADC_read      Achtung: Bei angeschlossener UBS funktioniert die ADC nicht,
//                        weil FT245 an den Data-Ausgaengen 4,7V ausgiebt
//----------------------------------------------------------------------------
// Tiefpass-Filter:
// adc_akt   : akt. ADC-Messwert
// adc_value : akt. Mittelwert
// adc_tmp   : Mittelwert des letzten Zyklus
// k         : Integer Wert mit k > 1
//
// adc_value = (k-1)/k * adc_tmp + 1/k * adc_akt
//============================================================================
void ADC_read(void)
{
  DWORD tmp;
  WORD adc_akt;
  WORD adc_tmp;

  if ( USB_IS_CONNECTED )
  { adc_tmp   = 0x3FF;
    adc_value = 0x3FF;
    return;
  }
    
  ADCSRA &= 0xF8;
  if (BIT_IS_CLEAR(CLKPR, CLKPS0))  // --> 16,667 MHZ
    ADCSRA |= (1<<ADEN) | ( 1 << ADPS2) | ( 1 << ADPS1) | ( 1 << ADPS0); // division factor 128 -> 130 kHz
  else
    ADCSRA |= (1<<ADEN) | ( 1 << ADPS2) | ( 1 << ADPS1) | ( 0 << ADPS0); // division factor  64 -> 130 kHz

  
  // Um die Kapazitaet der angeschlossenen IC's zu entladen:
  BIT_SET(  ADC_DDR,  ADC_PIN_INPUT);    // Pin PA0 wird output
  BIT_CLEAR(ADC_PORT, ADC_PIN_INPUT);    // Pin PA0 auf LO ziehen
  my_delay_us(10);                       // wichtig!!
  BIT_CLEAR(ADC_DDR,  ADC_PIN_INPUT);    // Pin PA0 wird wieder input

  BIT_SET(ADC_DDR, ADC_PIN_OUTPUT);     // Pin PA1 wird output
  BIT_SET(ADC_PORT,ADC_PIN_OUTPUT);     // Pin PA1: Vcc (damit Widerstaende Spannung erhaelt)
  DIDR0  |= ( 1 << ADC0D);              // disable digital input
     
  my_delay_ms(1);
  
  ADCSRA |= ( 1 << ADSC );  // enable ADC and start conversation

  // warten bis conversation beendet
  while(  BIT_IS_SET(ADCSRA, ADSC));
  adc_akt  = ADCL;
  adc_akt |= ADCH << 8;
   
  BIT_CLEAR (ADC_PORT,ADC_PIN_OUTPUT);  // Pin A1: LO
  BIT_CLEAR (ADC_DDR, ADC_PIN_OUTPUT);  // Pin A1 wird wieder input
  BIT_CLEAR (ADCSRA, ADEN );            // disable ADC
  DIDR0  &= ~( 1 << ADC0D);             // enable digital input

  if (adc_value == 0L)
  { adc_value = adc_akt;
    adc_tmp   = adc_akt;
  }
  else
  {
//    tmp =  (DWORD)adc_tmp * 75L + (DWORD)adc_akt * 25;    // k =4
//    adc_value = tmp / 100L;
    tmp =  (DWORD)adc_tmp * 875L + (DWORD)adc_akt * 125;  // k =8
    adc_value = tmp / 1000L;
    adc_tmp = adc_value;
  }
  
  if (adc_value <= VOLT_3p0)
    cam_status.low_battery = true;
  
  if (cam_status.low_battery)
  { if (adc_value > VOLT_3p2)
      cam_status.low_battery = false;
  }
}


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mehmet Kendi schrieb:

> Die Lösung:
> 1. Widerstaende verkleinern.
> 2. Vor der Messung D0 auf Ausgang schalten und kurz auf GND ziehen.
>
> PS: Der Sinn der Schaltung ist es die Betriebspannung zu erfassen.

Oder die Systematik ändern, falls der AVR-µC dies unterstützt.
* Als Eingang wird die Bandgapspannung benutzt.
  Bei einem Mega16 ist dies zb die MUX Kombination 11110
* Als Referenzspannung wird die Versorgungsspannung benutzt
  Bei einem Mega16 ist dies zb REFS Kombination 01

Da die Bandgapspannung konstant bei etwa 1.22V bleibt, während die 
Referenzspannung sich verändert, ändert sich auch der Zahlenwert vom 
ADC, wenn sich die Versorgungsspannung ändert. Steigende Werte bedeuten 
eine sinkende Spannung.

Vorteil: Keinerlei Aussenbeschaltung notwendig. Der ADC-Pin kann für 
andere Aufgaben benutzt werden. Die von Atmel vorgegebene Einschränkung, 
dass keine Schaltvorgänge am Port gemacht werden sollen, solange eine 
Messung im Gange ist, sollte auch in diesem Fall eingehalten werden.

Autor: Mehmet Kendi (mkmk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servus Karl Heinz

Ich war auswaerts taetig, weshalb ich erst jetzt dazu komme zu 
antworten.

Dein Vorschlag ist schlichtweg genial. Waerend dem Entwurf der Schaltung 
hatte ich mich wochenlang darüber geaergert, dass die Atmels keine 
interne Betriebsspannungs-Anzeige hatten.
Und waere Deine Antwort nicht so ausführlich gewesen und haettest Du nur 
gesagt "schau dir das MUX-Register an, dort gibt es eine solche Lösung" 
... also um ehrlich zu sein, ich waere nicht darauf gekommen. Einfach 
genial.

Nur einen kleinen Schönheitsfehler hat diese Art der Messung. Waerend 
ich mit meiner Lösung den Bereich zwischen 2,6V und 4,2V mit 410 
Schritten auflöse, komme ich mit Deiner Lösung nur auf 160 Schritte. 
Aber für meine Zwecke reicht das allemal.
Dafür hat aber Deine Lösung den Vorteil, dass die Werte auch ohne 
Tiefpassfilter sehr stabil daherkommen.

Nochmals vielen herzlichen Dank.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mehmet Kendi schrieb:

> Dein Vorschlag ist schlichtweg genial.

Ehre wem Ehre gebührt. Die Idee dazu kursiert seit langem hier im Forum. 
Ich glaube ich habe sie das erste mal von Hannes Lux aufgeschnappt.

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ATMEL selbst hat AppNotes veröffentlicht, wo diese Möglichkeit erklärt 
wird.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.