mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit externer ADwandler und Atmega16


Autor: smith (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

ich habe die 8bit Ausgänge von externer adwandler an PORTC von Atmega16 
angeschlossen.adwandler funktioniert gut
das problem liegt daran wenn ich die 8bit werte aus dem PORTC lesen will 
und damit ein LED anschalte bleibt der LED an auch wenn ich den Wert 
überschreite.
hiermit meine Source code:
Danke im Voraus für die hilfe

#define NR_SAMPLES 3    // Anzahl der Messungen, die gemittelt werden
#define LED1  PD0
#define OE    PD6
#define START PD7
#define C     PA6
#define B     PA5
#define A     PA4
#define data  PORTC

unsigned char ADC0809(unsigned char channel);
void init_ports();
int main()
{

  unsigned char d;

  init_ports();
  TIMER1_interrupt_init();

 sei();

  while( 1 )

  {
    d=ADC0809(0);
    if ( d < 125 )
    PORTD |= (1<<LED1);
    else PORTD &= ~(1<<LED1);
  }
}

void init_ports()
{
DDRD=0xFF; //PORTD als Ausgang
PORTD =0x00;
DDRC=0x00; //PORTC als Eingang
PORTC =0xFF;
}
unsigned char ADC0809(unsigned char channel)
{
  unsigned char adwert;
  unsigned char j;

  if ( channel == 0 )
  {
   PORTA &= ~ ( 1 << A) | ( 1 << B) | ( 1 << C) ;
  }
  if ( channel == 1 )
  {
   PORTA &= ~ ( 1 << B) | ( 1 << C) ;
   PORTA |=   ( 1 << A);
  }
  if ( channel == 2 )
  {
   PORTA &= ~ ( 1 << A) | ( 1 << C) ;
   PORTA |=   ( 1 << B) ;
  }
  if ( channel == 3 )
  {
   PORTA &= ~ ( 1 << C) ;
   PORTA |=   ( 1 << A) | ( 1 << B) ;
  }

  PORTD |=  ( 1 << START );
  PORTD &= ~( 1 << START );

  while( !(PINA & (1<<PINA3)) ) ;     //check for EOC to go high
  for( j = 0; j < NR_SAMPLES; j++ )
  {

   PORTD |=  ( 1 << OE );//enable output data
   adwert += data;      //read data
   PORTD &= ~ ( 1 << OE );            //disable adc
  }
  PORTD &= ~ ( 1 << OE );
  adwert /= NR_SAMPLES;


return adwert;          //return data
}

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
smith schrieb:
> PORTD |=  ( 1 << OE );//enable output data
>    adwert += data;      //read data

Beim Einlesen eines Port-Werts hast Du eine Verzögerungszeit (1 Takt). 
Somit liest Du hier den Wert ein, der anlag, bevor OE angelegt wurde. 
Das ist nicht das tatsächliche ADC-Resultat.

Hätte der ADC keine OE-Verzögerungszeit, bräuchtest Du hier mindestens 
einen NOP dazwischen.  Dazu kommt die ADC-OE-Zeit.

Noch'n paar Anmerkungen:
  for( j = 0; j < NR_SAMPLES; j++ )
  {

   PORTD |=  ( 1 << OE );//enable output data
   adwert += data;      //read data
   PORTD &= ~ ( 1 << OE );            //disable adc
  }
Hier liest Du NR_SAMPLES mal ein, ohne eine Konversion neu zu starten. 
Eine sinnlose Übung, denn Du bekommst einfach immer denselben Wert, 
insgesamt also den NR_SAMPLESfachen Wert, anstatt mehrere Male 
tatsächlich zu sampeln.

Die ganze if-Kette in Deinem Programm kann übrigens durch eine Zeile
PORTA = (PORTA & ~(1<<A|1<<B|1<<C)) | (channel << A) 
ersetzt werden.  Befasse Dich mal näher mit Bitmanipulationen, um 
weniger unnötige Bitwurschtelei zu erzeugen.

Autor: smith (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hc Zimmerer schrieb:
> PORTA = (PORTA & ~(1<<A|1<<B|1<<C)) | (channel << A)
biste sicher dass es richtig so? wenn wir channel 2 wählen was hat A da 
zu suchen.bin halt anfänger:)

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
smith schrieb:
> Hc Zimmerer schrieb:
>> PORTA = (PORTA & ~(1<<A|1<<B|1<<C)) | (channel << A)
> biste sicher dass es richtig so?

Ich kann zwar keinen Fehler entdecken, aber das ist keine Garantie 
dafür, dass keiner drin ist.  Ich bin jedenfalls der Ansicht, dass das 
richtig so ist.

> wenn wir channel 2 wählen was hat A da
> zu suchen.bin halt anfänger:)

Das A ganz rechts steht für die Verschiebung der Bits in „channel“ und 
„<<“ ist der Verschiebeoperator.  Ich denke, das Einfachste wird sein, 
dass Du Dir ein Blatt Papier nimmst und Dir klar machst, was passiert, 
wenn Du die Bits in channel um 4 Bitpositionen nach links verschiebst (A 
hat ja den Wert 4).  Du wirst sehen, dass sie im Port auf den für A, B, 
und C vorgesehenen Plätzen landen.

Ein C-Buch leistet da wertvolle Dienste.

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.