Kommentar: Einfügen von HTML im Kommentar: Link einfügen: <a href="LINKURL" target="_blank">LINKTITEL</a> Bild einfügen: <img src="BILDURL"> Text formatieren: <b>fetter Text</b> <i>kursiver Text</i> <u>unterstrichener Text</u> Kombinationen sind auch möglich z.B.: <b><i>fetter & kursiver Text</i></b> C Quellcode formatieren: <code>Quellcode</code> BASIC Quellcode formatieren: <basic>Quellcode</basic> (Innerhalb eines Quellcodeabschnitts ist kein html möglich.) Wichtig: Bitte mache Zeilenumbrüche, bevor Du am rechten Rand des Eingabefeldes ankommst ! -> I > > > 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