www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer0 gesteuerter AD-Wandler


Autor: Digi Hunter (digihunter)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen!

Es geht um nen digitalen Regler(Zeitdiskreten Regler) da werden ständig 
die Werte in festen Absänden abtastet, Berechnet und Ausgegeben.

Da bei 16MHz keine Abtastraten die niedriger als 125kHz gibt, nehme ich 
mir einen Timer0 und lasse damit bei Overflow den AD-Wandler ein mal 
Wandeln.
Also 16Mhz : Teiler 8 : 256 = 7812,5 Hz => 128us Periode in der 
AD-Wandler sich ein Wert schnapt mit dem später gerechent wird.

Das Problem ist, dass ich mit Timer und ISR noch nicht gearbeitet habe 
und auch keine Ahnung habe welche Zeile in welche routinen gehören.

z.B. eigentlich würd ich AD-Wandlung und Berechnung in ISR stecken, wie 
ich verstanden habe da geht mein Timer in meinem Fall jede 128us ein mal 
rein.

Und es wäre vielleicht besser wenn ich ADC mit ADTS2 (Timer0 Überlauf) 
Trigern lasse ? aber freilaufenden Betrib brauche ich eigentlich nicht.

Ich warne erfahrene C Programmierer vor meinem schlechten Code(den ich 
aber ziemlich gut auskommentiert habe) und hoffe ihr könnt mir helfen es 
bisschen aufzuräumen.

Danke !

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int x=0; // 8-bit Variable

Versuch mal, richtig zu kommentieren.

8 Bit ist "char", bzw. wenn positiv ausreicht, besser "unsigned char".


Und ins main gehört immer ne Endlosschleife (darf nie verlassen werden).

Du hast aufm MC kein BS, wohin Du zurück kannst.


Peter

Autor: Digi Hunter (digihunter)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger wrote:
> int x=0; // 8-bit Variable
>
> Versuch mal, richtig zu kommentieren.
> 8 Bit ist "char", bzw. wenn positiv ausreicht, besser "unsigned char".

das stimmt 8-bit, deklariert als int weil es wird dann mit int 
gerechnet, hier e = 230 - x; e ist int und so weit ich weiss ein 
gemischtes rechnen darf man nicht machen.

> Und ins main gehört immer ne Endlosschleife (darf nie verlassen werden).
>
> Du hast aufm MC kein BS, wohin Du zurück kannst.

nun ich habe alles aus main nach ISR kopiert und da ne schleife mit 
while(1) eingebaut. War das gemeint ?

meiner Meinung nach sehen da

    uint8_t buffer; // buffer für gewandelten 8-bit Wert

    // A/D - Wandler initialisieren
    adc_init();

nicht gut aus :(


Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Digi Hunter wrote:

> das stimmt 8-bit, deklariert als int weil es wird dann mit int
> gerechnet, hier e = 230 - x; e ist int und so weit ich weiss ein
> gemischtes rechnen darf man nicht machen.

Wer sagt denn sowas ?
char nach int geht problemlos.


> nun ich habe alles aus main nach ISR kopiert und da ne schleife mit
> while(1) eingebaut. War das gemeint ?

Es war genau so gemeint, wie ich es gesagt habe.

> // Berechnung Ende

ist keine C-Anweisung.

Und danach bist Du im Nirwana.


Peter

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Initialisierung von timer und ad wandler gehören ins main.

aber vielleicht solltest du erst mal mit etwas leichtem anfangen,

z.b. einen Ausgang zu setzen wenn eine Taste gedrückt wird,
wenn das läuft

versuchen Interrupts zu verstehen usw ...

Autor: Dirk (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, setz einfach ein Flag und polle in der Main Routine dieses Flag 
Bit.

Ein kleines Beispiel befindet sich im Anhang.

Autor: Digi Hunter (digihunter)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Danke Dirk !!!
Sieht schon viiiiiiel besser aus, dieses Flag(status_byte |= 
(1<<do_adc);) war u.a. mein Problem.

Nun habe ich in help.c Funktionen
int get_adc(void)
void rechnung(void)
gefüllt und regelung3.c genannt.

was muss ich noch mit Variablen temp und x anstellen damit 
AD-gewandelter Wert heil in void rechnung(void) ankommt ?
Also in diesem Absnitt hier:


________________________________________________________

// adc wandlung
int get_adc(void)
{
    // Wandlung starten (1<<ADSC) Einzel.Wandl. und (0<<ADATE) warschnl. 
nicht nötig da sowieso "0"
    ADCSRA |= (1<<ADSC)|(0<<ADATE);

    // Warten bis die AD-Wandlung abgeschloßen ist
    while ( !(ADCSRA & (1<<ADIF)) );

    // AD-Wert auslesen  ADCH da nur 8-bit ausreichen.
    x = ADCH;
}

// berechnung
void rechnung(void)
{
    // Berechnung Anfang
    e = 230 - x;
    esum = esum + e;
    edif = e - ealt;
    PORTC = ( 62 * e + 44 * esum + 274 * edif ) / 1000; 
//Reglergleichung
    ealt = e;
    // Berechnung Ende
}

int main(void) {
  unsigned int temp=0;
  timer0_init();
  adc_init();
  sei();
  for(;;){  //Endlosschleife starten
    if(status_byte & (1<<do_adc)){  // wenn do_adc 1 ist
      status_byte &= ~(1<<do_adc);  //do_adc löschen
      temp = get_adc(); // AD wandeln
      rechnung(); // Rechnen
    }
  }

}
________________________________________________________

Autor: Digi Hunter (digihunter)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal !
Wieso antwortet mir denn keiner ? stelle ich solche dumme Fragen ? :)

Nun habe ich regelung3.c wieder aufgeräumt und lade die gleich mit hoch.

Hab natürlich noch paar Fragen:

1. "status_byte" ist das irgendwo definiert oder nur ne Fantasie von 
Dirk ?
   das habe ich als char definiert (reicht doch ?) weil der Compiler 
gemeckert
   hat.

2. ADIF Bit in Register ADCSR wird doch automatisch(von uC) zurück auf 
"0"
   gesetz nachdem ich nur ADCH (s. regelung3.c) ausgelesen habe ?


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.