- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 13

Thema: Merkwürdiges Problem mit PCINT und UART

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    21.04.2005
    Ort
    Hannover
    Beiträge
    190

    Merkwürdiges Problem mit PCINT und UART

    Anzeige

    Praxistest und DIY Projekte
    Hallo Zusammen,

    wie oben schon steht habe ich ein ganz komisches Problem mit folgendem Code
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include "uart.h"
    
    
    #define UART_BAUD_RATE      9600
    
    ISR(PCINT_vect)
    {
    	uart_puts("A pin change interrupt occurred!");
    }
    
    int main(void)
    {
    	DDRB = 0x00; //set pins as output
    	PORTB |= (1<<PB0) | (1<<PB1); //activate pullup
    	PCMSK |= (1<<PCINT0) | (1<<PCINT1); //mask port
    	GIMSK |= (1<<PCIE); //activate PCinterrupts
    	
    	uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
    	sei();
    	while(1)
    	{
    		uart_puts("Noch alles in Ordnung?\r\n");
    		_delay_ms(1000);
    	}
    	return 0;
    }
    Es ist so, dass wenn ich die ISR auskommentiere das Programm problemlos läuft. Sobald es aber mit kompiliert wird ist nach dem uart_init(..); und sei(); schluss und die int main(void); wird von vorne durchlaufen.
    D.h. der µC steckt dann in einer Endlosschleife fest.

    Ich programmiere mit AVRStudio mit WinAVR plugin.

    Ach ja, die UART-Routinen sind von Peter Fleury und der µC ist ein ATTiny2313.

    Kann mir jemand einen Hinweis geben woran das liegen könnte?

    Vielen Dank!

    MfG, Marten83

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Du hast dir da einen netten Deadlock reinprogrammiert. Die Fleury-Lib versendet die Zeichen per Interrupt, die ja aber innerhalb eines anderen Interrupts deaktiviert sind. Wenn du die Zeichenkette kürzer machst (weniger als 32 Zeichen) wird es funktionieren, aber nur solange die Interrupts nicht zu schnell aufeinander folgen.
    MfG
    Stefan

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    21.04.2005
    Ort
    Hannover
    Beiträge
    190
    Ja, ok.
    Darüber habe ich noch nicht nachgedacht.
    Aber, müsste, solange kein pin change interrupt kommt, die Routine nicht "Noch alles in Ordnung?" senden?
    Nach der Simuation in AVRStudio kommt der Compiler noch nichtmal an die Stelle an der mit "sei();" die Interrupts aktiviert werden.
    Und das verstehe ich nicht.

    Marten83

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Du solltest das Pin-Change-Interrupt-Flag nach der Initialisierung löschen. Wahrscheinlich ist das Flag durch einen floatenden Eingang bereits gesetzt, und dann wird nach dem sei sofort der Interrupt ausgelöst.
    MfG
    Stefan

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    21.04.2005
    Ort
    Hannover
    Beiträge
    190
    Habe das ganze jetzt mal um folgende Zeile erwitert:

    EIFR &= ~(1<<PCIF); //clear interrupt flag

    Leider hatte auch das nicht den gewünschten Erfolg!

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    54
    Beiträge
    524
    Hallo,

    diese Flags werden eigentlich immer durch das Schreiben einer 1 gelöscht.

    Gruß

    Jens

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    21.04.2005
    Ort
    Hannover
    Beiträge
    190
    Oh, da hätte ich wohl bis zum Ende lesen sollen.

    Da stellt sich aber gleich noch eine Frage:

    Warum????

    Ich meine im Datenblatt steht, dass wenn ein Interrupt kommt, das PCIF gesetzt also "eins" wird und dadurch dann die entsprechende ISR ausgeführt werden kann. Ich finde es unlogisch dann eine "eins" zum löschen des bits zu schreiben.

    Naja, ich probiers erstmal!

    Danke!

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    21.04.2005
    Ort
    Hannover
    Beiträge
    190
    So, habe es ausprobiert....
    Leider geht es nur halb.
    Solange ich keinen Interrupt von aussen auslöse funktioniert die Hauptroutine. Nach einem Interrupt bleibt der µC wieder hängen und führt noch nicht einmal den Code der ISR aus.
    Das PCIF-flag wird doch bei Ausführung der ISR wieder gelöscht, oder?
    Zumindest steht es so im Datenblatt.

  9. #9
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Wie sieht der Code jetzt aus?
    MfG
    Stefan

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    21.04.2005
    Ort
    Hannover
    Beiträge
    190
    So sieht er jetzt aus:
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    #include <util/delay.h>
    #include <stdlib.h>
    #include <string.h>
    #include "uart.h"
    #include "owi.h"
    
    
    #define UART_BAUD_RATE      9600
    
    
    ISR(PCINT_vect)
    {
    	//EIFR |= (1<<PCIF); //<--hat auch nicht geklappt
    	uart_puts("A pin change interrupt occurred!");
    }
    
    int main(void)
    {
    	DDRB = 0x00; //set pins as output
    	PORTB |= (1<<PB0) | (1<<PB1); //activate pullup
    	PCMSK |= (1<<PCINT0) | (1<<PCINT1); //mask port
    	GIMSK |= (1<<PCIE); //activate PCinterrupts
    	EIFR |= (1<<PCIF); //clear interrupt flag
    	
    	uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
    	sei();
    	signed int temperatur;
    	char s[20];
    	char temp[5];
    	while(1)
    	{
    		OWReset();
    		OWWriteByte(0xcc); //skip rom
    		OWWriteByte(0x44); //convert T
    		_delay_ms(500);
    		OWReset();
    		OWWriteByte(0xcc);
    		OWWriteByte(0xbe);
    		temperatur = OWReadByte();
    		temperatur |= (OWReadByte() << 8);
    		temperatur = temperatur / 2;
    		strcpy(s,"$PMBPS,");
    		itoa(temperatur,temp,10);
    		strcat(s,temp);
    		uart_puts(s);
    		uart_puts("\r\n");
    		_delay_ms(500);
    		
    	}
    	return 0;
    }

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests