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

Re: @PeterS - AVR32 LCD-Ausgabe stört Interrupt Bearbeitung Kategorie: CC-Pro Unit & Appl.Board (von Hannes24 - 28.06.2014 19:43)
Als Antwort auf Re: @PeterS - AVR32 LCD-Ausgabe stört Interrupt Bearbeitung von PeterS - 27.06.2014 10:56
Ich nutze:
C-Control Pro AVR32
> > Hallo,
> >
> > ich möchte von der Netzspannung die beiden Scheitelpunkte nach dem Nulldurchgang
> > messen. Dabei gebe ich auf den ext.INT4 das Nullspannungssignal (im Bild gelb)
> > und starte nach Auslösen des IRQ zwei Timer die dann 5ms und 15ms später
> > (im Bild blau) den ADC auslesen.
> > Das funktioniert absolut stabil, solange keine LCD-Ausgabe stattfindet.
> > Findet eine LCD-Ausgabe statt und ein Hard- oder Software IRQ wird ausgelöst,
> > dann zittert das ADC Signal (blau) wie verrückt und eine präzise Messung ist nicht
> > mehr möglich.
> >
> > Kann man der Abarbeitung eines Hard- oder Software IRQ oberste Priorität geben ?
> > Eine verzögerte oder unterbrochene LCD-Ausgabe spielt ja sowieso keine Rolle.
> >
> >
> >
> >
> >
> >
> >
> > //--------------------------------------------------------------------------------
> > #define PORT_LED3 117                           // PortBit 117
> > #define PORT_LED4 119                           // PortBit 119
> >
> > word x;
> >
> >
> > void main(void)
> > {
> >
> >     Port_Attribute(10, PORT_ATTR_INPUT);        // P15 auf Eingang = Ext_Int4 (Nullsp)
> >     Port_Attribute(PORT_LED1,PORT_ATTR_OUTPUT|PORT_ATTR_INIT_LOW);        // LED 1
> >     Port_Attribute(PORT_LED2,PORT_ATTR_OUTPUT|PORT_ATTR_INIT_LOW);        // LED 2
> >     Port_Attribute(PORT_LED3,PORT_ATTR_OUTPUT|PORT_ATTR_INIT_LOW);        // LED 3
> >     Port_Attribute(PORT_LED4,PORT_ATTR_OUTPUT|PORT_ATTR_INIT_LOW);        // LED 4
> >
> >
> >     Irq_SetVect(INT_100HZ, ISR_10ms);               // Interrupt alle 10ms
> >
> >     Irq_SetVect(INT_4, ISR_ZeroCrossing);           // Int4 setzen fĂĽr Nulldurchgang
> >     Ext_IntEnable(4,2);                             // Int4: Mode 2 = fallende Flanke
> >
> >     Irq_SetVect(INT_TIMER0, ISR_Timer0);            // Timer0 IRQ, 5ms nach Nulldurchg.
> >     Irq_SetVect(INT_TIMER1, ISR_Timer1);            // Timer1 IRQ, 15ms nach Nulldurchg.
> >
> >     LCD_Init();                                     // Display initialisieren
> >     LCD_ClearLCD();
> >     LCD_CursorOff();                                // Display Cursor ausschalten
> >
> >     while(1)
> >     {
> >         x++;
> >     }
> >
> >
> >
> > }
> >
> > // -------------------------- IRQ Nulldurchgang (50Hz) ------------------------------
> > //
> > void ISR_ZeroCrossing(void)
> > {
> >     Timer_Set(0, TIM_128, 2579, TIMFLG_IRQ);    // 2579*1,939us = 5ms
> >     Timer_Set(1, TIM_128, 7736, TIMFLG_IRQ);    // 7736*1,939us = 15ms
> >
> >     Irq_GetCount(INT_4);
> > }
> >
> >
> > // ----------------------- IRQ Timer0, 5ms nach Nulldurchgang ----------------------
> > // den ADC0 auslesen (=Scheitelpunkt der 1.Halbwelle)
> > //
> > void ISR_Timer0(void)
> > {
> >     Port_WriteBit(PORT_LED2,PORT_ON);
> >     Irq_GetCount(INT_TIMER0);
> >     Timer_Disable(0);
> >     Port_WriteBit(PORT_LED2,PORT_OFF);
> > }
> >
> > // ----------------------- IRQ Timer1, 15ms nach Nulldurchgang ----------------------
> > // den ADC0 auslesen (=Scheitelpunkt der 2.Halbwelle)
> > //
> > void ISR_Timer1(void)
> > {
> >     Port_WriteBit(PORT_LED2,PORT_ON);
> >     Irq_GetCount(INT_TIMER1);
> >     Timer_Disable(1);
> >     Port_WriteBit(PORT_LED2,PORT_OFF);
> > }
> >
> > // ---------------------------System IRQ 100Hz, alle 10ms --------------------------
> > //
> > void ISR_10ms(void)
> > {
> >
> >
> >     Port_WriteBit(PORT_LED1,PORT_ON);
> >
> >     LCD_CursorPos(0x00);                        // dauert 1.2ms
> >     LCD_WriteWord(x, 5);
> >
> >     Port_WriteBit(PORT_LED1,PORT_OFF);
> >     Irq_GetCount(INT_100HZ);
> >
> > }
> >
> >
> >
>
> Hallo Hannes,
>
> die Priorität spielt keine Rolle, das Problem ist vielmehr, das für den Interpreter
> Libraryfunktionen wie LCD_CursorPos oder LCD_WriteWord atomar in Assembler
> ablaufen, und nicht unterbrochen werden können. Man könnte aber die Delays
> minimieren, in dem Du z.B. mit LCD_WriteChar immer nur einen Buchstaben ausgibst.
>
> Ich sehe im Programmcode nicht, wie der ADC angesprochen wird, eine Abarbeitung im
> "Free Running Mode" ist das beste um kontinuerlich präzise Werte zu samplen.
>
> Gruss Peter




Hallo Peter,

ich habe den ADC als IRQ initialisiert

ADC_SetInput(0, 0, ADC_GND, ADC_SHG_1);        
ADC_Enable(ADC_MODE_10BIT|ADC_MODE_ENAB_IRQ, 100000, ADC_ADCREF0,1, 13);

die ADC-Messung funktioniert u. ist ausreichend genau. In meinem
Testprogramm, das die Störung des Timings reproduziert schalte
ich anstelle der ADC-Konvertierung einfach die LED2 EIN und AUS
(blaues Signal). Gleichzeitig findet ĂĽber den System-IRQ 100Hz,
alle 10ms eine LCD-Ausgabe statt. Da beide Vorgänge nicht
synchronisiert sind, wird der ADC verzögert gelesen, wenn gerade
am LCD was ausgegeben wird.
 
Es gibt dann wohl nur die eine Lösung, dass die LCD-Ausgabe
zwischen den ADC-Messungen (ca. 8ms) stattfinden muss und das zu
timen wird interessant.

Wie verhält es sich, wenn gerade andere Komponenten angesprochen werden
z.B. I2C, SPI, RS232, SD-Card, int. EEprom

Danke + Gruss


    Antwort schreiben


Antworten:

Re: @PeterS - AVR32 LCD-Ausgabe stört Interrupt Bearbeitung (von PeterS - 13.07.2014 11:08)