Using ch2 and ch4 as input capture
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-03-18 5:44 AM
Hello,
I'd like to use channel 2 and channel 4 of TIM2 as input capture. Channel 2 work fine, but channel seems returning the timer counter. Here's the code:
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE);
/*Trigger pin configuration*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_1);
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_Period = 60000;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM16, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OC1Init(TIM16, &TIM_OCInitStructure);
TIM_CtrlPWMOutputs(TIM16, ENABLE);
TIM_Cmd(TIM16, ENABLE);
TIM_SetCompare1(TIM16, 10);
/*Echo Pin configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
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);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_2);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11,GPIO_AF_1);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x0;
TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);
TIM_Cmd(TIM2, ENABLE);
#clive1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-03-22 7:06 AM
Hi Clive, I am able to determine the pulse and period using the coding below.
May I ask how can I calculate distance with the pulse obtained and why do I have to read the pin state?void TIM2_IRQHandler(){
B = TIM_GetCapture2(TIM2);
delta = B - A;
A = B;
sprintf(str,''%d
'' ,delta);
printUART2(str);
TIM2 ->SR = 0;
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-03-22 7:54 AM
Ok,
If you are timestamping the Rising Edge, then you're going to be able to measure the period, not the period+duty. If you are timestamping BothEdges, then you're going to need to make THREE measurements (A, B ,C). One pair of measurements in a 50 Hz (20 ms) servo example is going (C-A) is going to be ~20 ms and the other (B-A) is going to be 1~2 ms. You can read the pin state to confirm the phase of the signal. You could do TWO measurements and read the pin state to understand where high pulse (1-2 ms, mark) ended, or you can do a test that it's between 1-2, or less than 3 ms, because presumably the space is going to be 17 ms or more. Think about the points you're measuring, and the nature of the signals you're looking at.Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-03-22 9:50 AM
Hi, by repeating the method above, I'm able to use ultrasonic sensor 1 by 1, but when 2 ultrasonic sensors are used simultaneously, only 1 giving values. I would like to ask is there any thing I can do to solve it?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-03-22 9:58 AM
You're interrupt handler is going to have to do a better job of selectively handling and clearing the interrupts on specific CCx sources, and how to hold state for each of the 2-4 channels you want to measure.
Probably also want to remove the uart/printf stuff from there too, as it's going to bog everything down. Compute results in the interrupt, print them in a foreground task/loop.Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-03-22 11:08 AM
Sorry to ask that, how to know that the channel flag is clear. I just know how to clear the timer flag. Besides, I have no idea on what u mean by how to hold state for each of the channel.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-03-22 6:37 PM
Hold the state information (the stuff you need to remember from call to call) in an arrayed structure, and not dozens of individually defined/named global variables.
void TIM2_IRQHandler()
{
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) == SET)
{
/* Clear TIM2 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
// .. TIM_GetCapture1(TIM2);
}
if (TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET)
{
/* Clear TIM2 Capture compare interrupt pending bit */
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
// .. TIM_GetCapture2(TIM2);
}
// ..
}
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-03-26 10:00 AM
Hi, I encountered a problem that a very large and incorrect value pop out in the middle of the data I obtained even after applying your suggestion. How can I solve this problem? Thanks in advance.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-03-26 10:39 AM
Sanity check that the measurements for the two consecutive rising edges are ~20ms apart?
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-03-26 11:50 AM
I tried to read the pin state using GPIOx->IDR, in order to know whether the consecutive rising edges is 20 ms, but it showed the values of 65535, 65487 and 65519. Is this results that I should obtain? If no, may you show me the proper method to check whether the rising edge is 20 ms apart?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2015-03-26 12:03 PM
You're time stamping the edges in the timer, review the measurements, they are in ticks of the counter timebase.
Measurements, A, B, CC-A should be approximately 20000 cycles at 1 MHz (1us), right? B-A some thing in the ~1000-2000 range. If the measurements look wrong, don't use them.For a 16-bit count, use 16-bit unsigned int's to do the math, it will wrap automatically in the desired fashion.Up vote any posts that you find helpful, it shows what's working..
