Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum

Re: @Peter S - Timer 0 läuft nicht stabil Kategorie: CC-Pro Unit & Appl.Board (von Hannes - 12.09.2008 15:40)
Als Antwort auf Re: @Peter S - Timer 0 läuft nicht stabil von PeterS - 12.09.2008 14:27
Ich nutze:
C-Control Pro Mega32, eigenes Board

Gerne teste ich mal die Betaversion mit Assembler. Erwarte aber nicht zuviel, ich bin kein Assembler
Experte für AVR-Controller. Kannst ja mal einen allgemeinen Aufruf machen, evtl. finden sich
ein paar Freiwillige.

Gruss




>
> Hallo Hannes,
>
> Assembler ist inzwischen eingebaut. Für die Gesamterweiterung fehlen allerdings noch einige Dinge,
> hättest Du Interesse in 1-2 Tagen eine Betaversion der neuen Software mit Assembler zu testen?
>
> Die Interrupts werden noch nicht an Assembler weitergegeben. Da muÃ? ich noch schauen, wie ich das
> effizient dazu baue.
>
> Gruss Peter
>
> >
> > Hallo Peter,
> >
> > der von mir beschriebene Effekt tritt auf mit dem beigefügtem Programm.
> > Da werden überhaupt keine rechenintensive Sachen ausgeführt. Seltsam
> > ist auch, dass gelegentlich, alle 20-30Sek., Interrupts ausfallen.
> > Am Speicherosszi sieht man das, auch die Frequenz der angesteuerten
> > LED ändert sich dann.
> >
> > Nunja, ist der C-Control für präzise Zeitanwendungen halt nicht geeignet,
> > aber vielleicht könnte man das für die Zukunft einbauen, dass Interrupt-
> > und Timerroutinen in Assembler ausgeführt werden können und deren
> > Abarbeitungpriorität an 1. Stelle steht.
> >
> > Gruss
> >  
> >
> >
> >
> >
> >
> > >
> > > Hallo Hannes,
> > >
> > > eine Interpreter Interrupt Routine ist ja keine richtige Assembler Interrrupt Routine. Wird ein Interrupt erzeugt,
> > > wird intern ein Flag gesetzt, und nach bei Abarbeitung des aktuellen Bytecodes, werden die Bytecodes
> > > der Interpreter Interrupt Routine abgearbeitet. Das ist natürlich leicht verzögert. Werden in dem Bytecode
> > > rechenintensive Sachen wie z.B: ein Sinus berechnet, kann die Verzögerung sogar im Bereich von ms liegen.
> > > Kann das Dein Problem erklären?
> > >
> > > Gruss Peter
> > >
> > > > Hallo Peter,
> > > >
> > > >
> > > > ich möchte exakt 5ms nachdem ein Interrupt ausgelöst wurde eine Spannung messen.
> > > > Zum Testen habe ich an INT0 ein stabiles Rechtecksignal von einem Frequenzgenerator mit einer
> > > > Periodendauer von 20ms angeschlossen. Die positive Flanke triggert den INT0, dieser startet den
> > > > Timer0 und nach 5ms wird die Spg. eingelesen.
> > > > Zum Messen schalte ich bei der INT0 Routine und der Timer0 Routine eine LED kurz EIN + AUS.
> > > >
> > > > Zum Problem:
> > > > Das INT0 Signal ist stabil vorhanden, und die 5ms Verzögerung passen, nur das Signal das der Timer
> > > > auslöst zittert, d.h. die 5ms werden vom Timer nicht exakt reproduziert. Das Signal schwankt rund
> > > > 100us hin und her, teilweise setzt es sogar ganz aus.
> > > >
> > > > Kann man das verbessern?
> > > > Weil es bringt mir nichts, wenn man Timer0 mit 67.8ns auflösen kann, der Timer aber die Zeit nicht
> > > > stabil reproduzieren kann.
> > > >
> > > > Gruss
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > > > word ADCWert_L1;
> > > > byte cnt1, Sekunde, Minute, Stunde, Sekunde_alt;
> > > >
> > > > void main(void)
> > > > {
> > > >
> > > >     SPI_Disable();
> > > >     Serial_Init(0,SR_8BIT|SR_1STOP|SR_NO_PAR,SR_BD38400);       // Schnittstelle 0
> > > >     LCD_Init();                             // Display initialisieren
> > > >     LCD_ClearLCD();                         // Display löschen
> > > >     LCD_CursorOff();                        // Display Cursor ausschalten
> > > >     Port_DataDirBit(PORT_LED1,PORT_OUT);
> > > >     Port_WriteBit(PORT_LED1,PORT_OFF);
> > > >
> > > >     Irq_SetVect(INT_0, Nulldurchgang_L1);   // INT0 setzen für Nulldurchgang L1 (Port D.2)
> > > >     Ext_IntEnable(0,3);                     // INT0: Mode 3 = steig Flanke
> > > >
> > > >     Irq_SetVect(INT_TIM0COMP,Timer0_ISR);   // Interrupt Routine Timer 0  definieren
> > > >
> > > >
> > > >     while(1);
> > > > }
> > > >
> > > >
> > > > void Nulldurchgang_L1(void)                 // Aufruf bei steigender Flanke
> > > > {
> > > >     int irqcnt;
> > > >
> > > >     Timer_T0Time(72,PS0_1024);              // Zeit (5ms) festlegen und Timer0 starten
> > > >     Port_WriteBit(PORT_LED1,PORT_OFF);      // LED1 OFF
> > > >     Port_WriteBit(PORT_LED1,PORT_ON);       // LED1 ON    Impulsdauer Off-On 50us
> > > >
> > > >     irqcnt=Irq_GetCount(INT_0);
> > > > }
> > > >
> > > >
> > > >
> > > > void Timer0_ISR(void)                       // Aufruf 5ms nach Nulldurchgang der Wechselspg.
> > > > {
> > > >     int  irqcnt;
> > > >     Port_WriteBit(PORT_LED1,PORT_OFF);      // LED1 OFF
> > > >     Timer_T0Stop();                         // Timer0 anhalten
> > > >
> > > >     ADC_Set(ADC_VREF_VCC, 0);               // VREF für ADC0(=PortA.0) = VCC (5.000V)
> > > >     ADCWert_L1 = ADC_Read();                // Spitzenwert von L1 in den ADC
> > > >
> > > >     irqcnt=Irq_GetCount(INT_TIM0COMP);
> > > >
> > > >     Port_WriteBit(PORT_LED1,PORT_ON);       // LED1 ON, Laufzeit LED1 OFF-ON ca. 400us
> > > > }
> > > >


    Antwort schreiben


Antworten: