2010-03-17 12:23 AM
Hello,
I'm attempting to design a stabilization system for a hobby level RC-UAV, using stm8s Discovery dev board. Right Now I'm just trying to get the mcu to: 1)Capture the input signals on-time and off-time, and store them in respective variables. 2)Output a PWM signal that identical to the input, as well as adjust the on-time and off-time to match. So far I haven't had any success, if anybody has any suggestions or advice it would be much appreciated. The code that I have gotten the closest to working is the TIM1 or 2 Input capture example included with the firmware. Here's a copy of the portion I use. /** ****************************************************************************** * @file TIM2_Input_Capture\main.c * @brief This file contains the main function for TIM2 Input Capture example. * @author STMicroelectronics - MCD Application Team * @version V1.1.1 * @date 06/05/2009 ****************************************************************************** * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * * <h2><center>© COPYRIGHT 2009 STMicroelectronics</center></h2> * @image html logo.bmp ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include ''stm8s.h'' /** * @addtogroup TIM2_Input_Capture * @{ */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define TIM2ClockFreq ((u32)2000000) /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ u32 LSIClockFreq = 0; u16 ICValue1 =0, ICValue2 =0; void main(void) { /* Capture only every 8 events!!! */ /* Enable capture of TI1 */ TIM2_ICInit(TIM2_CHANNEL_1, TIM2_ICPOLARITY_FALLING, TIM2_ICSELECTION_DIRECTTI, TIM2_ICPSC_DIV8, 0x00); /* Enable CC1 interrupt */ TIM2_ITConfig(TIM2_IT_CC1, ENABLE); /* Enable TIM2 */ TIM2_Cmd(ENABLE); /* Clear CC1 Flag*/ TIM2_ClearFlag(TIM2_FLAG_CC1); /* Connect LSI to COO pin*/ GPIO_Init(GPIOE, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST); CLK_CCOConfig(CLK_OUTPUT_LSI); CLK_CCOCmd(ENABLE); /* wait a capture on CC1 */ while((TIM2->SR1 & TIM2_FLAG_CC1) != TIM2_FLAG_CC1); /* Get CCR1 value*/ ICValue1 = TIM2_GetCapture1(); TIM2_ClearFlag(TIM2_FLAG_CC1); /* wait a capture on cc1 */ while((TIM2->SR1 & TIM2_FLAG_CC1) != TIM2_FLAG_CC1); /* Get CCR1 value*/ ICValue2 = TIM2_GetCapture1(); TIM2_ClearFlag(TIM2_FLAG_CC1); /* Compute LSI clock frequency */ LSIClockFreq = (8 * TIM2ClockFreq) / (ICValue2 - ICValue1); /* Insert a break point here */ while (1); }2010-03-17 12:30 AM
Hi Mken,
I remember that I have used this example and it works fine ! mit besten grüssen, mcu fan2010-03-17 08:49 AM
2010-03-18 02:43 AM
Hi Mken C- learner,
I don't understand your interpretation of the example. My own understanding of the example is: Timer 2 channel 1 is configured to capture external signal on falling edge, the signal in input is divided by 8. The timer 2 (TIM2) counter starts counting when executing this function: TIM2_Cmd(ENABLE); when a falling edge is detected the CC1 flag is set and CCR1 register is stored in ICValue1 when executing ICValue1 = TIM2_GetCapture1(); when the second falling edge is detected the CC1 is set again and CCR1 register is stored in ICValue2 when executing ICValue2 = TIM2_GetCapture1(); PS: when the CC1 is set the counter value is automatically saved in the CCR1 register I hope this helps. Mit besten grüssen, MCU fan2010-03-18 11:14 AM
My apologys I hadn't looked through the rm0016 document well enough to understand how the CC1 Flag worked, what I'm trying to say is that when CC1's Flag is active and it stores the value in ICValue1 it doesn't reset the counter on the next Flag activation. Basicly if CC1 flag is activated at say 15000 counts, that value is stored in ICValue1, but the counter is reset after the capture so that when the CC1 flag is activated a second time at 45000 counts from start, then that value gets placed into ICValue2, and the only time the counter gets reset is when it overflows.
What I'm wanting to do is start the counter at either the falling edge or the rising edge (which ever I decide to set it to) and have the counter reset on the opposite edge. So for example of what I'd Like to do is, when a rising edge is detected the counter starts, then at the falling edge the counter stops then that value is placed in ICValue1 and the counter is restarted at the falling edge and is then stopped at the next rising edge, captured and saved to ICValue2, and the cycle is repeated again for the next pulse cycle. Also after looking threw the RM0016 document I found the PWM input example that does just that HOWEVER it only works for input on channel 1 or channel 2 on TIM1 but I need to use 4 channels, since the the signals coming from my RC-receiver are set up so that when CH1's pulse goes low CH2's pulse goes high, and when CH2's pulse goes low CH3's pulse goes high, and so on for 8 channels although I'm only gonna use 4 of them. Here an image of the servo pulses from the receiver. And here is how I wanna try and capture the signals. I apologize if the images are oversized.2010-03-19 12:50 AM
Hi Mken C- learner,
I have looked for in the reference manual if something could help you. PWM input couldn't help you because it counts the cycle report and total period but what you need in your application is measuring both high and low levels duration. Isn't it ? But I have a question: why you don't ICValue 2 - ICValaue1 and you have the duration you need ? If the solution above isn't suitable for you, I can suggest to look for in the reference manual how to use the trigger selection ''TS'' bits in SMCR register it could help you because there description on how to reset the counter on external event. Keep me informed if you have updates / questions ? Mit besten grüssen, MCU fan2010-03-19 02:01 AM
2010-03-19 02:24 PM
Hi Mken,
I have a question before sinking in the code. What is the precision that you need when measuring the servo pulses ? What is the minimum, maximum and steps of the PWM signals to be measured ? Is it of some µs or ms ? what about your clock configuration ? This detail could considerably simplify your code. With regards, MCU fan2010-03-19 10:17 PM
I can't find it at the moment but I remember reading that 5uS is equivalent to 1 degree on the servo, I'll be running Brushless motors but they still use the same exact pulses as a rc servo. The minimum ontime is 1mS neutral is 1.5mS and Maximum is 2ms, I want it as precise as possible. As for the clock I have the Timers running at default 2MHz, the code could very well be simplified down to possible 6-10lines if the PWMIConfig command didn't ONLY work for TIM1 CH1 or TIM1 CH2 since it uses the complementary channel but the trigger is only available for TI1F_ED, TI1FP1, and TI2FP2, also the fact that this is the only way I've actually gotten the code to work with all 4 channels at once, although so far it ONLY produces a good pulse on the oscilliscope, tryed it on some servos and the servos all swing to max limit one way and don't respond to any command signals even with the controls set to neutral position.
2010-03-20 01:16 AM
Hi Mken,
I have an other question is there a synchronization between the four signals or they are independent ? Is the pwm frame constant as you have drawn in the figure above: 22.5ms. If it the case why you need the off-time, you need the on-time and you can sustract the frame duration from the on-time to compute the off-time ???? I am trying to understand more your application so I can suggest you the better config for timer. Mit besten grüssen, MCU Lüfter