- Akku Tests und Balkonkraftwerk Speicher         
Seite 2 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 11 bis 20 von 32

Thema: CTC + timer0 auf mega16 - geben keinen Interrupt (auch m168)

  1. #11
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    Anzeige

    Powerstation Test
    ? ? ? ?
    Ok, das hatte ich jetzt nicht gelesen, das habe ich nur überflogen. Daran hatte ich GARNICHT gedacht - auch vorher nix gelesen.

    ABER: im ersten Anlauf hatte ich (soweit ich mich erinnern kann - ok, hab nachgesehen, es ist so) pinc4 genommen - und beim Setzen ALLER acht LEDS brennen wirklich nur die von 2 bis 5 nicht. 0, 1 und 6, 7 brennen (brannten).

    ... the pull-up resistors on pins PC5(TDI), PC3(TMS) and PC2(TCK) will be activated ...
    Da scheint noch ein Programmierer (diesmal der von ATMEL) so gründlich zu sein wie ich und hat halt den Pin mittendrin gleich mitgenommen - oder?

    Sachlich: Ok, danke Hubert.G - ich hab also das doc überflogen, die fuses ausgelesen, JTAGEN gesetzt/gelöscht - und nun läufts. Puhhhhh.

    Und die logische Induktion müsste jetzt heissen - dann läuft der restliche Code auch (relativ ? ? sicher ).

    Schönen Abend,
    Ciao sagt der JoeamBerg

  2. #12
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    Hallo Hubert.G,

    das war eine feine Hilfestellung, nochmal danke. Und es wurde ein langer Abend daraus, bzw. eine kurze Nacht. Mittlerweile läuft der Timer0 mit 10 kHz und zählt die Zeitmarke entsprechend (LED ändert alle 10 000 Interrupts ihre Meinung), die PWM´s mit timer1 und L293 treiben die Motoren rauf und runter - und ich warte auf zwei Gabellichtschranken für extInt0 und ~1.

    UART habe ich ganz rausgeworfen, ebenso Bezüge auf delay.h und delay_basic.h. Neben <stdlib.h>, <avr/io.h> und <avr/interrupt.h> läuft nur eine eigene "..h", die <avr/io.h> ist aber wohl auch überflüssig - die habe ich noch nicht durchgelesen.

    Eine abschließende Frage: habe ich mit diesen Interruptroutinen überhaupt eine Chance eine USART-Ausgabe zu machen? Ich wollte gerne die aktuellen Ansteuerungsparameter am Terminal ausgeben. Ohne Interruptroutinen gings, aber ich vermute sicher, die bringen das serielle Timing ausreichend durcheinander. Meine Tests zwischen 2400 und 38400 Baud - auch mit abweichenden Sende- und Empfangsparametern - gaben nur Schotter - meist Nullen und einige Eurozeichen . Und mein I2C ist noch immer nicht absehbar .

    Schönen Abend,
    Ciao sagt der JoeamBerg

  3. #13
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Doch UART sollte kein Problem sein, mit und ohne Interrupt.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  4. #14
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    Tut mir leid, noch immer Probleme, aber andere (ist eigentlich off topic). Das geringere ist: UART läuft nur ohne Interrupt - sobald ich "sei;" sage, gehts nicht mehr - habe ich aber vorerst zur Seite geschoben.

    Aktuelles Problem: trotzt sicherer Funktion von Timer0 (LED´s signalisieren ihre Funktion korrekt ) läuft der extInt0 nicht (und auch nicht der extInt1).

    Der code:
    Code:
    /* =================================================================================
       ##### Hier ISR und ISR - Initialisierung(en)
    ================================================================================= */
    /* ===  Initialisierung fuer EXT_INT0/1 auf Pin 16+17/mega16(32)  ==================
    $002 jmp SIG_INTERRUPT0 ; IRQ0 Handler und
    $004 jmp SIG_INTERRUPT1 ; IRQ1 Handler                  */
    void XTI_01_init( void )	
    {				//Initialisiere beide Interrupts auf rising edge
    				//  d.h. MCUCR ISC00,01,10+11 auf 1 (doc,S68)
        MCUCR |= (1<<ISC11)|(1<<ISC10)|(1<<ISC01)|(1<<ISC00);
        GICR  |= (1<<INT1)|(1<<INT0);	//  und erlaube diese I´s in GICR
    }
    /* ============================================================================== */
    
    
    /* ===  Initialisierung fuer Timer mega16(32)  =====================================
    SIGNAL (SIG_OVERFLOW0)
    Beachte zu TIMSK:
                     OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0   TIMSK
    Read/Write        R/W   R/W   R/W    R/W    R/W    R/W   R/W   R/W
    Initial Value      0     0     0      0      0      0     0     0
    
    RNControl          0     0     1      1      1      1     0     0     hex 3c
    ###>>> dieser Wert wird GESETZT, d.h. Bit 0, 1, 6 und 7 gehen auf NULL.
    Hier wird: TIMSK |= (1<<OCIE0) mit ODER! eingeführt, d.h.
                                                              1
    									*/
    void TMR_0_init( void )	
    {				//Initialisiere 8-Bit-Timer auf 10 kHz
        TCCR0 |= (1<<CS01 | 1<<CS00); // Prescaler 1/64 / Clock <- CPU
        TCCR0 |= (1<<WGM01 | 0<<WGM00);	// Timer im CTC-Mode
        OCR0 = 25;   			// Preset 25 für 100µs bei 16Mhz  
        TIMSK |= (1<<OCIE0); 		// Compare Match IRQ 
    }
    /* ============================================================================== */
    
    
    /* ===  Nicht unterbrechbare ISR für EXT_INT0 auf Pin 16/PD2/mega16(32)  ======== */
    /* Routine setzt einfach einen Zähler hoch. Der Zähler wird im main
         ausgelesen ##>> cli/sei setzen <<## und nach 2 (od. 5) hunderstel Sekunden
         auf den Speicher WEG_L/_R vorzeichenrichtig aufaddiert und dann zurückgesetzt.
         ##>> Beim Richtungswechsel (cli/sei) wird der Zähler ausgelesen und genullt,
         damit ist eine saubere Wegmessung möglich.
         Der zugehörige Motor auf RNControl auf PB0/PB1 = li,re und PD5 Geschwind.
         Der alternat.  Motor auf RNControl auf PC7/PC6 = li,re und PB4 PWM/Geschw.
    $002 jmp EXT_INT0 ; IRQ0 Handler                  */
    SIGNAL(SIG_INTERRUPT0)
    {
        Iencdr1 ++;				//zähle Counter/encoder 1 hoch
        Iz_yseci1 = Izeit_1;		//Weise musi den akt. Timerwert zu
        Iz_diff1 = Iz_yseci1-Iz_ysecv1;	//Neue Zeit-Differenz1 ausrechnen
        Iz_ysecv1 = Iz_yseci1;		//der aktuelle Zeitwert wird "Alter"
    {
        if (Iencdr1 == 5000);
        PORTC ^= (1<<PC3);			//LED4 toggeln  alle 5000 Interrupts
      }
        PORTC ^= (1<<PC4);			//LED5 toggeln bei JEDEM Interrupt
    }
    /* ============================================================================== */
    
    
    /* ============================================================================== */
    /* ===  Nicht unterbrechbare ISR für EXT_INT1 auf Pin 17/PD3/mega16(32)  ======== */
    /* Routine setzt einfach einen Zähler hoch.
          Sonst wie ISR für EXT_INT0 für Motor auf PC7/PC6 = li,re und PB4 PWM/Geschw.
    
    $004 jmp EXT_INT1 ; IRQ1 Handler                  */
    SIGNAL(SIG_INTERRUPT1)
    {
        Iencdr2 ++;				//zähle Counter/encoder 2 hoch
        Iz_yseci2 = Izeit_1;		//Weise Iz_yseci den akt. Timerwert zu
        Iz_diff2 = Iz_yseci2-Iz_ysecv2;	//Neue Zeit-Differenz2 ausrechnen
        Iz_ysecv2 = Iz_yseci2;		//der aktuelle Zeitwert wird "Alter"
        PORTC ^= (1<<PC5);			//LED6 toggeln bei JEDEM Interrupt
    }
    /* ============================================================================== */
    
    
    /* ============================================================================== */
    /* ===  Nicht unterbrechbare ISR für timer ====================================== */
    /* Diese Routine zählt hoch im Takt 10 kHz.setzen.
          Dieser Wert wird von den beiden anderen ISR ausgelesen und den Werten      */
    // SIGNAL(SIG_OVERFLOW0)
    // #define SIG_OUTPUT_COMPARE0	//Interuptvektor, siehe Tabelle
    SIGNAL(SIG_OUTPUT_COMPARE0)
    {
      {
        if (Izeit_1 <= 10000)
    	Izeit_1 ++;		//Zeitstand Interupt-Timer läuft von 1 .. 10 000
        else
    	Izeit_1 = 0;
      }
      {				// von hier bis Ende (LED2 toggeln) nur Testphase
        if (Izeit_1 == 1)
        PORTC ^= (1<<PC2);		//LED3 toggeln alle Sekunde
      }
    	PORTC ^= (1<<PC1);	//LED2 toggeln jeden Interrupt
    }
    /* ============================================================================== */
    läßt die LED auf PC1 genau mit 0,1 ms blinken, die LED auf PC2 im Sekundenrhythmus - 10 000 mal 0,1 ms - aber die in den ISR für extInt0 und ~1 angesprochenen LED´s tun nichts.

    Ich habe PD2 und PD3 mit 10k gegen GND geschaltet und taste sie von Hand auf Vcc. Es geschieht nichts .

    Frage:
    Ist die Initialisierung in void XTI_01_init( void ) korrekt?
    Sind die ISR SIGNAL(SIG_INTERRUPT0) und die SIGNAL(SIG_INTERRUPT1) korrekt?
    Ich gehe davon aus, dass der mega16 seine Interrupt-Vektortabelle über die <avr/interrupt.h> einlädt. Das ist doch ok? Sonst würde ja schon die ISR für Timer0 nicht laufen. Und in der iom16.h steht ja auch:
    Code:
    /* Interrupt vectors */
    /* Vector 0 is the reset vector. */
    /* External Interrupt Request 0 */
    #define INT0_vect			_VECTOR(1)
    #define SIG_INTERRUPT0			_VECTOR(1)
    
    /* External Interrupt Request 1 */
    #define INT1_vect			_VECTOR(2)
    #define SIG_INTERRUPT1			_VECTOR(2)
    ... und das ist genau meine Schreibweise.


    Danke im Voraus.
    Ciao sagt der JoeamBerg

  5. #15
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Mit was programmierst du eigentlich, diese GCC-Version ist schon veraltet. Wenn du das AVR-Studio verwendest kannst du ziemlich viel simulieren.
    Sonst poste den gesamten Code, dann kann ich ihn mal simulieren.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  6. #16
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    Schönen Abend, Hubert.G,

    seit dem 10. Nov. läuft bei mir:

    AVR Studio 4.13.557 Service Pack 1
    GUI Version 4, 13, 0, 557
    und
    WinAVR 2007 0525

    davor hatte ich (am 09. Nov. 07 von sourceforge.net geholt und installiert):

    AVR Studio 4.12.460
    GUI Version 4, 12, 0, 460
    mit Servicepack 2
    das lief aber garnicht stabil bei mir.

    Ach - mit dem kompletten Code wollte ich den Thread nicht zumüllen. So toll ist der nicht (blos viele Kommentare, weil ich mir so wenig merken kann).
    Code:
    /* >> Diese ersten 2 Zeilen können zum Compilieren entfernt werden (muss nicht)
      Sicherung 19dez07 1654 nach Datei ..C1..\2_drehzahlen\2_drehzahlen-x26.c
     ===================================================================================
     ========== Beachte: printout aus AVRStudio geht (nur) bis col 85 ==================
      Target MCU        : ATmega16
      Target Hardware   : RNControl
      Target cpu-frequ. : 16 MHz, externer Quarzoszillator
     ===================================================================================
      Enthaltene Routinen:
      	#include "mlib-M16_x10_jwt.h"
      	static inline void setportd(c)on(off)
    	void Motst_aufab(void)		// Mot li+re, vor+zur, aufab
    	void XTI_01_init( void )	// ISR external Intrrpt 0+1 initialisieren
    	void TMR_0_init( void )		// ISR Timer0 initialisieren
    	SIGNAL (SIG_INTERRUPT0)		// ISR Motor/Speed1 erfassen
    	SIGNAL (SIG_INTERRUPT1)		// ISR Motor/Speed2 erfassen
    	SIGNAL(SIG_OUTPUT_COMPARE0)	// Timer0 ISR, Zeitmarke hochzählen
    	int main(void)
     ===================================================================================
      *** Versionsgeschichte:
     ====================
     x26 19dez07 16:54 Test: Zähle in ISR SIG_INTERRUPT0 Iencodr1 hoch und
     		zünde LED auf PortC3 wenn er auf 5000 ist LED auf PC4 toggeln bei
    		jedem Interrupt0 und PC5 toggeln bei jedem Interrupt1  ### nix
     x25 18dez07 18:12 Zustand: ISR OUTPUT_COMPARE0 toggelt LED 2 + 5,
     	MotorPWM läuft, Start-LED läuft..... ### Library MUSS M16conform sein ###
     x23b 18dez07 15:34 erstellt nach x24, durch x23 ohne USART+sound    OK
     	mit "alter" motstlib_x10_jwt.h. Motorroutinen laufen (lt. Oskar).
     x24 18dez07 14:50 UART und sound läuft nicht korrekt mit ISR => gestrichen =>
     	ABER jetzt ist natürlich die Datenerkennung nicht mehr möglich.
    	Läuft nicht mit motstlib_x20_jwt
     x23 18dez07 12:22 x21 wieder übernommen und ISR für Timer0 umbenannt von
     	SIGNAL(SIG_OVERFLOW0)  nach  SIGNAL(SIG_OUTPUT_COMPARE0)      OK
     x22 18dez07 12:05ff alles zusammenstreichen bis auf die "Grundversion" mit 
     	TMR_0_ ... und so     12:05 geht nix
     x21 18dez07 11:53
     	Nachtrag aus x14. Test: TMR_0_init() + sei() <==> dann läuft nix mehr :(
     x20 17dez07 23:43ff
     	Nachtrag der Berichtigungen aus der Testversion 2_drehzahlen-xxxok.c
     x14 18dez07 10:17 Bessere Dokumentation in TMR_0_init, LED auf PD4 wird getoggelt
     x12 18dez07 00:22 Läuft mit der richtigen Frequenz
     xxxok 17dez07 23:40 Testversion mit ordentlichem Interrupt - Frequenz stimmt nicht
     x11 17dez07 17:mmff Test - seltsame Ergebnisse - Timer timt nicht 
     x10 17dez07 15:43 Erster Codeausbau fertig zum Test (sichern und LED-Test mit 
     				dem Timer0
         18dez07 00:04 - - läuft noch nicht
     x01 16dez07 23:42 Sichern des ersten Standes - ohne Timer-Interrupt-Routine
     x00 16dez07 14:30ff erster Aufbau
     ===================================================================================
      *** Aufgabenstellung : Messen von 2 Motordrehzahlen
      Es werden Impulse von zwei Gabellichtschranken am µC erfasst. Daraus werden
        zwei Drehzahlen errechnet.
        Drehzahlbereich von 0 (Stillstand) bis 1kHz (60 000 Upm)
    
        Grundlage wird ein Timerinterrupt mit 
    
      Original: ...C1..\C-motst_x10\C_motst_x21_OK.c
     ===================================================================================
                                                                                      */
    /* ============================================================================== */
    
    #include <stdlib.h> 
    #include <avr/io.h> 
    #include <avr/interrupt.h>
    /* Beachte C:\Programme\WinAVR-20070525\avr\include\avr\iom16.h */
    #include "mlib-M16_x10_jwt.h"
    
    #define MCU = ATMega16 
    
    //   Mit Quarz 16 Mhz-CPU 
    #define F_CPU  16000000 
    
    /* ============================================================================== */
    /*   Interrupt-Handler und -Adressen
    Address Labels Code Comments
    siehe C:\Programme\WinAVR-20070525\avr\include\avr\iom16.h sowie
    Interruptvektoren/-vektortabelle in *doc2466, S 45+46 von AVR                    */
    
    /*### Variablenliste, global ###*/
    uint8_t i=1, kre=1, kli=1;
    uint8_t min=15, max=122;
    
    /* beachte: volatile!  und   Vorzeichenlos reicht für alle                   */
    volatile uint16_t Iencdr1, Iencdr2;	/* Counter für Encoder-ticks
      Werden in der ISR hochgezählt und im main bei Gelegenheit
        (welcher? - nach 5 sec?) - spätestens aber beim Fahrtrichtungswechsel
        auf Null gesetzt. DAnn aber die Werte musv+musi entsprechend anpassen    */
    volatile uint16_t Iz_ysecv1, Iz_ysecv2;	/* Zeitmarke "µsec"
      des vorletzten Interrupts in der Einheit 100 Mikrosekunden. Ist der Wert des
      hochlaufenden Timers zum Interruptzeitpunkt i-1                            */
    volatile uint16_t Iz_yseci1, Iz_yseci2;	/* Zeitmarke "µsec"
        des letzten Interrupts in der Einheit 100 Mikrosekunden. Ist der Wert des
        hochlaufenden Timers zum Interruptzeitpunkt i (letzter Interrupt)        */
    volatile uint16_t Iz_diff1, Iz_diff2;	/* Zeitdifferenz
      Beim Abarbeiten des Interrupts wird yseci mit time1 belegt und diff aus der
        Differenz yseci-ysecv errechnet. Danach wird yseci nach ysecv kopiert.
        Im main wird aus diff die Drehzahl berechnet.                            */
    volatile uint16_t Izeit_1;			/* Timer läuft hoch
      Die Interruptroutine läuft mit 10 kHz (Möglicherweise sind 100 kHz besser)
        Beim Start des Timers läuft der Zähler time1 hoch und wird nach 5 sec -
        also beim Wert 50 000 - wieder auf Null gesetzt. Dabei werden die Werte
        ysecv und yseci angepasst                                                  */
    /* ============================================================================== */
    //   ### Portroutinen und waitms aus RNContr Demo C 
    //   *### Ports setzen auf HIGH/LOW  ### 
    
      static inline void setportdon(const uint8_t n) 
      {PORTD |= (1<<n);}   //set PORTD.n high 
      static inline void setportdoff(const uint8_t n) 
      {PORTD &= ~(1<<n);}   //set PORTD.n low 
        static inline void setportcon(const uint8_t n) 
      {PORTC |= (1<<n);}   //set PORTC.n high 
      static inline void setportcoff(const uint8_t n) 
      {PORTC &= ~(1<<n);}   //set PORTC.n low 
    
    
    
    /*### Motortest mit tiny2313 auf exp2313-232/2 mit motL293-aufsteck/1
    	Anschluss (1+3) als negativ (schwarz), Anschluss (2+4) als positiv
     ============================================================================== */
    void Motst_aufab(void)	// Mot li+re, vor+zur, aufab
    {
    	Mlinksvor();
    	Mrechtsvor();
    
    	setPWMlinks(0);
    	setPWMrechts(0);
    	waitms(40);
    
    	for(uint16_t i=10; i<199; i=i+1)
    	{
    		kre=i;
    		kli=i+2;
    		setPWMlinks(kli);
    		setPWMrechts(kre);
    		waitms(1000);
    	}
    	waitms(1000);
    	for(uint16_t i=199; i>10; i=i-1)
    	{
    		kre=i;
    		kli=i+2;
    		setPWMlinks(kli);
    		setPWMrechts(kre);
    		waitms(1000);
    	}
    	setPWMlinks(0);
    	setPWMrechts(0);
    
    	Mlinksstop();
    	Mrechtsstop();
    	waitms(300);
    }
    /* ============================================================================== */
    
    
    /* =================================================================================
       ##### Hier ISR und ISR - Initialisierung(en)
    ================================================================================= */
    /* ===  Initialisierung fuer EXT_INT0/1 auf Pin 16+17/mega16(32)  ==================
    $002 jmp SIG_INTERRUPT0 ; IRQ0 Handler und
    $004 jmp SIG_INTERRUPT1 ; IRQ1 Handler                  */
    void XTI_01_init( void )	
    {				//Initialisiere beide Interrupts auf rising edge
    				//  d.h. MCUCR ISC00,01,10+11 auf 1 (doc,S68)
        MCUCR |= (1<<ISC11|1<<ISC10|1<<ISC01|1<<ISC00);
        GICR  |= (1<<INT1|1<<INT0);	//  und erlaube diese I´s in GICR
    }
    /* ============================================================================== */
    
    
    /* ===  Initialisierung fuer Timer mega16(32)  =====================================
    SIGNAL (SIG_OVERFLOW0)
    Beachte zu TIMSK:
                     OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0   TIMSK
    Read/Write        R/W   R/W   R/W    R/W    R/W    R/W   R/W   R/W
    Initial Value      0     0     0      0      0      0     0     0
    
    RNControl          0     0     1      1      1      1     0     0     hex 3c
    ###>>> dieser Wert wird GESETZT, d.h. Bit 0, 1, 6 und 7 gehen auf NULL.
    Hier wird: TIMSK |= (1<<OCIE0) mit ODER! eingeführt, d.h.
                                                              1
    									*/
    void TMR_0_init( void )	
    {				//Initialisiere 8-Bit-Timer auf 10 kHz
        TCCR0 |= (1<<CS01 | 1<<CS00); // Prescaler 1/64 / Clock <- CPU
        TCCR0 |= (1<<WGM01 | 0<<WGM00);	// Timer im CTC-Mode
        OCR0 = 25;   			// Preset 25 für 100µs bei 16Mhz  
        TIMSK |= (1<<OCIE0); 		// Compare Match IRQ 
    }
    /* ============================================================================== */
    
    
    /* ===  Nicht unterbrechbare ISR für EXT_INT0 auf Pin 16/PD2/mega16(32)  ======== */
    /* Routine setzt einfach einen Zähler hoch. Der Zähler wird im main
         ausgelesen ##>> cli/sei setzen <<## und nach 2 (od. 5) hunderstel Sekunden
         auf den Speicher WEG_L/_R vorzeichenrichtig aufaddiert und dann zurückgesetzt.
         ##>> Beim Richtungswechsel (cli/sei) wird der Zähler ausgelesen und genullt,
         damit ist eine saubere Wegmessung möglich.
         Der zugehörige Motor auf RNControl auf PB0/PB1 = li,re und PD5 Geschwind.
         Der alternat.  Motor auf RNControl auf PC7/PC6 = li,re und PB4 PWM/Geschw.
    $002 jmp EXT_INT0 ; IRQ0 Handler                  */
    SIGNAL(SIG_INTERRUPT0)
    {
        Iencdr1 ++;				//zähle Counter/encoder 1 hoch
        Iz_yseci1 = Izeit_1;		//Weise musi den akt. Timerwert zu
        Iz_diff1 = Iz_yseci1-Iz_ysecv1;	//Neue Zeit-Differenz1 ausrechnen
        Iz_ysecv1 = Iz_yseci1;		//der aktuelle Zeitwert wird "Alter"
    {
        if (Iencdr1 == 5000);
        PORTC ^= (1<<PC3);			//LED4 toggeln  alle 5000 Interrupts
      }
        PORTC ^= (1<<PC4);			//LED5 toggeln bei JEDEM Interrupt
    }
    /* ============================================================================== */
    
    
    /* ============================================================================== */
    /* ===  Nicht unterbrechbare ISR für EXT_INT1 auf Pin 17/PD3/mega16(32)  ======== */
    /* Routine setzt einfach einen Zähler hoch.
          Sonst wie ISR für EXT_INT0 für Motor auf PC7/PC6 = li,re und PB4 PWM/Geschw.
    
    $004 jmp EXT_INT1 ; IRQ1 Handler                  */
    SIGNAL(SIG_INTERRUPT1)
    {
        Iencdr2 ++;				//zähle Counter/encoder 2 hoch
        Iz_yseci2 = Izeit_1;		//Weise Iz_yseci den akt. Timerwert zu
        Iz_diff2 = Iz_yseci2-Iz_ysecv2;	//Neue Zeit-Differenz2 ausrechnen
        Iz_ysecv2 = Iz_yseci2;		//der aktuelle Zeitwert wird "Alter"
        PORTC ^= (1<<PC5);			//LED6 toggeln bei JEDEM Interrupt
    }
    /* ============================================================================== */
    
    
    /* ============================================================================== */
    /* ===  Nicht unterbrechbare ISR für timer ====================================== */
    /* Diese Routine zählt hoch im Takt 10 kHz.setzen.
          Dieser Wert wird von den beiden anderen ISR ausgelesen und den Werten      */
    // SIGNAL(SIG_OVERFLOW0)
    // #define SIG_OUTPUT_COMPARE0	//Interuptvektor, siehe Tabelle
    SIGNAL(SIG_OUTPUT_COMPARE0)
    {
      {
        if (Izeit_1 <= 10000)
    	Izeit_1 ++;		//Zeitstand Interupt-Timer läuft von 1 .. 10 000
        else
    	Izeit_1 = 0;
      }
      {				// von hier bis Ende (LED2 toggeln) nur Testphase
        if (Izeit_1 == 1)
        PORTC ^= (1<<PC2);		//LED3 toggeln alle Sekunde
      }
    	PORTC ^= (1<<PC1);	//LED2 toggeln jeden Interrupt
    }
    /* ============================================================================== */
    
    
    
    
    // ------------------------------------------------------------------ 
    /*### Hauptschleife ###*/ 
    int main(void) 
    {
    //  DDRB=0x3f;		// 0011 1111 -> Ports B für Motor als Ausgänge
    //  DDRD=0x08;		// 0000 1000 -> PortsD 3 als Ausgang
    /*  Im Unterschied zur Vorlage (für tiny2313 ist dieser Code für den ATMega16
        auf RNControl <==> nimm dortige Initialisierungen mit folgender Änderung
        Encoder-Eingang 1   PortA1
        Encoder-Eingang 2   PortA2
    */
    	/*###Initialisierungsphase###      Direkt aus RNContorl-test.c importiert*/
    
    	//Pins bzw. Ports als Ein-/Ausgänge konfigurieren
    	DDRA |= 0x00;	//00000000 -> alle Analogports als Eingänge
    	DDRB |= 0x03;	//00000011 -> PB0 und PB1 Kanäle des rechten Motors
    	DDRC |= 0xFF;	//11111111 -> PC6 und PC7 linker Mot, Rest LEDs/Lauflicht
    	DDRD |= 0xB0;	//10110000 -> D4 PWM linker Motors, PD5 rechter Mot
    	
    	//Initialisierungen
    	setportcon(0); setportcon(1); setportcon(2); setportcon(3);
    	setportcon(4); setportcon(5); setportcon(6); setportcon(7); //LEDs aus
    	// setportdoff(7);	//Speaker aus
    
    	init_timer1();	//Initialisierung Timer für PWM
    //		USART_Init(UBRR);     //USART initialisieren 
        
    	TMR_0_init();	//Initialisiere den Timer0-Interrupt (10 kHz)
    	sei();		//Globalen Interrupt freigeben
    
    
       for(i=0; i<20; i++)
       {
           setportcoff(0);	//2 sek blinken mit LED3 nach dem Reset -
           waitms(15);	//  damit man kurze resets besser erkennt
           setportcon(0);
           waitms(85);
       }
    
    for(;;){ 
           	setportcoff(0);
    	waitms(1000);
    	setportcon(0);
    	waitms(1000);
    	
    	Mlinksstop();
    	Mrechtsstop();
    	setPWMlinks(0);
    	setPWMrechts(0);
    	Motst_aufab();		
    	}
    }
    In Assembler hatte ich immer (na ja, gelegentlich) im AVRStudio mit dem Debugger ganz gut Fehlersuche praktiziert. Das hab ich mit C auch schon versucht - da läuft der CPU-Lüfter so schön hoch oder ? - aber ich bin meist nicht auf die Breakpoints gekommen. Da ich im letzten Monat eine Festplatte (Klar, die C - aber nur das System - und ein Netzteil geliefert hatte und da die Hilfe mir nicht EINDEUTIG sagte, dass debuggen in C möglich ist, hab ich da vorerst bei C nix weiter gemacht.

    Danke für die Mühe, (und sorry, ich muss zu einer Abendveranstaltung)
    Ciao sagt der JoeamBerg

  7. #17
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    Die Version mit der USART-Ausgabe (war für das letzte posting zu umfangreich) ist :
    Code:
    /* >> Diese ersten 2 Zeilen können zum Compilieren entfernt werden (muss nicht)
      Sicherung 18dez07 1222 nach Datei ..C1..\2_drehzahlen\2_drehzahlen-x23ok.c
     ===================================================================================
     ========== Beachte: printout aus AVRStudio geht (nur) bis col 85 ==================
      Target MCU        : ATmega16
      Target Hardware   : RNControl
      Target cpu-frequ. : 16 MHz, externer Quarzoszillator
     ===================================================================================
      Enthaltene Routinen:
    	static inline void setportdon/~off
    	void ext_int_init (void)	// ISR ext1+2 initialisieren  <<< offen
    	void tmr_int_init (void)	// Timer ISR  initialisieren  <<< offen
    	################################# diese beiden Routinen sind ISR
    					Timer fehlen
    	void USART_Init( unsigned int baud ) 
    	void sendchar(unsigned char c)
    	void sendUSART(char *s)
    	void Motst_aufab(void)		// Mot li+re, vor+zur, aufab
    	SIGNAL (SIG_INTERRUPT0)		// ISR Motor/Speed1
    	SIGNAL (SIG_INTERRUPT1)		// ISR Motor/Speed2
    	int main(void)
     ===================================================================================
      *** Versionsgeschichte:
     ====================
     x23 18dez07 12:22 x21 wieder übernommen und ISR für Timer0 umbenannt von
     	SIGNAL(SIG_OVERFLOW0)  nach  SIGNAL(SIG_OUTPUT_COMPARE0)      OK
     x22 18dez07 12:05ff alles zusammenstreichen bis auf die "Grundversion" mit 
     	TMR_0_ ... und so     12:05 geht nix
     x21 18dez07 11:53
     	Nachtrag aus x14. Test: TMR_0_init() + sei() <==> dann läuft nix mehr :(
     x20 17dez07 23:43ff
     	Nachtrag der Berichtigungen aus der Testversion 2_drehzahlen-xxxok.c
     x14 18dez07 10:17 Bessere Dokumentation in TMR_0_init, LED auf PD4 wird getoggelt
     x12 18dez07 00:22 Läuft mit der richtigen Frequenz
     xxxok 17dez07 23:40 Testversion mit ordentlichem Interrupt - Frequenz stimmt nicht
     x11 17dez07 17:mmff Test - seltsame Ergebnisse - Timer timt nicht 
     x10 17dez07 15:43 Erster Codeausbau fertig zum Test (sichern und LED-Test mit 
     				dem Timer0
         18dez07 00:04 - - läuft noch nicht
     x01 16dez07 23:42 Sichern des ersten Standes - ohne Timer-Interrupt-Routine
     x00 16dez07 14:30ff erster Aufbau
     ===================================================================================
      *** Aufgabenstellung : Messen von 2 Motordrehzahlen
      Es werden Impulse von zwei Gabellichtschranken am µC erfasst. Daraus werden
        zwei Drehzahlen errechnet.
        Drehzahlbereich von 0 (Stillstand) bis 1kHz (60 000 Upm)
    
        Grundlage wird ein Timerinterrupt mit 
    
      Original: ...C1..\C-motst_x10\C_motst_x21_OK.c
     ===================================================================================
                                                                                      */
    /* ============================================================================== */
    
    #include <stdlib.h> 
    #include <avr/io.h> 
    #include <avr/interrupt.h>
    /* Beachte C:\Programme\WinAVR-20070525\avr\include\avr\iom16.h */
    #include "motstlib_x10_jwt.h"
    
    #define MCU = ATMega16 
    
    //   Mit Quarz 16 Mhz-CPU 
    #define F_CPU  16000000 
    #define BAUD 38400 
    #define UBRR (unsigned int)(F_CPU / BAUD / 16 - 0.5) 
    
    /* ============================================================================== */
    /*   Interrupt-Handler und -Adressen
    Address Labels Code Comments
    siehe C:\Programme\WinAVR-20070525\avr\include\avr\iom16.h sowie
    Interruptvektoren/-vektortabelle in *doc2466, S 45+46 von AVR                    */
    
    /*### Variablenliste, global ###*/
    // uint8_t i=1, k=1, max=120, min=35;
    uint8_t i=1, kre=1, kli=1;
    uint8_t min=15, max=122;
    char id_MCU [30]; 
    
    /* beachte: volatile!  und   Vorzeichenlos reicht für alle                   */
    volatile uint16_t Iencdr1, Iencdr2;	/* Counter für Encoder-ticks
      Werden in der ISR hochgezählt und im main bei Gelegenheit
        (welcher? - nach 5 sec?) - spätestens aber beim Fahrtrichtungswechsel
        auf Null gesetzt. DAnn aber die Werte musv+musi entsprechend anpassen    */
    volatile uint16_t Iz_ysecv1, Iz_ysecv2;	/* Zeitmarke "µsec"
      des vorletzten Interrupts in der Einheit 100 Mikrosekunden. Ist der Wert des
      hochlaufenden Timers zum Interruptzeitpunkt i-1                            */
    volatile uint16_t Iz_yseci1, Iz_yseci2;	/* Zeitmarke "µsec"
        des letzten Interrupts in der Einheit 100 Mikrosekunden. Ist der Wert des
        hochlaufenden Timers zum Interruptzeitpunkt i (letzter Interrupt)        */
    volatile uint16_t Iz_diff1, Iz_diff2;	/* Zeitdifferenz
      Beim Abarbeiten des Interrupts wird yseci mit time1 belegt und diff aus der
        Differenz yseci-ysecv errechnet. Danach wird yseci nach ysecv kopiert.
        Im main wird aus diff die Drehzahl berechnet.                            */
    volatile uint16_t Izeit_1;			/* Timer läuft hoch
      Die Interruptroutine läuft mit 10 kHz (Möglicherweise sind 100 kHz besser)
        Beim Start des Timers läuft der Zähler time1 hoch und wird nach 5 sec -
        also beim Wert 50 000 - wieder auf Null gesetzt. Dabei werden die Werte
        ysecv und yseci angepasst                                                  */
    /* ============================================================================== */
    //   ### Portroutinen und waitms aus RNContr Demo C 
    //   *### Ports setzen auf HIGH/LOW  ### 
    
      static inline void setportdon(const uint8_t n) 
      {PORTD |= (1<<n);}   //set PORTD.n high 
      static inline void setportdoff(const uint8_t n) 
      {PORTD &= ~(1<<n);}   //set PORTD.n low 
        static inline void setportcon(const uint8_t n) 
      {PORTC |= (1<<n);}   //set PORTC.n high 
      static inline void setportcoff(const uint8_t n) 
      {PORTC &= ~(1<<n);}   //set PORTC.n low 
    
    
    
    /*### Senden per USART - RS232-Kommunikation ###*/
    /*Zum senden von Zeichen im Hauptprogramm entweder
    char irgendwas[] = "meintext";
    sendUSART(irgendwas);		oder direkt
    sendUSART("meinText");		verwenden.		*/ 
    
    /*
     ===================================================================================						
       Dieser Codeschnipsel ähnlich 2313-doc, S 121 				  */
    void USART_Init( unsigned int baud ) 
    { 					// Set baud rate
    UBRRH = (unsigned char)(baud>>8); 
    UBRRL = (unsigned char)baud;		// Enable receiver and transmitter
    UCSRB = (1<<RXEN)|(1<<TXEN); 		// Set frame format: 8data, 2stop bit
    UCSRC = (3<<UCSZ0); 
    } 
    
    // ------------------------------------------------------------------ 
    void sendchar(unsigned char c) 
    { 
       while(!(UCSRA & (1<<UDRE))) //Warten, bis Senden möglich ist 
       { 
       } 
       UDR = c; //schreibt das Zeichen aus 'c' auf die Schnittstelle 
    } 
    
    // ------------------------------------------------------------------ 
    void sendUSART(char *s) //*s funktiniert wie eine Art Array - auch bei 
             // einem String werden die Zeichen (char) 
             // einzeln ausgelesen - und auf die 
             // Sendeschnittstelle übertragen 
    { 
       while(*s) 
       { 
       sendchar(*s); 
       s++; 
       } 
    } 
    
    
    
    /*### Motortest mit tiny2313 auf exp2313-232/2 mit motL293-aufsteck/1
    	Anschluss (1+3) als negativ (schwarz), Anschluss (2+4) als positiv
    	hier für m16/RNControl
     ============================================================================== */
    void Motst_aufab(void)	// Mot li+re, vor+zur, aufab
    {
    char worti[5], wortkli[5], wortkre[5];
    	Mlinksvor();
    	Mrechtsvor();
    
    	setPWMlinks(0);
    	setPWMrechts(0);
    	waitms(40);
    	sendUSART("\r\nMotortest ~x21\r\n");
    	sendUSART("PWM-Stellwerte\r\n");
    	sendUSART("_n__li__re\r\n"); 
    
    	for(uint16_t i=10; i<199; i=i+1)
    	{
    		kre=i;
    		kli=i+2;
    		setPWMlinks(kli);
    		setPWMrechts(kre);
    		waitms(1000);
    		utoa(i, worti, 10);
    		utoa(kli, wortkli, 10);
    		utoa(kre, wortkre, 10);
    		sendUSART(worti);sendUSART("  ");
    		sendUSART(wortkli);sendUSART("  ");
    		sendUSART(wortkre);sendUSART("\r\n");
    	}
    	waitms(1000);
    /*	sendUSART("tiny2313\r\n");
    	sendUSART("PWM-Stellwerte\r\n");
    	sendUSART("_n__li__re\r\n");
    				Ausgeblendet wegen Speicherplatzbedarf  */
    	for(uint16_t i=199; i>10; i=i-1)
    	{
    		kre=i;
    		kli=i+2;
    		setPWMlinks(kli);
    		setPWMrechts(kre);
    		waitms(1000);
    //		utoa(i, worti, 10);
    //		utoa(kli, wortkli, 10);
    //		utoa(kre, wortkre, 10);
    //		sendUSART(worti);sendUSART("  ");
    //		sendUSART(wortkli);sendUSART("  ");
    //		sendUSART(wortkre);sendUSART("\r\n");
    	}
    	setPWMlinks(0);
    	setPWMrechts(0);
    
    	Mlinksstop();
    	Mrechtsstop();
    	waitms(300);
    }
    /* ============================================================================== */
    
    
    
    
    /* =================================================================================
       ##### Hier ISR und ISR - Initialisierung(en)
    ================================================================================= */
    /* ===  Initialisierung fuer EXT_INT0/1 auf Pin 16+17/mega16(32)  ==================
    $002 jmp SIG_INTERRUPT0 ; IRQ0 Handler und
    $004 jmp SIG_INTERRUPT1 ; IRQ1 Handler                  */
    void XTI_01_init( void )	
    {				//Initialisiere beide Interrupts auf rising edge
    				//  d.h. MCUCR ISC00,01,10+11 auf 1 (doc,S68)
        MCUCR |= (1<<ISC11)|(1<<ISC10)|(1<<ISC01)|(1<<ISC00);
        GICR  |= (1<<INT1)|(1<<INT0);	//  und erlaube diese I´s in GICR
    }
    /* ============================================================================== */
    
    
    /* ===  Initialisierung fuer Timer mega16(32)  =====================================
    SIGNAL (SIG_OVERFLOW0)
    Beachte zu TIMSK:
                     OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0   TIMSK
    Read/Write        R/W   R/W   R/W    R/W    R/W    R/W   R/W   R/W
    Initial Value      0     0     0      0      0      0     0     0
    
    RNControl          0     0     1      1      1      1     0     0     hex 3c
    ###>>> dieser Wert wird GESETZT, d.h. Bit 0, 1, 6 und 7 gehen auf NULL.
    Hier wird: TIMSK |= (1<<OCIE0) mit ODER! eingeführt, d.h.
                                                              1
    									*/
    void TMR_0_init( void )	
    {				//Initialisiere 8-Bit-Timer auf 10 kHz
        TCCR0 |= (1<<CS01 | 1<<CS00); // Prescaler 64 / Clock <- CPU
        TCCR0 |= (1<<WGM01 | 0<<WGM00);	// Timer im CTC-Mode
        OCR0 = 25;   			// Preset 25 für 100µs bei 16Mhz  
        TIMSK |= (1<<OCIE0); 		// Compare Match IRQ 
    }
    /* ============================================================================== */
    
    
    /* ===  Nicht unterbrechbare ISR für EXT_INT0 auf Pin 16/PD2/mega16(32)  ======== */
    /* Routine setzt einfach einen Zähler hoch. Der Zähler wird im main
         ausgelesen ##>> cli/sei setzen <<## und nach 2 (od. 5) hunderstel Sekunden
         auf den Speicher WEG_L/_R vorzeichenrichtig aufaddiert und dann zurückgesetzt.
         ##>> Beim Richtungswechsel (cli/sei) wird der Zähler ausgelesen und genullt,
         damit ist eine saubere Wegmessung möglich.
         Der zugehörige Motor auf RNControl auf PB0/PB1 = li,re und PD5 Geschwind.
         Der alternat.  Motor auf RNControl auf PC7/PC6 = li,re und PB4 PWM/Geschw.
    $002 jmp EXT_INT0 ; IRQ0 Handler                  */
    SIGNAL(SIG_INTERRUPT0)
    {
        Iencdr1 ++;			//zähle Counter/encoder 1 hoch
        Iz_yseci1 = Izeit_1;		//Weise musi den akt. Timerwert zu
        Iz_diff1 = Iz_yseci1-Iz_ysecv1;	    //Neue Zeit-Differenz1 ausrechnen
        Iz_ysecv1 = Iz_yseci1;		//der aktuelle Zeitwert wird "Alter"
    }
    /* ============================================================================== */
    
    
    /* ============================================================================== */
    /* ===  Nicht unterbrechbare ISR für EXT_INT1 auf Pin 17/PD3/mega16(32)  ======== */
    /* Routine setzt einfach einen Zähler hoch.
          Sonst wie ISR für EXT_INT0 für Motor auf PC7/PC6 = li,re und PB4 PWM/Geschw.
    
    $004 jmp EXT_INT1 ; IRQ1 Handler                  */
    SIGNAL(SIG_INTERRUPT1)
    {
        Iencdr2 ++;			//zähle Counter/encoder 2 hoch
        Iz_yseci2 = Izeit_1;		//Weise Iz_yseci den akt. Timerwert zu
        Iz_diff2 = Iz_yseci2-Iz_ysecv2;	//Neue Zeit-Differenz2 ausrechnen
        Iz_ysecv2 = Iz_yseci2;		//der aktuelle Zeitwert wird "Alter"
    }
    /* ============================================================================== */
    
    
    /* ============================================================================== */
    /* ===  Nicht unterbrechbare ISR für timer ====================================== */
    /* Diese Routine zählt hoch im Takt 10 kHz.setzen.
          Dieser Wert wird von den beiden anderen ISR ausgelesen und den Werten
    
    */
    // SIGNAL(SIG_OVERFLOW0)
    // #define SIG_OUTPUT_COMPARE0	//Interuptvektor, siehe Tabelle
    SIGNAL(SIG_OUTPUT_COMPARE0)
    {
        Izeit_1 ++;			//Zeitstand des Interupt-Timers
    
        PORTC ^= (1 << PC1);	//LED toggeln
    
    }
    /* ============================================================================== */
    
    
    
    
    // ------------------------------------------------------------------ 
    /*### Hauptschleife ###*/ 
    int main(void) 
    {
    //  DDRB=0x3f;		// 0011 1111 -> Ports B für Motor als Ausgänge
    //  DDRD=0x08;		// 0000 1000 -> PortsD 3 als Ausgang
    /*  Im Unterschied zur Vorlage (für tiny2313 ist dieser Code für den ATMega16
        auf RNControl <==> nimm dortige Initialisierungen mit folgender Änderung
        Encoder-Eingang 1   PortA1
        Encoder-Eingang 2   PortA2
    */
    	/*###Initialisierungsphase###      Direkt aus RNContorl-test.c importiert*/
    
    	//Pins bzw. Ports als Ein-/Ausgänge konfigurieren
    	DDRA |= 0x00;	//00000000 -> alle Analogports als Eingänge
    	DDRB |= 0x03;	//00000011 -> PB0 und PB1 Kanäle des rechten Motors
    	DDRC |= 0xFF;	//11111111 -> PC6 und PC7 linker Mot, Rest LEDs/Lauflicht
    	DDRD |= 0xB0;	//10110000 -> D4 PWM linker Motors, PD5 rechter Mot
    	
    	//Initialisierungen
    	setportcon(0); setportcon(1); setportcon(2); setportcon(3);
    	setportcon(4); setportcon(5); setportcon(6); setportcon(7); //LEDs aus
    	setportdoff(7);	//Speaker aus
    
    	init_timer1();	//Initialisierung Timer für PWM
    	USART_Init(UBRR);     //USART initialisieren 
        
    	TMR_0_init();	//Initialisiere den Timer0-Interrupt (10 kHz)
    	sei();		//Globalen Interrupt freigeben
    
    
       for(i=0; i<20; i++)
       {
           setportcoff(3);	//2 sek blinken nach dem Reset - damit man
           waitms(15);	//  kurze resets besser erkennt
           setportcon(3);
           waitms(85);
       }
    
    for(;;){ 
           	setportcoff(3);
    	waitms(1000);
    	setportcon(3);
    	waitms(1000);
    	
    /*	Mlinksstop();
    	Mrechtsstop();
    	setPWMlinks(0);
    	setPWMrechts(0);
    	Motst_aufab();		*/
    	}
    }
    die lief aber nur ohne Interrupt (die Quelle ist relativ "roh", sorry).
    Ciao sagt der JoeamBerg

  8. #18
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Ich kann mit nicht vorstellen das dieser Code irgendwie compilierbar ist.
    Aktuelle AVR-libc ist 1.4.7 oder 1.5.1
    Eine zusammenarbeit von waitms(xx) und Interrupt ist ohnehin problematisch.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  9. #19
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    Ich sass etwas auf heissen Kohlen weil ich meine beiden *lib*.h nicht mitgegeben hatte. Die unterschiedlichen Versionen verwenden unterschiedliche Bibliotheken. Die waitms(xx) wollte ich schon rauswerfen, sie stammt aus der header-Datei zum RNControl-Demoprogramm. Sie dient hier eher untergeordneten, also unkritischen Pausen, daher habe ich sie vorerst doch noch benutzt. WENN ich die zukünftig noch nutzen muss, werde ich sie vom Timerwert aus der SIG_OUTPUT_COMPARE0 ableiten.

    Die beiden geposteten Progrämmchen hatte das AVRStudio aber compiliert ? ! ? ?

    Bei der Übersetzung der "2_drehzahlen-x26.c" bekomme ich vom AVRStudio folgende build-meldungen:

    Build started 20.12.2007 at 00:42:01
    avr-gcc.exe -I"D:\pro-fils_D\computer+mcontroller\C1 mC Projekte\2_drehzahlen\util" -mmcu=atmega16 -Wall -gdwarf-2 -std=gnu99 -O0 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT 2_drehzahlen.o -MF dep/2_drehzahlen.o.d -
    c ../2_drehzahlen.c

    avr-gcc.exe -mmcu=atmega16 -Wl,-Map=2_drehzahlen.map 2_drehzahlen.o -o 2_drehzahlen.elf
    avr-objcopy -O ihex -R .eeprom 2_drehzahlen.elf 2_drehzahlen.hex
    avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex 2_drehzahlen.elf 2_drehzahlen.eep || exit 0
    c:\Programme\WinAVR-20070525\bin\avr-objcopy.exe: there are no sections to be copied!
    avr-objdump -h -S 2_drehzahlen.elf > 2_drehzahlen.lss

    AVR Memory Usage
    ----------------
    Device: atmega16

    Program: 1870 bytes (11.4% Full)
    (.text + .data + .bootloader)

    Data: 24 bytes (2.3% Full)
    (.data + .bss + .noinit)


    Build succeeded with 0 Warnings...

    und die 2_drehzahlen.lss sieht so aus: (siehe nächstes Posting - Zeichenlimit ist überschritten).... aber diesen Code bin ich noch nicht durchgegangen. Aber die SIG_INTERRUPT0 sieht darin "glaubhaft" aus. Anmerkung: Ich habe erst vorhin festgestellt, dass es so eine Datei nach dem Compilieren gibt. Wie gesagt: ich bin eher Anfänger.

    Der hexfile läuft auf meiner RNControl mit korrekter Funktion der TimerIRS - also das Zeitraster stimmt und auch z.B. das Umschalten der LED zum vorgegebenen Zählerstand innerhalb der ISR. Auch die Motoransteuerung funktioniert korrekt - bis auf die zeitliche Genauigkeit der waitms - klar. Es fehlt vollständig die Funktion der IRS für die beiden externen Interrupts.

    Ich weiss leider nicht, wo die AVR-libc benutzt wird - da sehe ich noch nach. Zu meiner Schande muss ich gestehen, dass ich von dieser lib erst seit Deiner Bemerkung weiss. Das user manual der lib trägt den Titel
    avr-libc Reference Manual
    1.4.6
    Generated by Doxygen 1.4.7
    Tue May 15 14:56:11 2007
    . . . das wäre doch (fast) die von Dir genannte Aktualität?

    Soweit ich das also betrachtet hatte (als C-Anfänger) sah das alles glaubhaft aus, bis auf die ausbleibenden externen Interrupts. Jetzt weiss ich nicht weiter.
    Angehängte Dateien Angehängte Dateien
    Ciao sagt der JoeamBerg

  10. #20
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    Die 2_drehzahlen.lss:

    Code:
    2_drehzahlen.elf:     file format elf32-avr
    
    Sections:
    Idx Name          Size      VMA       LMA       File off  Algn
      0 .text         00000748  00000000  00000000  00000094  2**1
                      CONTENTS, ALLOC, LOAD, READONLY, CODE
      1 .data         00000006  00800060  00000748  000007dc  2**0
                      CONTENTS, ALLOC, LOAD, DATA
      2 .bss          00000012  00800066  00800066  000007e2  2**0
                      ALLOC
      3 .stab         00000378  00000000  00000000  000007e4  2**2
                      CONTENTS, READONLY, DEBUGGING
      4 .stabstr      00000071  00000000  00000000  00000b5c  2**0
                      CONTENTS, READONLY, DEBUGGING
      5 .debug_aranges 00000020  00000000  00000000  00000bcd  2**0
                      CONTENTS, READONLY, DEBUGGING
      6 .debug_pubnames 000001a9  00000000  00000000  00000bed  2**0
                      CONTENTS, READONLY, DEBUGGING
      7 .debug_info   00000511  00000000  00000000  00000d96  2**0
                      CONTENTS, READONLY, DEBUGGING
      8 .debug_abbrev 000000d5  00000000  00000000  000012a7  2**0
                      CONTENTS, READONLY, DEBUGGING
      9 .debug_line   00000433  00000000  00000000  0000137c  2**0
                      CONTENTS, READONLY, DEBUGGING
     10 .debug_frame  00000140  00000000  00000000  000017b0  2**2
                      CONTENTS, READONLY, DEBUGGING
    Disassembly of section .text:
    
    00000000 <__vectors>:
       0:	0c 94 2a 00 	jmp	0x54	; 0x54 <__ctors_end>
       4:	0c 94 e4 01 	jmp	0x3c8	; 0x3c8 <__vector_1>
       8:	0c 94 45 02 	jmp	0x48a	; 0x48a <__vector_2>
       c:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      10:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      14:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      18:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      1c:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      20:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      24:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      28:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      2c:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      30:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      34:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      38:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      3c:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      40:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      44:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      48:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
      4c:	0c 94 9a 02 	jmp	0x534	; 0x534 <__vector_19>
      50:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
    
    00000054 <__ctors_end>:
      54:	11 24       	eor	r1, r1
      56:	1f be       	out	0x3f, r1	; 63
      58:	cf e5       	ldi	r28, 0x5F	; 95
      5a:	d4 e0       	ldi	r29, 0x04	; 4
      5c:	de bf       	out	0x3e, r29	; 62
      5e:	cd bf       	out	0x3d, r28	; 61
    
    00000060 <__do_copy_data>:
      60:	10 e0       	ldi	r17, 0x00	; 0
      62:	a0 e6       	ldi	r26, 0x60	; 96
      64:	b0 e0       	ldi	r27, 0x00	; 0
      66:	e8 e4       	ldi	r30, 0x48	; 72
      68:	f7 e0       	ldi	r31, 0x07	; 7
      6a:	02 c0       	rjmp	.+4      	; 0x70 <.do_copy_data_start>
    
    0000006c <.do_copy_data_loop>:
      6c:	05 90       	lpm	r0, Z+
      6e:	0d 92       	st	X+, r0
    
    00000070 <.do_copy_data_start>:
      70:	a6 36       	cpi	r26, 0x66	; 102
      72:	b1 07       	cpc	r27, r17
      74:	d9 f7       	brne	.-10     	; 0x6c <.do_copy_data_loop>
    
    00000076 <__do_clear_bss>:
      76:	10 e0       	ldi	r17, 0x00	; 0
      78:	a6 e6       	ldi	r26, 0x66	; 102
      7a:	b0 e0       	ldi	r27, 0x00	; 0
      7c:	01 c0       	rjmp	.+2      	; 0x80 <.do_clear_bss_start>
    
    0000007e <.do_clear_bss_loop>:
      7e:	1d 92       	st	X+, r1
    
    00000080 <.do_clear_bss_start>:
      80:	a8 37       	cpi	r26, 0x78	; 120
      82:	b1 07       	cpc	r27, r17
      84:	e1 f7       	brne	.-8      	; 0x7e <.do_clear_bss_loop>
      86:	0e 94 e5 02 	call	0x5ca	; 0x5ca <main>
      8a:	0c 94 a3 03 	jmp	0x746	; 0x746 <_exit>
    
    0000008e <__bad_interrupt>:
      8e:	0c 94 00 00 	jmp	0	; 0x0 <__vectors>
    
    00000092 <waitms>:
    /*### Programm pausieren lassen ###*/ 
    /*Pausenwert ist nur experimentell !*/ 
    
    void waitms(uint16_t ms) 
    { 
      92:	cf 93       	push	r28
      94:	df 93       	push	r29
      96:	cd b7       	in	r28, 0x3d	; 61
      98:	de b7       	in	r29, 0x3e	; 62
      9a:	24 97       	sbiw	r28, 0x04	; 4
      9c:	0f b6       	in	r0, 0x3f	; 63
      9e:	f8 94       	cli
      a0:	de bf       	out	0x3e, r29	; 62
      a2:	0f be       	out	0x3f, r0	; 63
      a4:	cd bf       	out	0x3d, r28	; 61
      a6:	9c 83       	std	Y+4, r25	; 0x04
      a8:	8b 83       	std	Y+3, r24	; 0x03
       for(; ms>0; ms--) 
      aa:	0f c0       	rjmp	.+30     	; 0xca <waitms+0x38>
       { 
          uint16_t __c = 4000; 
      ac:	80 ea       	ldi	r24, 0xA0	; 160
      ae:	9f e0       	ldi	r25, 0x0F	; 15
      b0:	9a 83       	std	Y+2, r25	; 0x02
      b2:	89 83       	std	Y+1, r24	; 0x01
          __asm__ volatile ( 
      b4:	89 81       	ldd	r24, Y+1	; 0x01
      b6:	9a 81       	ldd	r25, Y+2	; 0x02
      b8:	01 97       	sbiw	r24, 0x01	; 1
      ba:	f1 f7       	brne	.-4      	; 0xb8 <waitms+0x26>
      bc:	9a 83       	std	Y+2, r25	; 0x02
      be:	89 83       	std	Y+1, r24	; 0x01
      c0:	8b 81       	ldd	r24, Y+3	; 0x03
      c2:	9c 81       	ldd	r25, Y+4	; 0x04
      c4:	01 97       	sbiw	r24, 0x01	; 1
      c6:	9c 83       	std	Y+4, r25	; 0x04
      c8:	8b 83       	std	Y+3, r24	; 0x03
      ca:	8b 81       	ldd	r24, Y+3	; 0x03
      cc:	9c 81       	ldd	r25, Y+4	; 0x04
      ce:	00 97       	sbiw	r24, 0x00	; 0
      d0:	69 f7       	brne	.-38     	; 0xac <waitms+0x1a>
      d2:	24 96       	adiw	r28, 0x04	; 4
      d4:	0f b6       	in	r0, 0x3f	; 63
      d6:	f8 94       	cli
      d8:	de bf       	out	0x3e, r29	; 62
      da:	0f be       	out	0x3f, r0	; 63
      dc:	cd bf       	out	0x3d, r28	; 61
      de:	df 91       	pop	r29
      e0:	cf 91       	pop	r28
      e2:	08 95       	ret
    
    000000e4 <init_timer1>:
             "1: sbiw %0,1" "\n\t" 
             "brne 1b" 
             : "=w" (__c) 
             : "0" (__c) 
          ); 
       } 
    } 
    
    
    /*### PWM-Routinen zur Motoransteuerung -- aus rncontrol.h ###*/
    /* #####>>>>> Hier müssen die Motorports der RNControl umbenannt werden. Sie sind
    
    ------------
    Teile gelöscht wegen limitierter Posting-Länge
    
    
    /* =================================================================================
       ##### Hier ISR und ISR - Initialisierung(en)
    ================================================================================= */
    /* ===  Initialisierung fuer EXT_INT0/1 auf Pin 16+17/mega16(32)  ==================
    $002 jmp SIG_INTERRUPT0 ; IRQ0 Handler und
    $004 jmp SIG_INTERRUPT1 ; IRQ1 Handler                  */
    void XTI_01_init( void )	
    {				//Initialisiere beide Interrupts auf rising edge
     35e:	cf 93       	push	r28
     360:	df 93       	push	r29
     362:	cd b7       	in	r28, 0x3d	; 61
     364:	de b7       	in	r29, 0x3e	; 62
    				//  d.h. MCUCR ISC00,01,10+11 auf 1 (doc,S68)
        MCUCR |= (1<<ISC11)|(1<<ISC10)|(1<<ISC01)|(1<<ISC00);
     366:	a5 e5       	ldi	r26, 0x55	; 85
     368:	b0 e0       	ldi	r27, 0x00	; 0
     36a:	e5 e5       	ldi	r30, 0x55	; 85
     36c:	f0 e0       	ldi	r31, 0x00	; 0
     36e:	80 81       	ld	r24, Z
     370:	8f 60       	ori	r24, 0x0F	; 15
     372:	8c 93       	st	X, r24
        GICR  |= (1<<INT1)|(1<<INT0);	//  und erlaube diese I´s in GICR
     374:	ab e5       	ldi	r26, 0x5B	; 91
     376:	b0 e0       	ldi	r27, 0x00	; 0
     378:	eb e5       	ldi	r30, 0x5B	; 91
     37a:	f0 e0       	ldi	r31, 0x00	; 0
     37c:	80 81       	ld	r24, Z
     37e:	80 6c       	ori	r24, 0xC0	; 192
     380:	8c 93       	st	X, r24
     382:	df 91       	pop	r29
     384:	cf 91       	pop	r28
     386:	08 95       	ret
    
    00000388 <TMR_0_init>:
    }
    /* ============================================================================== */
    
    
    /* ===  Initialisierung fuer Timer mega16(32)  =====================================
    SIGNAL (SIG_OVERFLOW0)
    Beachte zu TIMSK:
                     OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0   TIMSK
    Read/Write        R/W   R/W   R/W    R/W    R/W    R/W   R/W   R/W
    Initial Value      0     0     0      0      0      0     0     0
    
    RNControl          0     0     1      1      1      1     0     0     hex 3c
    ###>>> dieser Wert wird GESETZT, d.h. Bit 0, 1, 6 und 7 gehen auf NULL.
    Hier wird: TIMSK |= (1<<OCIE0) mit ODER! eingeführt, d.h.
                                                              1
    									*/
    void TMR_0_init( void )	
    {				//Initialisiere 8-Bit-Timer auf 10 kHz
     388:	cf 93       	push	r28
     38a:	df 93       	push	r29
     38c:	cd b7       	in	r28, 0x3d	; 61
     38e:	de b7       	in	r29, 0x3e	; 62
        TCCR0 |= (1<<CS01 | 1<<CS00); // Prescaler 1/64 / Clock <- CPU
     390:	a3 e5       	ldi	r26, 0x53	; 83
     392:	b0 e0       	ldi	r27, 0x00	; 0
     394:	e3 e5       	ldi	r30, 0x53	; 83
     396:	f0 e0       	ldi	r31, 0x00	; 0
     398:	80 81       	ld	r24, Z
     39a:	83 60       	ori	r24, 0x03	; 3
     39c:	8c 93       	st	X, r24
        TCCR0 |= (1<<WGM01 | 0<<WGM00);	// Timer im CTC-Mode
     39e:	a3 e5       	ldi	r26, 0x53	; 83
     3a0:	b0 e0       	ldi	r27, 0x00	; 0
     3a2:	e3 e5       	ldi	r30, 0x53	; 83
     3a4:	f0 e0       	ldi	r31, 0x00	; 0
     3a6:	80 81       	ld	r24, Z
     3a8:	88 60       	ori	r24, 0x08	; 8
     3aa:	8c 93       	st	X, r24
        OCR0 = 25;   			// Preset 25 für 100µs bei 16Mhz  
     3ac:	ec e5       	ldi	r30, 0x5C	; 92
     3ae:	f0 e0       	ldi	r31, 0x00	; 0
     3b0:	89 e1       	ldi	r24, 0x19	; 25
     3b2:	80 83       	st	Z, r24
        TIMSK |= (1<<OCIE0); 		// Compare Match IRQ 
     3b4:	a9 e5       	ldi	r26, 0x59	; 89
     3b6:	b0 e0       	ldi	r27, 0x00	; 0
     3b8:	e9 e5       	ldi	r30, 0x59	; 89
     3ba:	f0 e0       	ldi	r31, 0x00	; 0
     3bc:	80 81       	ld	r24, Z
     3be:	82 60       	ori	r24, 0x02	; 2
     3c0:	8c 93       	st	X, r24
     3c2:	df 91       	pop	r29
     3c4:	cf 91       	pop	r28
     3c6:	08 95       	ret
    
    000003c8 <__vector_1>:
    }
    /* ============================================================================== */
    
    
    /* ===  Nicht unterbrechbare ISR für EXT_INT0 auf Pin 16/PD2/mega16(32)  ======== */
    /* Routine setzt einfach einen Zähler hoch. Der Zähler wird im main
         ausgelesen ##>> cli/sei setzen <<## und nach 2 (od. 5) hunderstel Sekunden
         auf den Speicher WEG_L/_R vorzeichenrichtig aufaddiert und dann zurückgesetzt.
         ##>> Beim Richtungswechsel (cli/sei) wird der Zähler ausgelesen und genullt,
         damit ist eine saubere Wegmessung möglich.
         Der zugehörige Motor auf RNControl auf PB0/PB1 = li,re und PD5 Geschwind.
         Der alternat.  Motor auf RNControl auf PC7/PC6 = li,re und PB4 PWM/Geschw.
    $002 jmp EXT_INT0 ; IRQ0 Handler                  */
    SIGNAL(SIG_INTERRUPT0)
    {
     3c8:	1f 92       	push	r1
     3ca:	0f 92       	push	r0
     3cc:	0f b6       	in	r0, 0x3f	; 63
     3ce:	0f 92       	push	r0
     3d0:	11 24       	eor	r1, r1
     3d2:	2f 93       	push	r18
     3d4:	3f 93       	push	r19
     3d6:	4f 93       	push	r20
     3d8:	5f 93       	push	r21
     3da:	8f 93       	push	r24
     3dc:	9f 93       	push	r25
     3de:	af 93       	push	r26
     3e0:	bf 93       	push	r27
     3e2:	ef 93       	push	r30
     3e4:	ff 93       	push	r31
     3e6:	cf 93       	push	r28
     3e8:	df 93       	push	r29
     3ea:	cd b7       	in	r28, 0x3d	; 61
     3ec:	de b7       	in	r29, 0x3e	; 62
        Iencdr1 ++;				//zähle Counter/encoder 1 hoch
     3ee:	80 91 68 00 	lds	r24, 0x0068
     3f2:	90 91 69 00 	lds	r25, 0x0069
     3f6:	01 96       	adiw	r24, 0x01	; 1
     3f8:	90 93 69 00 	sts	0x0069, r25
     3fc:	80 93 68 00 	sts	0x0068, r24
        Iz_yseci1 = Izeit_1;		//Weise musi den akt. Timerwert zu
     400:	80 91 72 00 	lds	r24, 0x0072
     404:	90 91 73 00 	lds	r25, 0x0073
     408:	90 93 6b 00 	sts	0x006B, r25
     40c:	80 93 6a 00 	sts	0x006A, r24
        Iz_diff1 = Iz_yseci1-Iz_ysecv1;	//Neue Zeit-Differenz1 ausrechnen
     410:	20 91 6a 00 	lds	r18, 0x006A
     414:	30 91 6b 00 	lds	r19, 0x006B
     418:	80 91 6c 00 	lds	r24, 0x006C
     41c:	90 91 6d 00 	lds	r25, 0x006D
     420:	a9 01       	movw	r20, r18
     422:	48 1b       	sub	r20, r24
     424:	59 0b       	sbc	r21, r25
     426:	ca 01       	movw	r24, r20
     428:	90 93 71 00 	sts	0x0071, r25
     42c:	80 93 70 00 	sts	0x0070, r24
        Iz_ysecv1 = Iz_yseci1;		//der aktuelle Zeitwert wird "Alter"
     430:	80 91 6a 00 	lds	r24, 0x006A
     434:	90 91 6b 00 	lds	r25, 0x006B
     438:	90 93 6d 00 	sts	0x006D, r25
     43c:	80 93 6c 00 	sts	0x006C, r24
    {
        if (Iencdr1 == 5000);
     440:	80 91 68 00 	lds	r24, 0x0068
     444:	90 91 69 00 	lds	r25, 0x0069
        PORTC ^= (1<<PC3);			//LED4 toggeln  alle 5000 Interrupts
     448:	a5 e3       	ldi	r26, 0x35	; 53
     44a:	b0 e0       	ldi	r27, 0x00	; 0
     44c:	e5 e3       	ldi	r30, 0x35	; 53
     44e:	f0 e0       	ldi	r31, 0x00	; 0
     450:	90 81       	ld	r25, Z
     452:	88 e0       	ldi	r24, 0x08	; 8
     454:	89 27       	eor	r24, r25
     456:	8c 93       	st	X, r24
      }
        PORTC ^= (1<<PC4);			//LED5 toggeln bei JEDEM Interrupt
     458:	a5 e3       	ldi	r26, 0x35	; 53
     45a:	b0 e0       	ldi	r27, 0x00	; 0
     45c:	e5 e3       	ldi	r30, 0x35	; 53
     45e:	f0 e0       	ldi	r31, 0x00	; 0
     460:	90 81       	ld	r25, Z
     462:	80 e1       	ldi	r24, 0x10	; 16
     464:	89 27       	eor	r24, r25
     466:	8c 93       	st	X, r24
     468:	df 91       	pop	r29
     46a:	cf 91       	pop	r28
     46c:	ff 91       	pop	r31
     46e:	ef 91       	pop	r30
     470:	bf 91       	pop	r27
     472:	af 91       	pop	r26
     474:	9f 91       	pop	r25
     476:	8f 91       	pop	r24
     478:	5f 91       	pop	r21
     47a:	4f 91       	pop	r20
     47c:	3f 91       	pop	r19
     47e:	2f 91       	pop	r18
     480:	0f 90       	pop	r0
     482:	0f be       	out	0x3f, r0	; 63
     484:	0f 90       	pop	r0
     486:	1f 90       	pop	r1
     488:	18 95       	reti
    
    0000048a <__vector_2>:
    }
    /* ============================================================================== */
    
    
    /* ============================================================================== */
    /* ===  Nicht unterbrechbare ISR für EXT_INT1 auf Pin 17/PD3/mega16(32)  ======== */
    /* Routine setzt einfach einen Zähler hoch.
          Sonst wie ISR für EXT_INT0 für Motor auf PC7/PC6 = li,re und PB4 PWM/Geschw.
    
    $004 jmp EXT_INT1 ; IRQ1 Handler                  */
    SIGNAL(SIG_INTERRUPT1)
    {
     48a:	1f 92       	push	r1
     48c:	0f 92       	push	r0
     48e:	0f b6       	in	r0, 0x3f	; 63
     490:	0f 92       	push	r0
     492:	11 24       	eor	r1, r1
     494:	2f 93       	push	r18
     496:	3f 93       	push	r19
     498:	4f 93       	push	r20
     49a:	5f 93       	push	r21
     49c:	8f 93       	push	r24
     49e:	9f 93       	push	r25
     4a0:	af 93       	push	r26
     4a2:	bf 93       	push	r27
     4a4:	ef 93       	push	r30
     4a6:	ff 93       	push	r31
     4a8:	cf 93       	push	r28
     4aa:	df 93       	push	r29
     4ac:	cd b7       	in	r28, 0x3d	; 61
     4ae:	de b7       	in	r29, 0x3e	; 62
        Iencdr2 ++;				//zähle Counter/encoder 2 hoch
     4b0:	80 91 66 00 	lds	r24, 0x0066
     4b4:	90 91 67 00 	lds	r25, 0x0067
     4b8:	01 96       	adiw	r24, 0x01	; 1
     4ba:	90 93 67 00 	sts	0x0067, r25
     4be:	80 93 66 00 	sts	0x0066, r24
        Iz_yseci2 = Izeit_1;		//Weise Iz_yseci den akt. Timerwert zu
     4c2:	80 91 72 00 	lds	r24, 0x0072
     4c6:	90 91 73 00 	lds	r25, 0x0073
     4ca:	90 93 6f 00 	sts	0x006F, r25
     4ce:	80 93 6e 00 	sts	0x006E, r24
        Iz_diff2 = Iz_yseci2-Iz_ysecv2;	//Neue Zeit-Differenz2 ausrechnen
     4d2:	20 91 6e 00 	lds	r18, 0x006E
     4d6:	30 91 6f 00 	lds	r19, 0x006F
     4da:	80 91 74 00 	lds	r24, 0x0074
     4de:	90 91 75 00 	lds	r25, 0x0075
     4e2:	a9 01       	movw	r20, r18
     4e4:	48 1b       	sub	r20, r24
     4e6:	59 0b       	sbc	r21, r25
     4e8:	ca 01       	movw	r24, r20
     4ea:	90 93 77 00 	sts	0x0077, r25
     4ee:	80 93 76 00 	sts	0x0076, r24
        Iz_ysecv2 = Iz_yseci2;		//der aktuelle Zeitwert wird "Alter"
     4f2:	80 91 6e 00 	lds	r24, 0x006E
     4f6:	90 91 6f 00 	lds	r25, 0x006F
     4fa:	90 93 75 00 	sts	0x0075, r25
     4fe:	80 93 74 00 	sts	0x0074, r24
        PORTC ^= (1<<PC5);			//LED6 toggeln bei JEDEM Interrupt
     502:	a5 e3       	ldi	r26, 0x35	; 53
     504:	b0 e0       	ldi	r27, 0x00	; 0
     506:	e5 e3       	ldi	r30, 0x35	; 53
     508:	f0 e0       	ldi	r31, 0x00	; 0
     50a:	90 81       	ld	r25, Z
     50c:	80 e2       	ldi	r24, 0x20	; 32
     50e:	89 27       	eor	r24, r25
     510:	8c 93       	st	X, r24
     512:	df 91       	pop	r29
     514:	cf 91       	pop	r28
     516:	ff 91       	pop	r31
     518:	ef 91       	pop	r30
     51a:	bf 91       	pop	r27
     51c:	af 91       	pop	r26
     51e:	9f 91       	pop	r25
     520:	8f 91       	pop	r24
     522:	5f 91       	pop	r21
     524:	4f 91       	pop	r20
     526:	3f 91       	pop	r19
     528:	2f 91       	pop	r18
     52a:	0f 90       	pop	r0
     52c:	0f be       	out	0x3f, r0	; 63
     52e:	0f 90       	pop	r0
     530:	1f 90       	pop	r1
     532:	18 95       	reti
    
    00000534 <__vector_19>:
    }
    /* ============================================================================== */
    
    
    /* ============================================================================== */
    /* ===  Nicht unterbrechbare ISR für timer ====================================== */
    /* Diese Routine zählt hoch im Takt 10 kHz.setzen.
          Dieser Wert wird von den beiden anderen ISR ausgelesen und den Werten      */
    // SIGNAL(SIG_OVERFLOW0)
    // #define SIG_OUTPUT_COMPARE0	//Interuptvektor, siehe Tabelle
    SIGNAL(SIG_OUTPUT_COMPARE0)
    {
     534:	1f 92       	push	r1
     536:	0f 92       	push	r0
     538:	0f b6       	in	r0, 0x3f	; 63
     53a:	0f 92       	push	r0
     53c:	11 24       	eor	r1, r1
     53e:	2f 93       	push	r18
     540:	8f 93       	push	r24
     542:	9f 93       	push	r25
     544:	af 93       	push	r26
     546:	bf 93       	push	r27
     548:	ef 93       	push	r30
     54a:	ff 93       	push	r31
     54c:	cf 93       	push	r28
     54e:	df 93       	push	r29
     550:	cd b7       	in	r28, 0x3d	; 61
     552:	de b7       	in	r29, 0x3e	; 62
      {
        if (Izeit_1 <= 10000)
     554:	80 91 72 00 	lds	r24, 0x0072
     558:	90 91 73 00 	lds	r25, 0x0073
     55c:	27 e2       	ldi	r18, 0x27	; 39
     55e:	81 31       	cpi	r24, 0x11	; 17
     560:	92 07       	cpc	r25, r18
     562:	50 f4       	brcc	.+20     	; 0x578 <__vector_19+0x44>
    	Izeit_1 ++;		//Zeitstand Interupt-Timer läuft von 1 .. 10 000
     564:	80 91 72 00 	lds	r24, 0x0072
     568:	90 91 73 00 	lds	r25, 0x0073
     56c:	01 96       	adiw	r24, 0x01	; 1
     56e:	90 93 73 00 	sts	0x0073, r25
     572:	80 93 72 00 	sts	0x0072, r24
     576:	04 c0       	rjmp	.+8      	; 0x580 <__vector_19+0x4c>
        else
    	Izeit_1 = 0;
     578:	10 92 73 00 	sts	0x0073, r1
     57c:	10 92 72 00 	sts	0x0072, r1
      }
      {				// von hier bis Ende (LED2 toggeln) nur Testphase
        if (Izeit_1 == 1)
     580:	80 91 72 00 	lds	r24, 0x0072
     584:	90 91 73 00 	lds	r25, 0x0073
     588:	81 30       	cpi	r24, 0x01	; 1
     58a:	91 05       	cpc	r25, r1
     58c:	41 f4       	brne	.+16     	; 0x59e <__vector_19+0x6a>
        PORTC ^= (1<<PC2);		//LED3 toggeln alle Sekunde
     58e:	a5 e3       	ldi	r26, 0x35	; 53
     590:	b0 e0       	ldi	r27, 0x00	; 0
     592:	e5 e3       	ldi	r30, 0x35	; 53
     594:	f0 e0       	ldi	r31, 0x00	; 0
     596:	90 81       	ld	r25, Z
     598:	84 e0       	ldi	r24, 0x04	; 4
     59a:	89 27       	eor	r24, r25
     59c:	8c 93       	st	X, r24
      }
    	PORTC ^= (1<<PC1);	//LED2 toggeln jeden Interrupt
     59e:	a5 e3       	ldi	r26, 0x35	; 53
     5a0:	b0 e0       	ldi	r27, 0x00	; 0
     5a2:	e5 e3       	ldi	r30, 0x35	; 53
     5a4:	f0 e0       	ldi	r31, 0x00	; 0
     5a6:	90 81       	ld	r25, Z
     5a8:	82 e0       	ldi	r24, 0x02	; 2
     5aa:	89 27       	eor	r24, r25
     5ac:	8c 93       	st	X, r24
     5ae:	df 91       	pop	r29
     5b0:	cf 91       	pop	r28
     5b2:	ff 91       	pop	r31
     5b4:	ef 91       	pop	r30
     5b6:	bf 91       	pop	r27
     5b8:	af 91       	pop	r26
     5ba:	9f 91       	pop	r25
     5bc:	8f 91       	pop	r24
     5be:	2f 91       	pop	r18
     5c0:	0f 90       	pop	r0
     5c2:	0f be       	out	0x3f, r0	; 63
     5c4:	0f 90       	pop	r0
     5c6:	1f 90       	pop	r1
     5c8:	18 95       	reti
    
    000005ca <main>:
    }
    /* ============================================================================== */
    
    
    
    
    // ------------------------------------------------------------------ 
    /*### Hauptschleife ###*/ 
    int main(void) 
    
    
    #### dies gelöscht wegen begrenzter Posting-länge
    
    
    00000746 <_exit>:
     746:	ff cf       	rjmp	.-2      	; 0x746 <_exit>
    Ciao sagt der JoeamBerg

Seite 2 von 4 ErsteErste 1234 LetzteLetzte

Berechtigungen

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

LiFePO4 Speicher Test