Hallo, ich baue hier eine kleine digitale Regelung mit Atmega16 auf und brauche eure Hilfe. uC: Atmega16 16Mhz Takt Eingang: ADC 8bit 125kHz, Signal an pin0 gegen Masse (Bereich 0-5V) Ausgang: PortC binär (8-bit) und dann auf ne R/2R Brücke. Compiler: CodevisionAVR 1.25.1 Standart Datei mit C-Quelle ist eingefügt Funktion: Der uC sollte Spannung dass an Pin0 anliegt wandeln, umrechnen mit der Formel, und Ergebnis an PortC einstellen und halten, und dann wieder Wert wandeln, berechnen und halten bis der nächste wert berechnet wird. 1.Problem: AD-Wandler und Interrupt ich bin mir nicht sicher ob AD-Wandlung unterbrochen wird wärend die Berechnung mit der Formel läuft. Da muss noch bestimmt am Anfang und am Ende der Berechnung was mit Interrupt passieren :) In pdf-Anleitung von cvavr steht nur bisi was über externe isr's und Timer. 2. Ich habe umgerechnet 128 Takte fürs AD-Wandeln und Berechnen, wird das ausreichen ?, denn ich muss warscheinlich mit float-DatenTyp rechnen weil die konstanten in der Formel Nachkommastellen haben und dazu muss ich noch 3 mal multiplizieren. ... und wenn jemend welche Vorschläge hat um Code schneller und schlanker zu machen wäre ich sehr dankbar. Danke !
>um Code schneller
Schmeiss floating-point-arithmetik raus. Benutze lieber
Fixpunkt-Arithmetik.
Dazu musst du die Konstanten erweitern.
> denn ich muss warscheinlich mit float-DatenTyp rechnen > weil die konstanten in der Formel Nachkommastellen haben > und dazu muss ich noch 3 mal multiplizieren. Das ist kein Grund a = 0.234 * b kann auch gerechnet werden als a = 234 * b / 100; wenn a und b integer sind, macht das keinen Unterschied. Ausser dem, dass die 2-te Variante um etliches schneller ist. In deinem Fall: anstatt PORTC=(0,062*e+0,044*esum+0,274*edif); //Reglergleichung kommt PORTC = ( 62 * e + 44 * esum + 274 * edif ) / 1000; und schon brauchst du kein floating point mehr. Es gibt auch keinen Grund, warum e, ealt, esum und edif float sein muessen. > ... und wenn jemend welche Vorschläge hat um Code schneller > und schlanker zu machen wäre ich sehr dankbar. Dein Code ist hauptsächlich deshalb so aufgebläht, wewil du einen Wizard benutzt hast, der dir auf dem Chip alles mögliche initialisierst. Unabhängig davon, ob du das brauchst oder nicht. Schmeiss das ganze Wizard Zeugs raus, lass nur das drinn was du brauchst und dein Code passt locker auf eine Bildschirmseite.
Danke für Vorschlag mit Fixpunkt-Arithmetik ! Ich habe jetzt alle Variablen als int deklariert ist doch richtig so ? was ist eigentlich mit Interrupt und ADC ? stimmt der code ?
Morgen ! habe gestern noch versuch zu ermitteln wie lange dauert die berechnung(natürlich mit Fixpunkt-Arithmetik), dazu habe ich vor der berechnung PortD auf 0 und nach der berechnung auf FF gesetzt und dann am Oszi den Dauer ermittelt und das sind 25uSekunden. Naja :( Perioden dauer zwischen Abtastwerten bei 125kHz ist 8us. Also es haut nicht hin es sei denn die Berechnung wird mehr als 3 mal schneller. Die 2 Fragen von vorhin interessiren mich immer noch: Alle Variablen als "int" deklariert ist doch richtig so ? Was ist eigentlich mit Interrupt für die berechnung und ADC ? stimmt der code ?
> Also es haut nicht hin es sei denn die Berechnung wird mehr als 3 mal > schneller. Schneller wirds nicht mehr. Ein Problem könnte ich mir noch vorstellen. Dein µC wird wahrscheinlich eine Menge Zeit in der ADC_ISR verbringen. Eine Wandlung dauert ein paar Taktzyklen. Ist die Wandlung fertig, so wird die ISR abgearbeitet und sofort die nächste Wandlung gestartet. D.h. Dein µC arbeitet hauptsächlich in der ISR. Mit der dann noch verbleibenden Rechenzeitzeit werden nebenbei noch deine Berechnungen in der Hauptschleife ausgeführt. Eventuell (müsste man probieren) wäre hier ein Verzicht auf eine ISR und eine klassische Hauptschleife ADC starten while( 1 ) { ADC holen ADC starten umrechnen Ausgeben } die bessere Alternative. Zumindest verteilt sich dann die Rechenzeit besser auf die 2 Tasks. Während der ADC wandelt, rechnet der µC den Wert um und gibt ihn aus sodass beim nächsten Schleifendurchlauf das nächste ADC Ergebnis schon wieder fertig zum Abholen ist. > Alle Variablen als "int" deklariert ist doch richtig so ? Denk nach. Was sollen sie sonst sein? > Was ist eigentlich mit Interrupt für die berechnung und ADC ? > stimmt der code ? Ich frag moch schon die ganze Zeit was du in dieser ISR eigentlich machst. Anscheinend werden da nacheinander verschiedene ADC Kanäle durchgeschaltet. Ausgewertet wird aber immer nur ein einziger. Sieht für mich nicht so aus als ob das stimmen könnte.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.