- 12V Akku mit 280 Ah bauen         
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 26

Thema: Böse Interrupts

  1. #1

    Böse Interrupts

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo Forum,
    zwischen Eiersuchen und Osterwünsche verteilen lese ich mich das erste mal in die Interrupt meines AVR 169 ein.

    Ich habe einen IS471 an meinen Butterfly angeschlossen und möchte bei entsprechendem Signal eine Meldung über das LCD laufen lassen.

    Das Problem, dass ich gerade habe ist, dass das Interrupt nicht ausgelöst wird und der entsprechende Programmtext nicht ausgeführt wird.

    Ich denke, dass die Fehler in den EIFR (oder wie auch immer die sich schimpfen)-Registern zu finden sind und ich diese falsch anspreche.

    Der Quelltext ist nicht groß, das ansprechen des LCD´s klappt prima.

    // Auslesen eines IS471-Sensors

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    #include <avr/sleep.h>
    #include <inttypes.h>
    #include <avr/signal.h>
    #include <inttypes.h>
    #include "main.h"
    #include "lcd_functions.h"
    #include "lcd_driver.h"
    #include <avr/delay.h>

    #define pLCDREG_test (*(char *)(0xEC))

    // extern unsigned int LCD_character_table[] PROGMEM;

    volatile PGM_P statetext;

    void PinChangeInterrupt(void)
    {
    cli(); // disable interrrupts

    statetext = PSTR("wand");
    LCD_puts_f(statetext, 1);
    LCD_Colon(0);
    _delay_loop_2(300000000); // Ja, Pausen in Interrupts sind böse

    // Ist diese Zeile hier sinnvoll?
    EIFR = (1<<PCIF1) | (1<<PCIF0); // Delete pin change interrupt flags

    sei();
    }

    SIGNAL(SIG_PIN_CHANGE0)
    {
    PinChangeInterrupt();
    }

    SIGNAL(SIG_PIN_CHANGE1)
    {
    PinChangeInterrupt();
    }

    /************************************************** ***************************
    *
    * Function name : main
    *
    * Returns : None
    *
    * Parameters : None
    *
    * Purpose : Contains the main loop of the program
    *
    ************************************************** ***************************/
    int main(void)
    {

    DDRB = 0x00; // set Port B for input
    //PORTB = 0xFF;
    // Enable pin change interrupt on PORTB

    // Auch in diesen Zeilen blicke ich nicht durch

    PCMSK0 = (1<<PINB1)|(1<<PINB2)|(1<<PINB3)|(1<<PINB4);
    PCMSK1 = (1<<PINB1)|(1<<PINB2)|(1<<PINB3)|(1<<PINB4);
    EIFR = (1<<1)|(1<<2)|(1<<3)|(1<<4);
    EIMSK = (1<<1)|(1<<2)|(1<<3)|(1<<4);

    statetext = PSTR("1");

    // Program initalization
    Initialization();
    sei(); // mt __enable_interrupt();

    while (1) // Main loop
    {

    statetext = PSTR("1");
    LCD_puts_f(statetext, 1);
    LCD_Colon(0);

    } //End Main loop

    return 0;
    }

    /************************************************** **************************
    *
    * Function name : Initialization
    *
    * Returns : None
    *
    * Parameters : None
    *
    * Purpose : Initializate the different modules
    *
    ************************************************** ***************************/
    void Initialization(void)
    {
    /*
    CLKPR = (1<<CLKPCE); // set Clock Prescaler Change Enable

    // set prescaler = 8, Inter RC 8Mhz / 8 = 1Mhz
    CLKPR = (1<<CLKPS1) | (1<<CLKPS0);

    // Disable Analog Comparator (power save)
    ACSR = (1<<ACD);

    // Disable Digital input on PF0-2 (power save)
    DIDR1 = (7<<ADC0D);

    // mt PORTB = (15<<PORTB0); // Enable pullup on
    PORTB = (15<<PB0); // Enable pullup on
    // mt PORTE = (15<<PORTE4);
    PORTE = (15<<PE4);

    sbi(DDRB, 5); // set OC1A as output
    sbi(PORTB, 5); // set OC1A high
    */

    LCD_Init(); // initialize the LCD
    }
    Im Endeffekt wird das Signal vom IS471 von VCC auf GND invertiert und das soll der Butterfly erkennen.

    Ach ja, ohne Interrupts sondern nur mit der Abfrage in einer Schleife klappt alles ganz prima.

    Schon mal Danke fürs lesen,
    ich wünsche noch weiterhin frohe OStern,
    Florian.

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Hallo, ohne sich ein Dattenblatt zu Deinem µC runterzuladen, und sich die Register anzugucken, kann ich folgendes sagen...

    Code:
    #include <avr/delay.h>
    Wo gibt es das ?

    delay.h befindet sich meiner Meinung nach in util/ ....

    Code:
     _delay_loop_2(300000000);
    300000000 ??

    Code:
    void 	_delay_loop_2 (uint16_t __count)
    so steht es in delay.h drin und jetzt überleg mal wie groß maximal uint16_t
    sein kann.

    warum springst Du as der ISR in eine Funktion raus? das kann man ruhig in der ISR erledigen, ohne sie zu verlassen.

    Warum machst Du cli(); in der ISR ? das ist sinnlos.

    und ja
    Ja, Pausen in Interrupts sind böse
    dem kann ich nur zustimmen....

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  3. #3
    Hi izaseba,
    schon einmal vielen Dank für die Antwort.

    Also bei den Delays stimmt das soweit. Ich arbeite großen Teils mit Joe Pardues Butterfly-Buch, daher kommen auch die Delay-Angaben.

    Die 300000000 kommt mir auch erstaunlich groß vor, bewirkt aber im Endeffekt keine großen Verzögerungen. Ich schätze, dass es sich bloß um eine halbe Sekunde delay handelt.

    Wie dem auch sei, die Problematik, dass die Interrupts nicht beachtet werden, ist noch gegeben.

    Ach ja, cli() rufe ich in der ISR auf, um in diesem Interrupt zu vermeiden, dass ein weiterer Interrupt erkannt wird.

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    19.03.2005
    Ort
    Villach
    Alter
    32
    Beiträge
    995
    Hi,
    300000000 ist unmöglich da die variale nur max. 65536 zulässt.

    und warum schreibst du:
    PORTB = (15<<PB0); // Enable pullup on

    Ich würddas schreiben:
    PORTB |= (1<<PB0); // Enable pullup on

    Grüße
    Superhirn

    PS: Mit deinem Problem kenn ich mich nicht so aus. aber dass ist das, was ich nicht verstehen kann.

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Ich arbeite großen Teils mit Joe Pardues Butterfly-Buch, daher kommen auch die Delay-Angaben.
    Dann tue des Buch in die Tonne, wenn so ein Quatsch drin steht.

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  6. #6
    Na gut, die Delays scheinen tatsächlich ziemlich buggy zu sein, dann schmeiß ich die gerne raus (das Buch behalte ich noch ein paar Tage... .

    Den Quelltext habe ich jetzt schon ein wenig reduzieren können, die aktuelle Version werde ich jetzt hier posten und weiterhin um Hilfe mit den Interrupts bitten - denn das klappt alles noch nicht....

    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    #include <avr/sleep.h>
    #include <inttypes.h>
    #include <avr/signal.h>
    #include <inttypes.h>
    #include "main.h"
    #include "lcd_functions.h"
    #include "lcd_driver.h"
    #include <avr/delay.h>
    
    #define pLCDREG_test (*(char *)(0xEC))
    
    volatile PGM_P statetext;
    
    void PinChangeInterrupt(void)
    {
    
    	statetext = PSTR("wand");
    	LCD_puts_f(statetext, 1);
    	LCD_Colon(0);
    		
    }
    
    SIGNAL(SIG_PIN_CHANGE0)
    {
        PinChangeInterrupt();
    }
    
    SIGNAL(SIG_PIN_CHANGE1)
    {
        PinChangeInterrupt();    
    }
    
    /*****************************************************************************
    *
    *   Function name : main
    *
    *   Returns :       None
    *
    *   Parameters :    None
    *
    *   Purpose :       Contains the main loop of the program
    *
    *****************************************************************************/
    int main(void)
    {   
    	LCD_Init();
    	DDRB = 0x00; // set Port B for input
    	PORTB = 0xFF;
    	
        // Enable pin change interrupt on PORTB
    
    	PCMSK1 = (1<<PCINT12)|(1<<PCINT11)|(1<<PCINT10)|(1<<PCINT9);
    	EIMSK = (1<<PCINT1);
    	statetext = PSTR("1");
    
    	// Program initalization
        
             sei();
    	
    	while (1)            // Main loop
        {
    		
    		statetext = PSTR("1");
    		LCD_puts_f(statetext, 1);
    		LCD_Colon(0);
    
        } //End Main loop
    	
    	return 0;
    }
    Weiterhin vielen Dank für eure Hilfe,
    cheers,
    Flo.

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.02.2006
    Ort
    München
    Alter
    35
    Beiträge
    161
    Die Delay-Include stimmt übrigens auch!
    @Izaseba: Schau mal nach /opt/cross/avr/include/avr/ (oder wo auch immer dein avr-gcc liegt). Dadrin befindet sich auf jeden Fall ne delay.h, die auch funzt. Benutze sie schließlich selber. Achja, vll liegt's auch an der neuen Version...

    mfG, Manni

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    In der tat liegt delay.h in avr, aber mit einem sehr schönem Inhalt:
    Code:
    #warning "This file has been moved to <util/delay.h>."
    #include <util/delay.h>
    womit letzendlich auch die richtige .h included wird, ich halte mich halt nach der Library Reference wo die delay.h unter util/ aufgelistet ist.
    Das ändert aber nichts an der Tatsache daß ein uint16_t keine 300 Mil. aufnehmen kann und wenn das so in einem Buch steht gehört das dingen für mich in den Müll.

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  9. #9
    Nein nein, die 3000000000000000000000 stand in keinem Buch

    Aus dem Buch stammt die Funktion an sich und auch, wo und in welcher Bibliothek sie zu finden ist.

    Da mir die Verzögerung aber zu gering war, habe ich nach und nach den Wert erhöht. Mittlerweile habe ich auch rausgefunden, dass der Compiler den Wert automatisch auf 65000 runtersetzt.

    Wie dem auch sei(), nach langem schmölern im AT169 Handbuch habe ich immer noch keine Ahnung, wie ich den Butterfly dazu bringen soll, die ersten 4 Pins (oder überhaupt einen dieser Pins) als Quelle für einen Interrupt anzusehen.

    Any more Ideas??

    Weiterhin einen schönen Abend,
    Florian.

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    also nochmal sorry, dann liegt das nicht am Buch

    Also ich hab mir das Dattenblatt runtergeladen und das erste was mir aufgefallen ist Register EIMSK hat kein Bit mit dem namen PCINT1
    PCINT1 ist in der iom169.h mit 1 definiert und Bit 1 in EIMSK ist nicht vorhanden, naja vorhanden schon aber nicht benutzt.
    Prüf das nochmal nach, vielleicht hilft es.
    Es kann auch sein, daß ich einen an der wafel hab, es handelt sich doch um atmega169?

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

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

LiFePO4 Speicher Test