-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 19

Thema: STM32F100/ Capture Compare Unit

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    07.07.2011
    Beiträge
    35

    STM32F100/ Capture Compare Unit

    Anzeige

    Hallo,

    ich bin bei Konfiguration TIM2 als Compare Capture Timer.

    Genau diesen Timer habe ich ausgewählt, weil:

    "These Timers (TIM1, TIM2, and TIM3) are capable of handling quadrature (incremental) encoder signals and the digital outputs from 1 to 3 hall-effect sensors. Page 19"

    SUPER!!! Genau das brauche ich, denn ich einen incremntal-Drehgeber steuern möchte.

    Also dieser Timer - soweit ich richtig verstanden habe- kann als Capture Compare Unit verwendet werden.

    Er besitzt 4-Chanels jeweils Counter und Compare/Capture_Register (CCR).

    Wird es funktionieren, wenn ich:

    1) Den Counter von CH-2 stelle ich so ein, dass er 65535 up-countet (16-Bit). sein PSC stelle ich auf 24 ein, somit ist der Counter_Clock 1MHz (24/24).Demzufolge countet der Counter pro 1µs. so braucht er ca. 65536*1µ= 65ms.

    2) Der Capture Eingang ist über Signalleitung mit dem Geber_Pulssignal verbunden. Den konfiguriere ich so, dass er die Steigende Flanke captures. Hinter her stelle den PSC auf 4. So werden 4 steigende Flanken gecaptured, ist der Psc Voll danach wird den Counter-Stand ausgelesen und in CCR kopiert.

    3) 1und 2 widerhole ich für den zweiten CH nämlich CH_3 mit dem Unterschied, dass der Capture die Fallende Flanke erwischen soll.

    4) am Ende habe ich zwei Value (Zeit der 4-Steigende Flanke und Zeit der 4_Fallende Flanke), die werden durch den Copmare vergleichen und den sich daraus ergebenden Wer wird durch Interrupt im Main Program abgegeben.

    So der Counter zählt ganz normal.
    Der Capture beobachtet den Eingagnssignal(bei dem soll ich nur einstellen was soll er erfassen (steigende oder fallende) oder gibt noch was einzustellen?)
    und der Compare vergleicht die Werte die sich im CCR befinden.

    Den Code habe ich Wie geschrieben:

    Hier ist die Konfiguration des Counters:

    TIM2_Configuration.TIM_CounterMode= TIM_CounterMode_Up;
    TIM2_Configuration.TIM_Prescaler= 24;// 24 MHz dividiert durch 24MHz ist 1MHz
    TIM2_Configuration.TIM_Period=65535;// Counter zählt bis 65535
    TIM2_Configuration.TIM_ClockDivision= 0X0;
    TIM2_Configuration.TIM_RepetitionCounter= 0x0;
    TIM_TimeBaseInit(TIM2,&TIM2_Configuration);

    Hier sind die Configuration für Input Capture:

    Input_Capture.TIM_Channel= TIM_Channel_2;// an ch_2 von Tim_2 ist der Drehsignal angeschlossen
    Input_Capture.TIM_ICPolarity= TIM_ICPolarity_Rising;// bei Steigender Flanke wird erfasst
    Input_Capture.TIM_ICSelection = TIM_ICSelection_DirectTI;
    Input_Capture.TIM_ICPrescaler = TIM_ICPSC_DIV4;// jede Vier Flanke
    Input_Capture.TIM_ICFilter = 0x0;

    TIM_ICInit(TIM2, &Input_Capture);
    TIM_Cmd(TIM2, ENABLE);// Der Counter von Tim2 wird eingeschaltet

    Hier ist die CC_Interrupt

    TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);

    Schließlich kommt die nested vector Tabelle.

    /* Enable the TIM2 global Interrupt */

    NVIC_InitStructure.NVIC_IRQChannel= TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriori ty=0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
    NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    Ich bin jedem sehr DANKBAR, der mir weiter helfen kann.

    LG.

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    09.04.2008
    Beiträge
    376
    Ich verstehe eigentlich das Problem nicht. Diese Timer konnen so konfiguriert werden das ein kwadratuur encoder eingelesen werd. Der counter wird dan eindeutig die Flanken zaehlen und abhangig das A oder B erst kommt in die richtige Richtung zaehlen. So hat der Counter immer die exacte Position von Drehgeber. Einen Input Capture muss nicht gemacht werden. Ich habe diese Function schon getestet mit das Discovery board, und das functioniert. Für eine Geschwindigkeitsmessung kan ess Sinn machen von die Abstand zwischen Zwei Flanken zu erfassen. In Prinzip muss das auch moglich sein, aber dan mussen sie eine extra Timer verwenden. Das ist dan eine standard ICP Ablauf. Functioniert auch bei mir, aber standard wird oder die Steigende Flanke, oder die Fallende flanke captiert. Zwie moglichkeiten um beide zu captieren : Zwei Kanalen verwenden (ein Timer hat 4 Kanalen) oder das register in ISR selbst togglen.
    Sie mussen naturlich auch noch die ISR programmieren. Da werd bei jeden capture ein TIM2_IRQHandler aufgerufen. In diesen ISR muss dan getestet werden in welches Kanal das passiert ware. Forbild von so einen ISR (steht bei mir in die c-file: stm32f10x_it.c (IAR compiler)

    Code:
    void TIM2_IRQHandler(void)
    { 
      
      if(TIM_GetITStatus(TIM2, TIM_IT_CC3) == SET) //stijgende flank : stroom> 10 mA
        {
          kanaal[i]=  TIM_GetCapture3(TIM2)-ICP_old;     
          ICP_old=TIM_GetCapture3(TIM2);
         /* Clear TIM3 Capture compare interrupt pending bit */
          TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);    
        }
      if(TIM_GetITStatus(TIM2, TIM_IT_CC4) == SET) //dalende flank : stroom< 10 mA
        {
          kanaal[i]=  TIM_GetCapture4(TIM2)-ICP_old;
           ICP_old=TIM_GetCapture4(TIM2);
        /* Clear TIM4 Capture compare interrupt pending bit */
          TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);    
        }
      
    }
    Geändert von RP6conrad (14.07.2011 um 21:49 Uhr)

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    07.07.2011
    Beiträge
    35
    [QUOTE=RP6conrad;518054]Ich verstehe eigentlich das Problem nicht.

    Das Problem liegt an :

    1) Den Capture: ich bin nicht sicher ob es so funktioniert, und ob ich es richtig eingestellt habe?.

    a)wie wird die Flanke erfasst? soweit ich weiss, er beobachtet den Einganssignal und reagiert auf bestimmten Event. und er tut das abgesehn wie schnell/langsma läuft der Counter

    b)wird die steigende Flanke mit dieser Zeile Erfasst?
    Input_Capture.TIM_ICPolarity= TIM_ICPolarity_Rising;

    2)Den Counter: mir ist nicht sicher ob Autoreload laufen soll? Ich glaube nicht, denn ich will nur wissen bei welchem Stand war er Bei Erfassung einer Flanke
    TIM2_Configuration.TIM_Period=65535;
    er zählt bis 65535 und dann fängt von null an
    TIM2_Configuration.TIM_RepetitionCounter= 0x0;

    3)Den Compare: wie lasse ihn einen Interrupt auslösen, wenn die Zwei Werte verglieschen hat?
    löst der CC1 einen Interrupt aus, wenn er zwei Values verglischen hat?
    TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE)

    4)Bestimmung die Werte: wie werden die Werte dem Compare zugewiesen?

    Timer2 hat 4 Chanels.
    CH-1 möchte ich für das erste Eingangssignal zur verfügung stellen
    CH-2 für das Zweite Eingagnssignal
    CH-3 möchte ich als Ausgangsbit, womit ich ein Led toggle. (optional)

    wie kann ich die Werte von den Capturs an einzigen Compare leiten.

    Ich bitte um Hilfe, Orientierung.

    Vielen Dank

  4. #4
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    09.04.2008
    Beiträge
    376
    a)wie wird die Flanke erfasst?
    Bei eine richtige Einstellung lauft das automatisch ab. Sobald eine Flanke erkannt ist, wird die Zaehlerstand von TIM2 in eine Register kopiert. Der Zaehler lauft weiter, eine IRQ wird ausgelost.
    b)wird die steigende Flanke mit dieser Zeile Erfasst?
    Das ist eine foreinstellung von diesen "Input capture channel". Nur zwei optionen, oder er soll reagieren auf eine Positive Flanke, oder eine negative.
    2)Den Counter: mir ist nicht sicher ob Autoreload laufen soll?
    Normalerweise lauft den timer einfach weiter, bei 0xFFFF fangt er dan wieder an bie 0x0000. Er kan auch eine Interrupt generiert werden, wenn sie das wunschen (wieder eine Foreinstellung).
    3)Den Compare: wie lasse ihn einen Interrupt auslösen, wenn die Zwei Werte verglieschen hat?
    Das ist ihre eigene Verantwortung : in den ISR (Interrupt Sub Routine) konnen sie das programmieren das bei Erfassung von beide Interrupts, eine Variable gesetzt werd. Der CC1 lost nur eine Interrupt aus bei eine steigende Flanke an Pin A0.2, und das jedesmal. Was passiert an CC2 ist abhangig was dort die Foreinstellung ist. CC2 ist normalerweise an eine andere Eingangpin gekuppelt (A0.3 ?). Den CC2 lost dan nur ein Interrupt aus bein eine Flanke an pin A0.3.
    4)Bestimmung die Werte: wie werden die Werte dem Compare zugewiesen?
    CC1 : bein eine Flanke an pin A0.2 wird die Zaeherstand von TIM2 abgelegt in register TIM_GetCapture1(TIM2)
    CC2 : bei eine Flanke an pin A0.3 wird die Zaehlerstand von TIM2 abgelegt in register TIM_GetCapture2(TIM2)
    An der Pin von CH3 passiert nicht, da auch nichts foreingestellt/ programmiert ist. Wie soll diese LED eigentlich reagieren ?

    Hier meine code für eine ICP von CCH3/4 von TIM2 : durch eine Foreinstellung reagiert CC3 uaf eine Fallende flanke von A0.2, CC4 auf eine steigende flanke von A0.2 (remap von pins)
    Code:
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_10;
     GPIO_Init(GPIOA, &GPIO_InitStructure);    //Pin A10=USART Rx,Pin A2 = Input capture TIM2 CH3  
    
    /* ² configuration: Input Capture mode ---------------------
         The external signal is connected to TIM2 CH3 pin (PA.2)  
         The Rising edge is used as active edge,
         The TIM2 CCR2 is used to compute the frequency value 
      ------------------------------------------------------------ */
      TIM_ICInitTypeDef  TIM_ICInitStructure; //alleen voor input capture
     /* Time base configuration */
      TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
      TIM_TimeBaseStructure.TIM_Prescaler = 23; 
      TIM_TimeBaseStructure.TIM_ClockDivision = 0;
      TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
      TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
     /*Input capture channel 3 configuration*/
      TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
      TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; 
      TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//PA.2
      TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;  
      TIM_ICInitStructure.TIM_ICFilter = 0x0;
      TIM_ICInit(TIM2, &TIM_ICInitStructure);
      /*Input capture channel 4 configuration*/
      TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
      TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
      TIM_ICInitStructure.TIM_ICSelection =  TIM_ICSelection_IndirectTI;//Alternate function PA.2
      TIM_ICInit(TIM2, &TIM_ICInitStructure);
      /* TIM enable counter */
      TIM_Cmd(TIM2, ENABLE);
      /* Enable the CC3//CC4 Interrupt Request */
      TIM_ITConfig(TIM2, TIM_IT_CC3, ENABLE);
      TIM_ITConfig(TIM2, TIM_IT_CC4, ENABLE);
      
       /* Setup the microcontroller system. Initialize the Embedded Flash Interface,  
         initialize the PLL and update the SystemFrequency variable. */
      SystemInit();
      /* PCLK1 = HCLK/4 */
      /* TIM2 clock enable */
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
       /* GPIOA, GPIOB and GPIOC clock enable */
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
                             RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
      
      
      void NVIC_Configuration(void)
    {
      NVIC_InitTypeDef NVIC_InitStructure;
      /* Enable the TIM2 global Interrupt */
      NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);
    }

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    07.07.2011
    Beiträge
    35
    Hallo,

    Ich danke dir sehr Herzlich RP6Conrad für deine Hilfe.

    Ich hätte noch paar Fragen und Zwar bezüglich der AFIO.

    Ich möchte den User_Button als Inputcapture einstellen, somit wenn ich das Button drucke wird an Input_capture logisch 1 generiert, und dementsprechend läuft der Capture.

    Der Pin dieses Buttons ist als WKUP eigestellt, jetzt sollte ich ihn so umstellen, dass er als TIM2_CH0 funktioniert.

    Ich habe die folgenden Sätze im RM008 gelesen, die ich nicht ganz gut verstanden habe, und möchte gerne deine Meinung/ Bestätigung einholen:

    1) "For alternate function inputs, the port must be configured in input mode (floating, pull-up or Pull down) and the Input pin must be driven externally"

    Da der User_Button ist nicht externally getrieben sonder innen, wird das nicht akzeptable, dass der User_Butto als Input capture vorgenommen wird, RICHTIG?????

    2) "If you configure a port bit as alternate function Output, this disconnects the Output Register and connects the pin to the out signal of an on_chip peripheral"

    Hier wird nur der Output_Register deaktiviert, aber der Inputregister bleibt doch aktive, Richtig? oder wird sowohl als auch deaktiviert????

    3) gibt Methode, womit ich mit dem Board "STM32 value line Discovery" den Capture/copmare Funktion teste??? ich muss unbedingt ein Eingagnstriger für den Inputcapture, ich habe Zuhause keine Möglichkeit ein Signal einzuspeisen. Deswegen bin ich darauf gekommen dass der User_button selbst als Eingangssignal einzustellen.

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    09.04.2008
    Beiträge
    376
    1) "For alternate function inputs, the port must be configured in input mode (floating, pull-up or Pull down) and the Input pin must be driven externally"
    Kan gemacht werden mit der User Button : Diese Button ist verbunden an Pin A0 mit eine Pull down. Ohne betatigung hat der eingang damit 0V, oder logisch 0, betaetigt hat her 3.3V, oder logisch ein. Das wird gemeint mit "Externaly driven". Er muss naturlich als Eingang configuriert werden, und den TIM2 CH1 muss activiert werden.
    2) "If you configure a port bit as alternate function Output, this disconnects the Output Register and connects the pin to the out signal of an on_chip peripheral"
    Eine pin configuriert als "Alternate Function Output" wird dan nur gesteurt durch die "On chip peripheral" wie PWM, DAC, USART, I2C.... Sie konnen dan nicht mehr die Ausgangen beinflussen direct aus ihre Program. Nach meine Meinung gibt noch immer die Moglichkeit um die Pins ab zu fragen als Eingang.
    3) gibt Methode, womit ich mit dem Board "STM32 value line Discovery" den Capture/copmare Funktion teste???
    Muss gehen mit der User button und TIM2 CH1 (pin A0). Zum debuggen verwende ich gerne die USART und ein Terminal program auf PC. Damit kan ich in jeden Punkt von mein Program eine variable ausgeben nach PC. Naturlich brauchen sie dan noch ein level converter (MAX232) und eine seriele port auf den PC. Alternativ konnen sie ein Debugger verwenden. Bei den IAR compiler ist das standard moglich. Damit kan auch jeden variable/register ausgelesen werden, obwohl dan der Controller gestoppt werd. Sehr hilfreich fur mich ware auch al die Forbild-Programme von STM32 Std lib, mit eingebunden bei den IAR compiler. Diese sind eigenlich fur ein andere Board gemacht (Eval board STM32..), aber perfect zu verwenden mit kleine Anpassungen. Auch die LEDS an pin C8/C9 sind zu verwenden ! Das standard Program von das discovery board selbst ist nicht so hilfreich : unheimlich fiele "Defines", machen das schwierig zu verstehen.

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    07.07.2011
    Beiträge
    35
    Hallo;

    Ich werde bald verrückt

    Ich verstehe nicht wo steckt meinen Fehler.
    fast(90%) Jede Zeile verstehe ich, und bin ich sogar sicher dass es so richtig aber 1% falsch reicht um den Programm wahnsinnig zu machen.

    Ich brauche jede kleine Hinweise, Tipp, Orientierung bitte....!


    /* Includes */

    #include <stddef.h>
    #include "stm32f10x.h"

    /* ---------------------------Private typedef -------------------------------*/
    TIM_TimeBaseInitTypeDef TIM2_Configuration;
    NVIC_InitTypeDef NVIC_InitStructure;
    TIM_OCInitTypeDef Output_Compare;
    TIM_ICInitTypeDef Input_Capture;
    GPIO_InitTypeDef GPIO_Inity;

    /*Variable*/

    uint32_t Interrupt_Counter = 0;

    /*# ************************************************** *****************************/*/

    void RCC_Configuration(void)
    {
    /* TIM2clock= SystemCoreColock, enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    /* GPIOA clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    /* ALTERNATE FUNCTION ENABLE*/
    RCC_APB1PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    /* GPIOC clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    }

    /************************************************** *****************************/
    void GPIO_Setup ()
    {
    /* LEDs pin (PC.08 and 09) configuration */
    GPIO_Inity.GPIO_Pin =GPIO_Pin_8 | GPIO_Pin_9;
    GPIO_Inity.GPIO_Mode =GPIO_Mode_Out_PP;
    GPIO_Inity.GPIO_Speed =GPIO_Speed_50MHz;

    /* TIM2 PA.0 configuration*/
    GPIO_Inity.GPIO_Mode =GPIO_Mode_AF_PP;// soll ich PULL-Down oder Pull up werwenden wenn der
    // Eingang als Pull-Down Konfiguriert?
    // Der AF weil bei dieser Pin wir der Alternate Function verwendet
    GPIO_Inity.GPIO_Speed =GPIO_Speed_50MHz;
    GPIO_Inity.GPIO_Pin =GPIO_Pin_0;

    GPIO_Init(GPIOA, &GPIO_Inity);
    GPIO_Init(GPIOC, &GPIO_Inity);

    }

    /************************************************** ******************************/

    void TIM2_SETUP ()
    {

    /*----Time_Base_Counter-----*/

    TIM2_Configuration.TIM_CounterMode= TIM_CounterMode_Up;
    TIM2_Configuration.TIM_ClockDivision= 0;
    TIM2_Configuration.TIM_Period=65535;
    TIM2_Configuration.TIM_Prescaler=1;
    TIM_TimeBaseInit(TIM2,&TIM2_Configuration);

    /*----Input_Capture Mode CH1----*/
    Input_Capture.TIM_ICSelection = TIM_ICSelection_IndirectTI;// hier verstehe ich der Unterschied
    // zwischen Direct und Indirekt nicht
    // wirklich, aber ich verwende Direct weil ich
    // kein remaping durchführe
    Input_Capture.TIM_ICPolarity= TIM_ICPolarity_Rising;
    Input_Capture.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    Input_Capture.TIM_Channel= TIM_Channel_1;
    Input_Capture.TIM_ICFilter = 0;

    TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1);// dieze Zeile verstehe ich überhaupt nicht
    TIM_ICInit(TIM2, &Input_Capture);

    TIM_Cmd(TIM2, ENABLE);

    /*----Enable the Capture Compare Interrupt Request-----*/
    TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);

    }

    /************************************************** ******************************/
    void NVIC_SETUP ()
    {
    /* Enable the TIM2 global Interrupt */

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriori ty=0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
    NVIC_InitStructure.NVIC_IRQChannel= TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    }

    /************************************************** ******************************/

    void delayLoop()
    {
    volatile uint32_t delayCount = 1000000;
    while (delayCount > 0)
    {
    delayCount--;
    }
    }


    /*+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++*/

    int main (void)
    {
    RCC_Configuration();
    GPIO_Setup();
    TIM2_SETUP();

    while (1)
    {

    if(INT_Counter ==1)
    {
    GPIOC->BSRR = GPIO_Pin_8; // LED On
    delayLoop();

    GPIOC->BRR = GPIO_Pin_8; // LED Off
    delayLoop();

    GPIOC->BSRR = GPIO_Pin_8; // LED On
    delayLoop();

    GPIOC->BRR = GPIO_Pin_8; // LED Off
    delayLoop();
    GPIOC->BSRR = GPIO_Pin_9; // LED On
    delayLoop();

    GPIOC->BRR = GPIO_Pin_9; // LED Off
    delayLoop();

    }

    }
    return 0;
    }

    void TIM2_IRQHandler (void)
    {
    // Interrupt Flag muß per Software gelöscht werden

    TIM_ClearFlag(TIM2, TIM_FLAG_Update);

    INT_Counter++;
    }


    Ich danke Ihnen.

  8. #8
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    09.04.2008
    Beiträge
    376
    /*Variable*/

    uint32_t Interrupt_Counter = 0;
    Diese soll als "volatile" declariert werden, da er in einen Interrupt gaendert wird.
    /* TIM2 PA.0 configuration*/
    GPIO_Inity.GPIO_Mode =GPIO_Mode_AF_PP;// soll ich PULL-Down oder Pull up werwenden wenn der
    // Eingang als Pull-Down Konfiguriert?
    Soll ich als Eingang declarieren, ein AF_PP ist eher ein Ausgang für PWM und solche zu steuern. Bei mir functioniert die ICP beim Eingang declariert als GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    Input_Capture.TIM_ICSelection = TIM_ICSelection_IndirectTI;// hier verstehe ich der Unterschied
    // zwischen Direct und Indirekt nicht
    // wirklich, aber ich verwende Direct weil ich
    // kein remaping durchführe
    Ein Timer channel ist normalerweise fast an einen Pin zugewiesen. TIM2 CH1 ist standaard verbunden an pin A0. Da gibt noch eine moglichkeit diese TIM2 CH1 auf einen andere pin zu acivieren : pin A15. Da ist dan eine "REMAP", wird activiert ueber "Indirect"
    TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1);// dieze Zeile verstehe ich überhaupt nicht
    Verwende ich nicht beim Input cature. Wird genutzt beim "external clock" configuration. Diese info steht in die TIM library. :
    /**
    * @brief Configures the TIMx Internal Trigger as External Clock
    * @param TIMx: where x can be 1, 2, 3, 4, 5 or 8 to select the TIM peripheral.
    * @param TIM_ITRSource: Trigger source.
    * This parameter can be one of the following values:
    * @param TIM_TS_ITR0: Internal Trigger 0
    * @param TIM_TS_ITR1: Internal Trigger 1
    * @param TIM_TS_ITR2: Internal Trigger 2
    * @param TIM_TS_ITR3: Internal Trigger 3
    * @retval None

    Welche compiler verwenden sie ?

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    07.07.2011
    Beiträge
    35
    Hallo,

    Danke für die schnelle Antwort.
    ich habe Ihren Hinweise befolgen, was Sie oben erwähnt haben, aber leider immer erfolglos.
    Langsam langsam verzweifle ich an das Bord. es muss irgendwie an das Bord liegen. weil das Code soll fehlerlos laufen oder?

    Ich verwende den Atolic/TrueSTUDIO STM32 Lite 2.1.0 (STMicroelectronics ST-Link_V2_USBdriver).

    Danke.


    /* Includes */

    #include <stddef.h>
    #include "stm32f10x.h"

    /* ---------------------------Private typedef -------------------------------*/
    TIM_TimeBaseInitTypeDef TIM2_Configuration;
    NVIC_InitTypeDef NVIC_InitStructure;
    //TIM_OCInitTypeDef Output_Compare;
    TIM_ICInitTypeDef Input_Capture;
    GPIO_InitTypeDef GPIO_Inity;

    /*---------------------------Global Variable---------------------------------*/
    volatile uint32_t INT_Counter = 0;



    /************************************************** *****************************
    # * Function Name : RCC_cONFIGURATION
    # * Description : .
    # * Input : None
    # * Output : None
    # * Return : None
    # ************************************************** *****************************/

    void RCC_Configuration(void)
    {
    /* TIM2clock= SystemCoreColock, enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    /* GPIOA clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    /* ALTERNATE FUNCTION ENABLE*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    /* GPIOC clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    }

    /************************************************** *****************************
    # * Function Name : GPIO_SETUP
    # * Description : .
    # * Input : None
    # * Output : None
    # * Return : None
    # ************************************************** *****************************/

    void GPIO_Setup ()
    {
    /* LEDs pin (PC.08 and 09) configuration */
    GPIO_Inity.GPIO_Pin =GPIO_Pin_8 | GPIO_Pin_9;
    GPIO_Inity.GPIO_Mode =GPIO_Mode_Out_PP;
    GPIO_Inity.GPIO_Speed =GPIO_Speed_50MHz;

    /* TIM2 PA.0 configuration*/
    GPIO_Inity.GPIO_Mode =GPIO_Mode_IN_FLOATING;// soll ich PULL-Down oder Pull up werwenden wenn der
    //Eingang als Pull-Down Konfiguriert?
    //Der AF weil bei dieser Pin wir der Alternate Function verwendet
    GPIO_Inity.GPIO_Speed =GPIO_Speed_50MHz;
    GPIO_Inity.GPIO_Pin =GPIO_Pin_0;

    GPIO_Init(GPIOA, &GPIO_Inity);
    GPIO_Init(GPIOC, &GPIO_Inity);

    }

    /************************************************** *****************************
    # * Function Name : TIM2_SETUP
    # * Description : Timer2 as Output/Compare
    # * Input : None
    # * Output : None
    # * Return : None
    # ************************************************** *****************************/

    void TIM2_SETUP ()
    {

    /*----Time_Base_Counter-----*/

    TIM2_Configuration.TIM_CounterMode= TIM_CounterMode_Up;
    TIM2_Configuration.TIM_ClockDivision= 0;
    TIM2_Configuration.TIM_Period=65535;
    TIM2_Configuration.TIM_Prescaler=1;
    TIM_TimeBaseInit(TIM2,&TIM2_Configuration);

    /*----Input_Capture Mode CH1----*/
    Input_Capture.TIM_ICSelection = TIM_ICSelection_DirectTI;// hier verstehe ich der Unterschied
    // zwischen Direct und Indirekt nicht
    //wirklich, aber ich verwende Direct weil ich
    // kein remaping durchführe
    Input_Capture.TIM_ICPolarity= TIM_ICPolarity_Rising;
    Input_Capture.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    Input_Capture.TIM_Channel= TIM_Channel_1;
    Input_Capture.TIM_ICFilter = 0;

    TIM_ICInit(TIM2, &Input_Capture);
    TIM_Cmd(TIM2, ENABLE);

    /*----Enable the Capture Compare Interrupt Request-----*/
    TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);

    }

    /************************************************** *****************************
    # * Function Name : Configure the nested vectored interrupt controller.
    # * Description : .
    # * Input : None
    # * Output : None
    # * Return : None
    # ************************************************** *****************************/
    void NVIC_SETUP ()
    {
    /* Enable the TIM2 global Interrupt */

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriori ty=0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
    NVIC_InitStructure.NVIC_IRQChannel= TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    }

    /************************************************** *****************************
    # * Function Name : delayloop
    # * Description : .
    # * Input : None
    # * Output : None
    # * Return : None
    # ************************************************** *****************************/

    void delayLoop()
    {
    volatile uint32_t delayCount = 1000000;
    while (delayCount > 0)
    {
    delayCount--;
    }
    }


    /*+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++*/

    int main (void)
    {
    RCC_Configuration();
    GPIO_Setup();
    TIM2_SETUP();
    NVIC_SETUP();



    while (1)
    {

    if(INT_Counter ==1)
    {
    GPIOC->BSRR = GPIO_Pin_8; // LED On
    delayLoop();

    GPIOC->BRR = GPIO_Pin_8; // LED Off
    delayLoop();

    GPIOC->BSRR = GPIO_Pin_8; // LED On
    delayLoop();

    GPIOC->BRR = GPIO_Pin_8; // LED Off
    delayLoop();
    GPIOC->BSRR = GPIO_Pin_9; // LED On
    delayLoop();

    GPIOC->BRR = GPIO_Pin_9; // LED Off
    delayLoop();


    }

    }
    return 0;
    }

    void TIM2_IRQHandler (void)
    {
    // Interrupt Flag muß per Software gelöscht werden

    TIM_ClearFlag(TIM2, TIM_FLAG_Update);

    INT_Counter++;
    }

  10. #10
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    09.04.2008
    Beiträge
    376
    Ich habe mal ihre code mit den IAR compiler in meines Discovery board versucht. Das scheint zu functionieren. Jeden mal das ich den user button drucke, erhoht die variable "INT_count", und die LEDS fangen an zu blinken Ich habe nur kleine aenderungen gemacht wegend andere compiler. Moglich sind andere systemfiles auch noch wichtig (Clock Init).
    Ich kopîere das nochmal hierein.
    Code:
    /* Includes */
    #include <stddef.h>
    #include "stm32f10x.h"
    /* ---------------------------Private typedef -------------------------------*/
    TIM_TimeBaseInitTypeDef TIM2_Configuration;
    NVIC_InitTypeDef NVIC_InitStructure;
    //TIM_OCInitTypeDef Output_Compare;
    TIM_ICInitTypeDef Input_Capture;
    GPIO_InitTypeDef GPIO_Inity;
    /*---------------------------Global Variable---------------------------------*/
    volatile uint32_t INT_Counter = 0;
    volatile uint32_t delayCount;
    
    /************************************************** *****************************
    # * Function Name : RCC_cONFIGURATION
    # * Description : .
    # * Input : None
    # * Output : None
    # * Return : None
    # ************************************************** *****************************/
    void RCC_Configuration(void)
    {
    /* TIM2clock= SystemCoreColock, enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    /* GPIOA clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    /* ALTERNATE FUNCTION ENABLE*/
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    /* GPIOC clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    }
    /************************************************** *****************************
    # * Function Name : GPIO_SETUP
    # * Description : .
    # * Input : None
    # * Output : None
    # * Return : None
    # ************************************************** *****************************/
    void GPIO_Setup ()
    {
    /* LEDs pin (PC.08 and 09) configuration */
    GPIO_Inity.GPIO_Pin =GPIO_Pin_8 | GPIO_Pin_9;
    GPIO_Inity.GPIO_Mode =GPIO_Mode_Out_PP;
    GPIO_Inity.GPIO_Speed =GPIO_Speed_50MHz;
    /* TIM2 PA.0 configuration*/
    GPIO_Inity.GPIO_Mode =GPIO_Mode_IN_FLOATING;// soll ich PULL-Down oder Pull up werwenden wenn der
    //Eingang als Pull-Down Konfiguriert?
    //Der AF weil bei dieser Pin wir der Alternate Function verwendet
    GPIO_Inity.GPIO_Speed =GPIO_Speed_50MHz;
    GPIO_Inity.GPIO_Pin =GPIO_Pin_0;
    GPIO_Init(GPIOA, &GPIO_Inity);
    GPIO_Init(GPIOC, &GPIO_Inity);
    }
    /************************************************** *****************************
    # * Function Name : TIM2_SETUP
    # * Description : Timer2 as Output/Compare
    # * Input : None
    # * Output : None
    # * Return : None
    # ************************************************** *****************************/
    void TIM2_SETUP ()
    {
    /*----Time_Base_Counter-----*/
    TIM2_Configuration.TIM_CounterMode= TIM_CounterMode_Up;
    TIM2_Configuration.TIM_ClockDivision= 0;
    TIM2_Configuration.TIM_Period=65535;
    TIM2_Configuration.TIM_Prescaler=1;
    TIM_TimeBaseInit(TIM2,&TIM2_Configuration);
    /*----Input_Capture Mode CH1----*/
    Input_Capture.TIM_ICSelection = TIM_ICSelection_DirectTI;// hier verstehe ich der Unterschied
    // zwischen Direct und Indirekt nicht
    //wirklich, aber ich verwende Direct weil ich
    // kein remaping durchführe
    Input_Capture.TIM_ICPolarity= TIM_ICPolarity_Rising;
    Input_Capture.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    Input_Capture.TIM_Channel= TIM_Channel_1;
    Input_Capture.TIM_ICFilter = 0;
    TIM_ICInit(TIM2, &Input_Capture);
    TIM_Cmd(TIM2, ENABLE);
    /*----Enable the Capture Compare Interrupt Request-----*/
    TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
    }
    /************************************************** *****************************
    # * Function Name : Configure the nested vectored interrupt controller.
    # * Description : .
    # * Input : None
    # * Output : None
    # * Return : None
    # ************************************************** *****************************/
    void NVIC_SETUP ()
    {
    /* Enable the TIM2 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
    NVIC_InitStructure.NVIC_IRQChannel= TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    }
    /************************************************** *****************************
    # * Function Name : delayloop
    # * Description : .
    # * Input : None
    # * Output : None
    # * Return : None
    # ************************************************** *****************************/
    void delayLoop()
    {
    delayCount = 1000000;
    while (delayCount > 0)
    {
    delayCount--;
    }
    }
    
    /*+++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++*/
    int main (void)
    {
    RCC_Configuration();
    GPIO_Setup();
    TIM2_SETUP();
    NVIC_SETUP();
     
    while (1)
    {
    if(INT_Counter >1)
    {
    GPIOC->BSRR = GPIO_Pin_8; // LED On
    delayLoop();
    GPIOC->BRR = GPIO_Pin_8; // LED Off
    delayLoop();
    GPIOC->BSRR = GPIO_Pin_8; // LED On
    delayLoop();
    GPIOC->BRR = GPIO_Pin_8; // LED Off
    delayLoop();
    GPIOC->BSRR = GPIO_Pin_9; // LED On
    delayLoop();
    GPIOC->BRR = GPIO_Pin_9; // LED Off
    delayLoop();
    
    }
    }
    return 0;
    }
    //steht bei mir in eine ander file : STM32F10x_it.c
    void TIM2_IRQHandler (void)
    {
    // Interrupt Flag muß per Software gelöscht werden
    TIM_ClearFlag(TIM2, TIM_FLAG_CC1);
    //TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); 
    INT_Counter++;
    }
    Ha der Atollic compiler auchj eine debugger ?
    Fiel erfolg !!

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. ISR per Output Compare funktioniert nicht wie gewünscht
    Von Sebastian132 im Forum C - Programmierung (GCC u.a.)
    Antworten: 7
    Letzter Beitrag: 24.07.2006, 12:22
  2. Fragen zu Compare -> Timer
    Von Rage_Empire im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 21.11.2005, 19:35
  3. Problem mit Timer1 und Compare...
    Von Murus im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 16
    Letzter Beitrag: 12.11.2005, 17:34
  4. Compare Register
    Von chouifi im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 31.10.2005, 14:47
  5. Wie Compare Register Werte sicher ändern?
    Von Werner_Just im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 0
    Letzter Beitrag: 22.04.2005, 15:29

Berechtigungen

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