-         

Ergebnis 1 bis 2 von 2

Thema: STM32F4 - Timer als Counter - ISR löst nach Initialisierung sporadisch aus.

  1. #1
    Erfahrener Benutzer Roboter-Spezialist Avatar von erik_wolfram
    Registriert seit
    02.12.2009
    Ort
    Berlin
    Beiträge
    406

    STM32F4 - Timer als Counter - ISR löst nach Initialisierung sporadisch aus.

    Anzeige

    Hallo,

    ich merke schon, dass ich in diesen Forum sehr aktiv bin Fragen zu stellen.
    Nun habe ich mal wieder ein neues Problem bei einem Interupt von verketteten Timern.

    Grundsätzlich möchte ich einen umfangreichen Funktionsgenerator mit einem externen 16-Bit DAC realisieren. Dieser wird über einen DMA und SPI angesteuert.
    Als Mikrocontroller kommt ein STM32F07VG Discovery zum Einsatz.

    Der Programmablauf sieht wie folgend aus.

    - ich verwende TIM8 für das Triggern des DMA-Vorgangs um die Werte koninuierlich auszugeben. (Der DMA funktioniert und wird daher nicht näher beschrieben)
    - TIM8 wirkt als Master-Timer und gibt beim Überlauf (update) den internen Trigger aus
    - TIM4 nutzt diesen Trigger (ITR3) als Slave als Taktquelle
    - ein Überlauf-Interupt von TIM4 soll die Ausgabe von X Werten abfangen und den vollständigen Vorgang beenden

    Da der DMA im Circular Mode arbeitet kann ich hier nicht die Werte mitzählen und wollte den TIM4 stattdessen nutzen.
    Das Abfangen der X Werte funktioniert. Doch nach der Initialisierung von TIM4 und dem Interupt lösst dieses in variierenden Abständen einmal aus.
    Das Mitzählen und Abbrechen der Ausgabevorganges funktiert nach dem einmaligen Auslösen des Interupts zuverlässig.

    Der Code sieht so aus (vereinfacht):
    Code:
    void TIM8_init()
    {
        ...
        TIM_TimeBaseInit( TIM8, &TIM_TimeBaseStructure );
    
        // Select the TRGO source
        TIM_SelectOutputTrigger( TIM8, TIM_TRGOSource_Update );                                
        TIM_SelectMasterSlaveMode( TIM8, TIM_MasterSlaveMode_Enable );                       
        ...
    }
    
    
    void TIM4_init()
    {
        RCC_APB1PeriphClockCmd( RCC_APB1ENR_TIM4EN, ENABLE );
    
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    
        TIM_TimeBaseStructure.TIM_Prescaler =             0;                           
        TIM_TimeBaseStructure.TIM_CounterMode =         TIM_CounterMode_Up;                    
        TIM_TimeBaseStructure.TIM_Period =                 5;                            
        TIM_TimeBaseStructure.TIM_ClockDivision =         TIM_CKD_DIV1;   
                
        TIM_DeInit( TIM4 );
        TIM_TimeBaseInit( TIM4, &TIM_TimeBaseStructure );
    
        TIM_SetCounter( TIM4, 0 );
    
        // TIM2 durch TIM8 synchron starten
        TIM_SelectInputTrigger(TIM4, TIM_TS_ITR3);                       
        TIM_SelectSlaveMode( TIM4, TIM_SlaveMode_External1 );                
    
        TIM_ITConfig( TIM4, TIM_IT_Update, ENABLE );
    
        NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_InitStructure.NVIC_IRQChannel =                     TIM4_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =     0;           
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =         0;
        NVIC_InitStructure.NVIC_IRQChannelCmd =                 ENABLE;
        NVIC_Init( &NVIC_InitStructure );
    
        TIM_Cmd( TIM4, ENABLE );
    }
    
    
    void TIM4_IRQHandler()
    {
        if( TIM_GetITStatus( TIM4, TIM_IT_Update ) == SET )
        {
            // ClearITPendigBit TIM8 Update
            TIM_ClearITPendingBit( TIM4, TIM_IT_Update);
    
            TIM_Cmd( TIM8, DISABLE );
        }
    }
    
    
    main
    {
        ...
        TIM8_init();
        TIM4_init();
    
        TIM_Cmd( TIM8, ENABLE );
        ...
    
    }
    Wie kann das vorschnelle Ausösen des Überlauf-Interupts erfolgen? Ich habe auch schon den CNT-Wert mit Werten größer 0 initialisiert - trotzdem wird jedesmal das Überlaufinterupt einmal aufgerufen...

    Gruß Erik
    Meine Projekte auf Youtube

  2. #2
    Erfahrener Benutzer Roboter-Spezialist Avatar von erik_wolfram
    Registriert seit
    02.12.2009
    Ort
    Berlin
    Beiträge
    406
    Nach längerem Suchen und einen ausführlichen Debugen bin ich dem Fehler auf die Schliche gekommen.

    Ich verwende die StdPeriph-Driver Bibleothek. Zum Ende der Timer-Initialisierung wird im EGR-Register das Bit0 gesetzt und sollte laut Beschreibung ein Update-Event generieren, welches durch die Hardware automatisch gelöscht werden sollte.
    Das erfolgt jedoch nicht, und sobald ich danach das Interupt aktiviere springt das Programm auf Grund des bestehenden ISR-Flags ins Interupt.

    Abhilfe:

    TIM_TimeBaseInit( TIM4, &TIM_TimeBaseStructure );
    ...
    TIM_ClearITPendingBit( TIM4, TIM_IT_Update);
    TIM_ITConfig( TIM4, TIM_IT_Update, ENABLE );


    Den Fehler will ich den anderen Nutzern nicht vorenthalten. Die Verkettung der Timer, bzw. Zähler funktioniert jetzt so.
    Meine Projekte auf Youtube

Ähnliche Themen

  1. Hilfestellung für DAC-Initialisierung beim STM32F4 gesucht
    Von erik_wolfram im Forum ARM - 32-bit-Mikrocontroller-Architektur
    Antworten: 4
    Letzter Beitrag: 29.02.2016, 19:11
  2. Timer/Counter und PWM Channles
    Von ricola im Forum C - Programmierung (GCC u.a.)
    Antworten: 9
    Letzter Beitrag: 04.07.2007, 20:48
  3. Timer/Counter
    Von Jon im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 16
    Letzter Beitrag: 17.05.2007, 19:43
  4. Timer initialisierung
    Von goobelz im Forum ARM - 32-bit-Mikrocontroller-Architektur
    Antworten: 2
    Letzter Beitrag: 28.01.2006, 17:05
  5. Timer 2 Initialisierung
    Von duderino im Forum PIC Controller
    Antworten: 1
    Letzter Beitrag: 06.04.2005, 09:27

Berechtigungen

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