Skip to main content
Bogdan
Senior
January 2, 2017
Question

Hall sensors not triggering IRQ from TIMER2

  • January 2, 2017
  • 7 replies
  • 1475 views
Posted on January 02, 2017 at 18:14

Hello,

i am working on a bldc motor project for school, and for start to understand whats happening inside the IRQ handler, i have configured timer2  on ch1,2,3 with 3 emulated hardware signals, imitating the CW of a bldc motors

The hall emulated signals are coming from another development board. The signals are bellow

0690X00000605yKQAQ.png

These signals ( H1,H2,H3) are feed into a STM32F407 device, on PA0, PA1 and PA2   which are Ch1,2,3 of the TIMER2 

i have prepared only the initialization of the timer2 to see if the hall signals trigger the CC1 event in the irq handler, but its not triggering.

I've put a small toggle on a PC1 pin just to see when its triggering inside the TIM2_IRQhandler,

But there is no triggering,

At this point Timer1 is not initialized, i just want to see how it behaives on the hall signals.

I am missing something?  Of does the Timer2 takes some kind of feedback from TIM1 in order to trigger CC1 event?

void timer2_setup(void){

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 |GPIO_Pin_2;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2);

//**** PC1 is used for toggle in IRQ handlers to see with logic analyzer

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;

GPIO_Init(GPIOC, &GPIO_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

TIM_TimeBaseStructure.TIM_Prescaler = 126;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseStructure.TIM_Period = 65530;

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

TIM_SelectHallSensor(TIM2, ENABLE);

TIM_SelectInputTrigger(TIM2, TIM_TS_TI1F_ED);

TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

TIM_ICInitStructure.TIM_Channel = TIM_Channel_1 ;

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;

TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;// listen to T1, the HallSensorEvent

TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;// Div:1, every edge

TIM_ICInitStructure.TIM_ICFilter = 0;

TIM_ICInit(TIM2, &TIM_ICInitStructure);

// Enable CC1 interrupt request

TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);

TIM_Cmd(TIM2, ENABLE);

}

void TIM2_IRQHandler(void){

if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)

{

GPIO_ToggleBits(GPIOC,GPIO_Pin_1); // Toggle the pin for logic analyzer

TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);

}

}

    This topic has been closed for replies.

    7 replies

    Khouloud GARSI
    Technical Moderator
    January 2, 2017
    Posted on January 02, 2017 at 19:38

    Hi

    Anton.Bogdan

    ,

    Try to modify your input polarity from both edges to rising edge:

    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

    I'm waiting for your feedback.

    If this solves your issue, please click on correct

    :)

    .

    Best regards,

    Khouloud.

    Bogdan
    BogdanAuthor
    Senior
    January 2, 2017
    Posted on January 02, 2017 at 21:43

    Hello Khouloud,

    i tryied modifing  

    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

    And the same behaviour, there is no trigger on the CC1 IRQ

    Tesla DeLorean
    Guru
    January 2, 2017
    Posted on January 02, 2017 at 22:19

    .CPP or C++ compilation? Try extern 'C' void TIM2_IRQHandler(void){ .. }

    Have you checked the linkage via the Vector Table?

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Bogdan
    BogdanAuthor
    Senior
    January 3, 2017
    Posted on January 03, 2017 at 00:20

    Hello Clive,

    after the code from above see it wasnt working, i decided to modify the code just for simple update event.

    The code is writen in C only, using IAR enviroment.

    After modifing the IRQ handler for the TIM_IT_UPDATE it still wasnt working,    tryied with a demo project provided by ST in IAR enviroment, and that was working. But still i didnt understand why...

    Normaly for working with interupts i know the following components are needed to the enviroment   :

    - misc.c/h

    - stm32f4xx_it.c/h

    - the vector file ( in my case startup_stm32f40_41xxx.s for IAR Ewarm)

    If i am mistaken, please corect me.

    Now after almost 2hours of coffe and code debug, i noticed a stupid thing

    my main routine is this normaly in this structure

    int main(void) {

    RCC_ClocksTypeDef clocks;

    RCC_GetClocksFreq(&clocks);

    NVIC_InitTypeDef NVIC_InitStructure;

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 ;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;

    GPIO_Init(GPIOD, &GPIO_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    TIM_TimeBaseStructure.TIM_Prescaler = 500;

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseStructure.TIM_Period = 65530; // tick arround  2.5 hertz for the eye....

    TIM_TimeBaseStructure.TIM_ClockDivision = 0;

    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    TIM_Cmd(TIM2, ENABLE);

    while(1) { } // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! whitout this line, the IRQ handler is not working !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    }

    void TIM2_IRQHandler(void){

     

     

    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)

     

    {

     

    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

     

    // GPIO_ToggleBits(GPIOC,GPIO_Pin_1);

     

    GPIO_ToggleBits(GPIOD,GPIO_Pin_14);

     

     

    }

     

    }

    If i  put a while(1){}  in my  main function,  the irq works,   if not .... its not working.... Now i am not very experienced in C language but i found this very strange....  I even try ending the int main(void) function with a return 0;   and didn not work... It seems its working only if i have a while(1){} inside my main program.

    I will return to my main motor code and see if this was the issue.

    I will keep updated 

    Thanks

    Tesla DeLorean
    Guru
    January 3, 2017
    Posted on January 03, 2017 at 00:42

    Returning from main() drops into nowhere, unless specially handled by the startup code I'd expect the system to crash/fail. See also exit() or abort().

    Here in Keil the BX __main provides no expectation of ever returning

    ...
    ; Reset handler
    Reset_Handler PROC
     EXPORT Reset_Handler [WEAK]
     IMPORT SystemInit
     IMPORT __main
     LDR R0, =SystemInit
     BLX R0
     LDR R0, =__main
     BX R0
     ENDP
    ; Dummy Exception Handlers (infinite loops which can be modified)
    NMI_Handler PROC
     EXPORT NMI_Handler [WEAK]
     B .
     ENDP
    ...�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    In an optimistic interpretation it might come back to just before the call to __main (line 10)

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Bogdan
    BogdanAuthor
    Senior
    January 3, 2017
    Posted on January 03, 2017 at 13:58

    Ok, now that my IRQ handler is working,  i started the following code, i modifyied my timebase to overflow at arround 500 ms

    My Hall signals each are 2.9 ms at 50% dutycycle.

    Basicaly i have a hall event at every 1ms

    The problem is that the CC1 interrupt should occour at every hall rising edge, is this correct?

    But from the logic analyzer i see the CC1 is fired haoticaly,  and i wonder why....

    0690X00000605qcQAA.png

    Here is my code 

    int main(void){

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 |GPIO_Pin_2;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2);

    //**** PC1 is used for toggle in IRQ handlers to see with logic analyzer

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 |GPIO_Pin_3 ;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;

    GPIO_Init(GPIOC, &GPIO_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 7;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

    TIM_TimeBaseStructure.TIM_Prescaler = 647;

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseStructure.TIM_Period = 65000;

    TIM_TimeBaseStructure.TIM_ClockDivision = 0;

    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_SelectHallSensor(TIM2, ENABLE);

    TIM_SelectInputTrigger(TIM2, TIM_TS_TI1F_ED);

    TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

    TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);

    TIM_ICInitStructure.TIM_Channel = TIM_Channel_1 ;

    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;// listen to T1, the HallSensorEvent

    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

    TIM_ICInitStructure.TIM_ICFilter = 0x0F;

    TIM_ICInit(TIM2, &TIM_ICInitStructure);

    // Enable CC1 interrupt request

    TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);

    TIM_Cmd(TIM2, ENABLE);

    while(1){}

    }

    void TIM2_IRQHandler(void){

    if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)

    {

    TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);

    GPIOC->BSRRH = GPIO_Pin_1; //reset

    GPIOC->BSRRL = GPIO_Pin_1; //set

    GPIOC->BSRRH = GPIO_Pin_1; //reset

    }

    Khouloud GARSI
    Technical Moderator
    January 13, 2017
    Posted on January 13, 2017 at 18:58

    Hi

    Anton.Bogdan

    ,

    Pleasetry with a basic configuration without using the filter :

    TIM_ICInitStructure.TIM_ICFilter = 0;

    And send me a new screen shot of the signals seen on the analyser.

    Khouloud.

    Bogdan
    BogdanAuthor
    Senior
    January 22, 2017
    Posted on January 22, 2017 at 23:24

    The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6ZI&d=%2Fa%2F0X0000000bqr%2FUQfLNNJ8Ffw3Q5x1Tt8u_ciDasSFDqE5bMSNJ.LvI50&asPdf=false
    Bogdan
    BogdanAuthor
    Senior
    January 25, 2017
    Posted on January 25, 2017 at 22:31

    In the end i solved'it,  it was because of the GPIO PullUP enabled for  the 6pwm outputs,  after configured with NOPULL everything is as expected.

    Thanks guys 

    Khouloud GARSI
    Technical Moderator
    January 26, 2017
    Posted on January 26, 2017 at 09:46

    Hi

    Anton.Bogdan

    ,

    Thanks for sharing the solution.This will be helpful for other users.

    Khouloud