2017-01-02 09:14 AM
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
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 requestTIM_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); }}
2017-01-02 10:38 AM
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.
2017-01-02 12:43 PM
Hello Khouloud,
i tryied modifing
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
And the same behaviour, there is no trigger on the CC1 IRQ
2017-01-02 01:19 PM
.CPP or C++ compilation? Try extern 'C' void TIM2_IRQHandler(void){ .. }
Have you checked the linkage via the Vector Table?
2017-01-02 04:20 PM
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
2017-01-02 04:42 PM
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)
2017-01-03 04:58 AM
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....
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 analyzerGPIO_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 requestTIM_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 }2017-01-13 09:58 AM
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.
2017-01-22 02:24 PM
2017-01-25 01:31 PM
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