Forum: Mikrocontroller und Digitale Elektronik Problem mit AD-Wandler


von Osmaniak (Gast)


Lesenswert?

Hallo Leute,

ich habe mit einem Atmega8 eine binäre LED Uhr aufgebaut, die 
funktioniert soweit wunderbar. Jetzt möchte ich noch eine binäre 
Temperaturausgabe hinzufügen. Dazu greife ich die Spannung an einem 
Spannungsteiler bestehend aus einem Widerstand und einem PTC-Widerstand 
(PT1000) ab. Diese gebe ich auf PC0. Als Beschaltung für den Atmega 
benutze ich die folgende Schaltung:
http://www.mikrocontroller.net/wikifiles/9/9e/Adc_connection.png
(Der Spannungsteiler ist dort nicht eingezeichnet ;-), er existiert aber 
in meiner Schaltung)

Anbei ist mein Programm.
Wenn ich dieses aufspiele läuft die Uhr, wenn ich aber auf den 
Temperaturmodus umschalte leuchtet keine LED, allerdings sollten die 
LEDs, die an Port D angeschlossen sind doch zumindest irgendwie leuchten 
;-).
Ist PC0 als Eingang richtig konfiguriert?
Wer entdeckt meinen Fehler?


#include "Main.h"
#include "externe_Variablen.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

//Variablen deklarieren
volatile unsigned sekunden=0;
volatile unsigned minuten=0;
volatile unsigned stunden=0;
volatile unsigned i=0;
volatile unsigned j=0;

int main(void)
{

  cli(); //Interrupt schließen

  // Eingänge-Ausgänge konfigurieren
  DDRC=0x3E;
  DDRD=0x3F;
   DDRB=0x3F;

  init_adc();      //Analog-Digital Konverter initialisieren
  init_Timer1();  // Timer1 Initialisieren

  unsigned adcwert;

  sei(); //Interrupt starten

  //Polling Loop
  while(1)
  {
    if (key_pressed(&PIND, PD7))
    {
      j++;
    }

    if (j%2)
    {
      adcwert = ADC_average(0,10);
      PORTD = adcwert;
      PORTC = 0x00;
    }
    else
    {
      binaer_uhr_stellen();
      binaer_uhr_ausgeben();
    }
  }

  return 0;
}




// Funktion: Binäruhr
void binaer_uhr_stellen()
{
  if (key_pressed(&PIND, PD6))
  {
    if(i<=2)
    {
      _delay_ms(20);
       _delay_ms(20);
      _delay_ms(20);
       _delay_ms(20);
      _delay_ms(20);
       _delay_ms(20);
      _delay_ms(20);
       _delay_ms(20);
      _delay_ms(20);
      _delay_ms(20);
       _delay_ms(20);
       sekunden=60;
    }
    if(i>2)
    {
      sekunden=60;
    }
  }
  else
  {
    i=0;
  }

  if (sekunden==60)
  {
    sekunden=0;
    minuten++;
    if(minuten==60)
    {
      minuten=0;
      stunden++;
      if(stunden==24)
      {
        stunden=0;
      }
    }
  }
}


void binaer_uhr_ausgeben()
{
  PORTD = sekunden;
  PORTB = minuten;
  PORTC = stunden<<1;
}



// Function: Taste gedrückt + Entprellen
uint8_t key_pressed(volatile uint8_t *port, uint8_t pin)
{
  // active low button: Bit nicht gesetzt
  if ( ! (*port & (1 << pin)) )
  {
    _delay_ms(20);
    _delay_ms(20);
    _delay_ms(20);
    _delay_ms(20);
    _delay_ms(20);

    if ( ! (*port & (1 << pin)) )
      return 1;
  }
  return 0;
}

void init_Timer1()
{
  //Timer initialisieren:
  TCCR1A = 0x00;
  TCCR1B|= (1<<CS00)|(1<<CS02)|(1<<WGM12);    //Prescaler 1024, CTC-Mode
  OCR1A = 4096;                                //Vergleiswert setzten 
// normal 4096
  TIMSK = (1<<OCIE1A);                        //OC-Interrupt aktivieren
}


// ISR Timer1
ISR(TIMER1_COMPA_vect)
{
  //Uhrzeit berechnen:
  sekunden++;
  if (sekunden==60)
  {
    sekunden=0;
    minuten++;
    if(minuten==60)
    {
      minuten=0;
      stunden++;
      if(stunden==24)
      {
        stunden=0;
      }
    }
  }

  if (key_pressed(&PIND, PD6))
  {
    i++;
  }


  TIFR |= (1 << OCF1A);    // Timer Interrupt Flag löschen
}



// Funktion ADC Initialisieren:
void init_adc()    // ADC initialisieren
{
  uint8_t result;  // Dummy für auslesen des ADC

  ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<ADLAR);    // AvCC als Referenz 
// Um nur das High-Byte-auszulesen, da Low-Byte wird als rauschen 
verworfen
  ADCSRA = (1<<ADPS2) | (1<<ADPS0) | (1<<ADEN);    // Vorteiler des ADC 
auf 32 // ADC aktivieren

  // Dummy-Readout:
  ADCSRA = (1<<ADSC);                  // Start Single Conversion
  while((ADCSRA & (1<<ADIF)));        // warten bis Wandlung 
abgeschlossen ist
  result = ADCL;
  result = ADCH;
}


uint16_t ADC_Read( uint8_t channel )
{
  uint8_t result;  // Dummy für auslesen des ADC
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);  // Kanalauswahl

  ADCSRA =  (1<<ADSC);                           // Start Single 
Conversion
  while((ADCSRA & (1<<ADIF)));                  // warten bis Wandlung 
abgeschlossen ist
  result = ADCL;
  return ADCH;
}



// Funktion: ADC auslesen und Mittelwert bilden:
uint16_t ADC_average( uint8_t channel , uint8_t average )
{
  uint16_t result=0;
  for (uint8_t k=0 ; k<average ; k++)
  {
    result += ADC_Read( channel );
  }
  result /= average;
  return result;
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.