STM32F407VG Working code for reading 8 ch R/C PPM receiver

General discussion on mikroBasic PRO for ARM.
Post Reply
Author
Message
s_sergiu
Posts: 77
Joined: 10 Jan 2012 15:09

STM32F407VG Working code for reading 8 ch R/C PPM receiver

#1 Post by s_sergiu » 08 Jul 2012 17:17

Hi,

This was the last step on getting all peripherals working in order to make my first STM32F407 autopilot. You can see all other examples in previous posts: DMA USART for Rx and TX, Dma mode for all 3 ADC's. For Pwm output for motors/servo mE team has already given one clear example.
Here we go: reading of PPM output of any R/C receiver, no matter PCM, 2.4Ghz FHSS etc, as all of them are sending on the output, pulse between 1 to 2 ms 50-70 times /s.
Timers TIM1 and TIM8 are used in Input Capture Mode, triggered in both edges:
For different registers settings please read Reference manual. In this example, I used one port pin as PWM output in order to feed the inputs of the TIM1, TIM8 (simulating one R/C output).
All four inputs from TIM1 and TIM8 are used. Total of 8 inputs.



program PWM_RC_Input

Dim rc1,rc2,rc3,rc4,rc5,rc6,rc7,rc8 as word
Dim rco1,rco2,rco3,rco4,rco5,rco6,rco7,rco8 as word
Dim flag1,flag2,flag3,flag4,flag5,flag6,flag7,flag8 as bit
Dim rc_out1,rc_out2,rc_out3,rc_out4 as word
Dim rc_out5,rc_out6,rc_out7,rc_out8 as word
Dim nr as byte
Dim print_txt as string[10]
Dim pwm_period as word
Dim current_duty as word
Dim Led3 as sbit at GPIOD_ODR.B13
'*****************************************
'Interrupt routine for capture ; keep it as small as possible
sub procedure RC_TIM1() iv IVT_INT_TIM1_CC ics ICS_AUTO
if TIM1_SR.1=1 then
rc5 = TIM1_CCR1
flag5=1
end if
if TIM1_SR.2=1 then
rc6 = TIM1_CCR2
flag6=1
end if
if TIM1_SR.3=1 then
rc7 = TIM1_CCR3
flag7=1
end if
if TIM1_SR.4=1 then
rc8 = TIM1_CCR4
flag8=1
end if
end sub

sub procedure RC_TIM8() iv IVT_INT_TIM8_CC ics ICS_AUTO
if TIM8_SR.1=1 then
rc1 = TIM8_CCR1
flag1=1
end if
if TIM8_SR.2=1 then
rc2 = TIM8_CCR2
flag2=1
end if
if TIM8_SR.3=1 then
rc3 = TIM8_CCR3
flag3=1
end if
if TIM8_SR.4=1 then
rc4 = TIM8_CCR4
flag4=1
end if
end sub
'*****************************************

main:

Rem Enable high performance mode, System frequency up to 168 MHz
RCC_APB1ENR.PWREN=1
'*******************************************************************************
UART2_Init_Advanced(256000, _UART_8_BIT_DATA, _UART_NOPARITY, _UART_ONE_STOPBIT, @_GPIO_MODULE_USART2_PD56)
'*******************************************************************************
GPIO_Digital_Output(@GPIOD_BASE, _GPIO_PINMASK_13) ' Set PORTD.13 (Led3) as digital output
'******************************
rem generated PPM output signal signal
current_duty=4600 ' 4600 for about 1ms and 9200 for 2ms
PWM_TIM2_Init(70) ' 70Hz (Futaba 2.4Ghz receiver refresh rate is approx 65Hz)
PWM_TIM2_Set_Duty(current_duty, _PWM_NON_INVERTED, _PWM_CHANNEL2)
PWM_TIM2_Start(_PWM_CHANNEL2, @_GPIO_MODULE_TIM2_CH2_PB3)
PWM_TIM2_Set_Duty(current_duty, _PWM_NON_INVERTED, _PWM_CHANNEL2)
'*******************************************************************************
rem Enable TIM1 and TIM8 Peripheral Clock
RCC_APB2ENR.TIM1EN=1
RCC_APB2ENR.TIM8EN=1
'*****************************
rem Enable Port_A and Port_C Peripheral Clock
RCC_AHB1ENR.GPIOAEN=1
RCC_AHB1ENR.GPIOCEN=1
'*****************************
rem Configure the R/C input pins
rem config in alternate function
GPIOA_MODER.17=1 GPIOA_MODER.19=1 GPIOA_MODER.21=1 GPIOA_MODER.23=1
GPIOC_MODER.13=1 GPIOC_MODER.15=1 GPIOC_MODER.17=1 GPIOC_MODER.19=1
rem config pin speed 50Mhz
'GPIOA_OSPEEDR.17=1 GPIOA_OSPEEDR.19=1 GPIOA_OSPEEDR.21=1 GPIOA_OSPEEDR.23=1
rem config pullup/pulldn to PULL DOWN
GPIOA_PUPDR.17=1 GPIOA_PUPDR.19=1 GPIOA_PUPDR.21=1 GPIOA_PUPDR.23=1
GPIOC_PUPDR.13=1 GPIOC_PUPDR.15=1 GPIOC_PUPDR.17=1 GPIOC_PUPDR.19=1
rem alternate function for PortA TIM1 is AF1 and PortC TIM8 is AF3
GPIOA_AFRH.0=1 GPIOA_AFRH.4=1 GPIOA_AFRH.8=1 GPIOA_AFRH.12=1
GPIOC_AFRL.24=1 GPIOC_AFRL.25=1 GPIOC_AFRL.28=1 GPIOC_AFRL.29=1
GPIOC_AFRH.0=1 GPIOC_AFRH.1=1 GPIOC_AFRH.4=1 GPIOC_AFRH.5=1
'*****************************
rem Configure TIM1 and TIM8 for Input Capture
rem Clk prescaler AHB2/(PSC+1)
TIM1_PSC=167 ' we have 1us resolution (1000 to 2000us )
TIM8_PSC=167
rem Select the Active input (CC1S,CC2S,CC3S,CC4S),CC1 on TI1,CC2 on TI2...
TIM1_CCMR1O.8=1 TIM1_CCMR1O.0=1 TIM1_CCMR2O.8=1 TIM1_CCMR2O.0=1
TIM8_CCMR1O.8=1 TIM8_CCMR1O.0=1 TIM8_CCMR2O.8=1 TIM8_CCMR2O.0=1
'*****************************
rem Select the edge of the active transition on the TIx channel (CC1P and CC1NP) ;both edges
TIM1_CCER.1=1 TIM1_CCER.3=1 TIM1_CCER.5=1 TIM1_CCER.7=1
TIM1_CCER.9=1 TIM1_CCER.11=1 TIM1_CCER.13=1 TIM1_CCER.15=1
TIM8_CCER.1=1 TIM8_CCER.3=1 TIM8_CCER.5=1 TIM8_CCER.7=1
TIM8_CCER.9=1 TIM8_CCER.11=1 TIM8_CCER.13=1 TIM8_CCER.15=1
'*******************************
rem Enable capture from the counter in to the capture register (CCxE)
TIM1_CCER.12=1 TIM1_CCER.8=1 TIM1_CCER.4=1 TIM1_CCER.0=1
TIM8_CCER.12=1 TIM8_CCER.8=1 TIM8_CCER.4=1 TIM8_CCER.0=1
rem Enable interrupt request by setting CCxIE bit
TIM1_DIER.1=1 TIM1_DIER.2=1 TIM1_DIER.3=1 TIM1_DIER.4=1
TIM8_DIER.1=1 TIM8_DIER.2=1 TIM8_DIER.3=1 TIM8_DIER.4=1
'******************************************************
Delay_ms(1000)
UART2_Write_Text("R/C Input Capture Test")
UART2_Write(13)
UART2_Write(10)
Delay_ms(1000)
'******************************************************
rem Start TIM1 and TIM8
TIM1_CR1.0=1
TIM8_CR1.0=1
rem Enable interrupts
EnableInterrupts()
NVIC_IntEnable(IVT_INT_TIM1_CC)
NVIC_IntEnable(IVT_INT_TIM8_CC)
'******************************************************

while True

'*******************************************************
'**************** R/C PPM INPUT ************************
'*******************************************************
if flag1=1 then
flag1=0
if (rc1-rco1) > 700 then
if (rc1-rco1)<2300 then
rc_out1=rc1-rco1
end if
end if
rco1=rc1
WordToStr(rc_out1, print_txt)
UART2_Write_Text("rc1= ")
UART2_Write_Text(print_txt)
UART2_Write(13)
UART2_Write(10)
end if
'**********************
if flag2=1 then
flag2=0
if (rc2-rco2) > 700 then
if (rc2-rco2)<2300 then
rc_out2=rc2-rco2
end if
end if
rco2=rc2
WordToStr(rc_out2, print_txt)
UART2_Write_Text("rc2= ")
UART2_Write_Text(print_txt)
UART2_Write(13)
UART2_Write(10)
end if
'*********************
if flag3=1 then
flag3=0
if (rc3-rco3) > 700 then
if (rc3-rco3)<2300 then
rc_out3=rc3-rco3
end if
end if
rco3=rc3
WordToStr(rc_out3, print_txt)
UART2_Write_Text("rc3= ")
UART2_Write_Text(print_txt)
UART2_Write(13)
UART2_Write(10)
end if
'*********************
if flag4=1 then
flag4=0
if (rc4-rco4) > 700 then
if (rc4-rco4)<2300 then
rc_out4=rc4-rco4
end if
end if
rco4=rc4
WordToStr(rc_out4, print_txt)
UART2_Write_Text("rc4= ")
UART2_Write_Text(print_txt)
UART2_Write(13)
UART2_Write(10)
end if
'************************
'************************
if flag5=1 then
flag5=0
if (rc5-rco5) > 700 then
if (rc5-rco5)<2300 then
rc_out5=rc5-rco5
end if
end if
rco5=rc5
WordToStr(rc_out5, print_txt)
UART2_Write_Text("rc5= ")
UART2_Write_Text(print_txt)
UART2_Write(13)
UART2_Write(10)
end if
'**************************
if flag6=1 then
flag6=0
if (rc6-rco6) > 700 then
if (rc6-rco6)<2300 then
rc_out6=rc6-rco6
end if
end if
rco6=rc6
WordToStr(rc_out6, print_txt)
UART2_Write_Text("rc6= ")
UART2_Write_Text(print_txt)
UART2_Write(13)
UART2_Write(10)
end if
'************************
if flag7=1 then
flag7=0
if (rc7-rco7) > 700 then
if (rc7-rco7)<2300 then
rc_out7=rc7-rco7
end if
end if
rco7=rc7
WordToStr(rc_out7, print_txt)
UART2_Write_Text("rc7= ")
UART2_Write_Text(print_txt)
UART2_Write(13)
UART2_Write(10)
end if
'************************
if flag8=1 then
flag8=0
if (rc8-rco8) > 700 then
if (rc8-rco8)<2300 then
rc_out8=rc8-rco8
end if
end if
rco8=rc8
WordToStr(rc_out8, print_txt)
UART2_Write_Text("rc8= ")
UART2_Write_Text(print_txt)
UART2_Write(13)
UART2_Write(10)
end if
'****************************************************
'************ END R/C PPM Input *********************
'****************************************************



wend

end.

Cheers,
Sergiu

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: STM32F407VG Working code for reading 8 ch R/C PPM recei

#2 Post by filip » 09 Jul 2012 08:47

Hi,

Thank you for sharing this code, it would be great if you could upload some video regarding auto pilot when you finish your project. :)

Regards,
Filip.

s_sergiu
Posts: 77
Joined: 10 Jan 2012 15:09

Re: STM32F407VG Working code for reading 8 ch R/C PPM recei

#3 Post by s_sergiu » 09 Jul 2012 11:43

Hi Filip,

You can be sure of that. I am certain that STM32F407 have the horse power I was always looking for and because I know (and like) basic language, mikroBasic Pro for ARM was the missing link .

Cheers,
Sergiu

SeanH
Posts: 37
Joined: 10 Oct 2014 20:47

Re: STM32F407VG Working code for reading 8 ch R/C PPM recei

#4 Post by SeanH » 29 Oct 2014 22:56

Hi Sergiu

Old post I know, but thank you for this and nicely laid out.

It helped me understand a few different registers that is helping with getting to grips with the processor.

Cheers

Sean.

Post Reply

Return to “mikroBasic PRO for ARM General”