Hi Arno.

Zitat Zitat von Olle_Filzlaus Beitrag anzeigen
... schonmal mit dem ADC auseinander gesetzt. Ist echt grauenhaft das Teil ...
Das kann ich so wirklich nicht stehen lassen. Ich habe den ADC z.B. in der Familie m168/m328 genutzt und es geht so prächtig, dass ich meinen Zweirädrer sogar ziemlich simpel balancieren lassen kann (klick zur Demo).

Vielleicht kannst Du mit dem Code für meine Controller etwas anfangen (nen ~128~ hatte ich noch nie) ? Der Code dient zum Auslesen eines Sharp-Entfernungssensors. Dann schau mal hier:
Code:
// ============================================================================== =
// ===  HAUPTProgramm =========================================================== =
// Initialisierungen, LED1 kurzblinken als Signal für Programmstart,
//   Ausgabe des Identifizierungsstrings per USART 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                         
 int main(void)
 {                      //
....
                        //
// Pins/Ports als Ein- (0) oder Ausgänge (1) konfigurieren, Pull Ups (1) aktivieren
//   A = Ausgang, E = Eingang ohne , EU = Eingang MIT PullUp
....
  DDRC  = 0b01110000;   // PC3 ist ADC3, PC0 .. 6 , kein PC7-Pin bei m168
  PORTC = 0b00000111;   // Beachte für ADC: PC3 ist ADC-Eingang ##>> OHNE Pullup !!
....
//  Dadurch Initialisierung der Anschlüsse für miniD0 auf mega328: - - - - - - - -
//          /RESET,PC6   1 A   A 28   PC5,(SCL), gLED
//             RxD,PD0   2 EU  A 27   PC4,(SDA), rLED
//             TxD,PD1___3 EU  E 26___PC3, ADC0=GP2D120
// SigMot1/ExtINT0,PD2   4 EU EU 25   PC2, SFH 5110, IN irDME 4     Rechts
// SigMot2/ExtINT1,PD3   5 EU EU 24   PC1, SFH 5110, IN irDME 3     Links
//   _|-- 3,4 Guz, PD4___6 A  EU 23___PC0, SFH 5110, IN irDME 1-2   Mitte
//     - - - - - - Belegung Pinne - - - - - - - - -
//          XTAL1  PB6___9 EU    20___VCC
//          XTAL2  PB7  10 EU EU 19   PB5, SCK, Taster2
//  PWM 1,2 uz+Guz,PD5  11 A   A 18   PB4, MISO,  _|-- 3,4  uz, (Taster1)
//  PWM 3,4 uz+Guz,PD6__12 A   A 17___PB3, MOSI, Reserve 2
//    _|-- 1,2  uz,PD7  13 A   A 16   PB2, Servo
//    _|-- 1,2 Guz,PB0  14 A   A 15   PB1, OC1A = SFH 415, OUT (irDME)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// ============================================================================== =
// ============================================================================== =
.....
 
 
Es folgen die Module für die ADC-Initialisierung und -Auswertung
/* ============================================================================== */
/* ===  Initialisierung fuer ADC    mega168   MIT Interrupt ========================
          ADC3/PC3 auf 10 Bit, Wandlung #####>>>>> Interrupt ausgelöst            */
void ADC3_10_init_irupt(void)   //
{      
  ADMUX  |= (1<<MUX1)|(1<<MUX0);        // Wandlung mit ADC3 
  ADMUX  |= (1<<REFS0);                // Referenzspannung ist Vcc       doc S 256
//          sowie https://www.roboternetz.de/phpBB2/ze...=287602#287602
  ADCSRA |= (1<<ADATE);         // Auto Triggering Enable           doc S 247 + 257
  ADCSRB |= (1<<ADTS1)|(1<<ADTS0);      // Triggersource = TC0 CmpA       doc S 260
                                // es wird also mit 1/1220 getriggert ca. 0,82 ms
  ADCSRA |= (1<<ADIE);          // ADC Interrupt Enable                   doc S 258
  ADCSRA |= (1<<ADEN);  // AD Enable
  ADCSRA |= (1<<ADSC);         // starte gleich die erste Wandlung
            
  adc3_cnt = 0;                 // ADC-Wert wird x-fach aufaddiert
  adc3_tmp = 0;                 // ADC-x-fach-Speicher
}
/* ============================================================================== */

/* ============================================================================== */
/* ===  Nicht unterbrechbare ISR für ADC3 auf Pin 26/PC3/mega168  =============== */
/* Routine übernimmt ADC-Wert und quittiert mit 170 ins Statusbyte.               */
ISR(ADC_vect)                   // _VECTOR(21)   
{                                 
  adc3_tmp     = ADC;                   // Hole Wert
  adc3_sum     = adc3_sum + adc3_tmp;   //   ADC-Werte aufsummieren
  adc3_cnt     = adc3_cnt + 1;          // Hochzählen Counter für ISR-Aufruf
            
  if (adc3_cnt == 4)            // Jeden vierten (zwölften!) ISR-Aufruf regeln
      rgl_mo_12();              // Aufruf Regeln für mo_12
                                 
  if (adc3_cnt == 8)             
      rgl_mo_34();              // Aufruf Regeln für mo_34
                                 
  if (adc3_cnt >= 12)           // Wenn Counter >= x, dann Messwert ausrechnen
  {                             //   Wenn adc3_counter < x, dann keine Aktion
    adc3_dat  = adc3_sum / 12;  // Gemittelten ADC-Wert ausrechnen
    adc3_sum  = 0;              // adc3_sum und Counter rücksetzen
    adc3_cnt  = 1;                
    PORTC ^=  (1<<PC4);         // Zeitmessung: Port PC4 toggeln
//  ADCSRA |= (1<<ADSC); // starte die nächste Wandlung
  }      
}           
/* ============================================================================== */

/* ============================================================================== */
/*### ADCwert für GP2D120 auf ADC3/PC3/Pin26 des ATMega168 z.B. auf m168D-Platine
 ================================================================================ */
// === Abholen des ADC-Wertes (keine Ausgabe, wenn ein neuer da ist?) ==============
// Codeschnippsel, ähnlich 22dzms168-regel-x13.c, eingefügt am 26mai2008 1126
//   ##>> DAZU unbedingt notwendig: Internen Pullup auf PC3 ausgeschaltet!! >> main
  int GPDist (void)             // Auswerten des aktuellen Messwertes mit dem Sharp
{
uint16_t GPDmm = 0, gpdtmp = 0;         // Messwert Distanz in mm, temporärer Wert
                                        // 
// Verbesserung, siehe hierzu auch Umrechnung im µC-Tabelle-Tool. Der Umrechnungs-
//   bezugswert "25600" gilt für eine Vesorgungsspannung von 5,00 V
  cli();                        // Datenübernahme Interruptgefährdet - 2 Byte
  gpdtmp     = adc3_dat;        // Übernimm Daten
  sei();                        // Gefahr vorbei
  GPDmm  = 25600 / gpdtmp;
  if (GPDmm  > 999)
  GPDmm  = 999;
  if (GPDmm  < 0 )
  GPDmm  = 0;
             
  return GPDmm;
}
// === Ende Abholen des ADC-Wertes und Ausgabe ===================================
/* ============================================================================== */