|
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
|