- 校正舵机中位、转向符号和阿克曼后轮差速模型\n- 增加航向角速度辅助及遥控通道调试开关\n- 将速度环提升至 200Hz,并按实际 dt 计算 PI 积分\n- 将 IMU 启动校准缩短为 2 秒\n- 为 USART3 增加 DMA 发送和 MCU 采样时间戳
554 lines
27 KiB
C
554 lines
27 KiB
C
#include "timer.h"
|
||
|
||
//Input the capture flag for channel 1,
|
||
//the capture flag for the higher bits, and the overflow flag for the lower 6 bits
|
||
//ͨ<><CDA8>1<EFBFBD><31><EFBFBD>벶<EFBFBD><EBB2B6><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>6λ<36><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
||
u8 TIM8CH1_CAPTURE_STA = 0;
|
||
u16 TIM8CH1_CAPTURE_UPVAL;
|
||
u16 TIM8CH1_CAPTURE_DOWNVAL;
|
||
|
||
//Input the capture flag for channel 2,
|
||
//the capture flag for the higher bits, and the overflow flag for the lower 6 bits
|
||
//ͨ<><CDA8>2<EFBFBD><32><EFBFBD>벶<EFBFBD><EBB2B6><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>6λ<36><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
||
u8 TIM8CH2_CAPTURE_STA = 0;
|
||
u16 TIM8CH2_CAPTURE_UPVAL;
|
||
u16 TIM8CH2_CAPTURE_DOWNVAL;
|
||
|
||
//Input the capture flag for channel 3,
|
||
//the capture flag for the higher bits, and the overflow flag for the lower 6 bits
|
||
//ͨ<><CDA8>3<EFBFBD><33><EFBFBD>벶<EFBFBD><EBB2B6><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>6λ<36><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
||
u8 TIM8CH3_CAPTURE_STA = 0;
|
||
u16 TIM8CH3_CAPTURE_UPVAL;
|
||
u16 TIM8CH3_CAPTURE_DOWNVAL;
|
||
|
||
//Input the capture flag for channel 4,
|
||
//the capture flag for the higher bits, and the overflow flag for the lower 6 bits
|
||
//ͨ<><CDA8>4<EFBFBD><34><EFBFBD>벶<EFBFBD><EBB2B6><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>6λ<36><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
||
u8 TIM8CH4_CAPTURE_STA = 0;
|
||
u16 TIM8CH4_CAPTURE_UPVAL;
|
||
u16 TIM8CH4_CAPTURE_DOWNVAL;
|
||
|
||
u32 TIM8_T1;
|
||
u32 TIM8_T2;
|
||
u32 TIM8_T3;
|
||
u32 TIM8_T4;
|
||
|
||
//Variables related to remote control acquisition of model aircraft
|
||
//<2F><>ģң<C4A3>زɼ<D8B2><C9BC><EFBFBD>ر<EFBFBD><D8B1><EFBFBD>
|
||
int Remoter_Ch1=1500,Remoter_Ch2=1500,Remoter_Ch3=1500,Remoter_Ch4=1500;
|
||
//Model aircraft remote control receiver variable
|
||
//<2F><>ģң<C4A3>ؽ<EFBFBD><D8BD>ձ<EFBFBD><D5B1><EFBFBD>
|
||
int L_Remoter_Ch1=1500,L_Remoter_Ch2=1500,L_Remoter_Ch3=1500,L_Remoter_Ch4=1500;
|
||
|
||
/**************************************************************************
|
||
Function: Model aircraft remote control initialization function, timer 1 input capture initialization
|
||
Input : arr: Automatic reload value, psc: clock preset frequency
|
||
Output : none
|
||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>ģң<EFBFBD>س<EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD>벶<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>
|
||
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>arr<EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD>װֵ<EFBFBD><EFBFBD>psc<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD>
|
||
<EFBFBD><EFBFBD> <20><> ֵ<><D6B5><EFBFBD><EFBFBD>
|
||
**************************************************************************/
|
||
void TIM8_Cap_Init(u16 arr, u16 psc)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStructure;
|
||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||
NVIC_InitTypeDef NVIC_InitStructure;
|
||
TIM_ICInitTypeDef TIM_ICInitStructure;
|
||
|
||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM1ʱ<31><CAB1>ʹ<EFBFBD><CAB9>
|
||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //ʹ<><CAB9>PORTEʱ<45><CAB1>
|
||
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; //GPIOC
|
||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//<2F><><EFBFBD>ù<EFBFBD><C3B9><EFBFBD>
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //<2F>ٶ<EFBFBD>100MHz
|
||
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //<2F><><EFBFBD>츴<EFBFBD><ECB8B4><EFBFBD><EFBFBD><EFBFBD>
|
||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //<2F><><EFBFBD><EFBFBD>
|
||
GPIO_Init(GPIOC,&GPIO_InitStructure);
|
||
|
||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8);
|
||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8);
|
||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8);
|
||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_TIM8);
|
||
|
||
/*** Initialize timer 1 || <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>1 ***/
|
||
//Set the counter to automatically reload //<2F>趨<EFBFBD><E8B6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>װֵ
|
||
TIM_TimeBaseStructure.TIM_Period = arr;
|
||
//Pre-divider //Ԥ<><D4A4>Ƶ<EFBFBD><C6B5>
|
||
TIM_TimeBaseStructure.TIM_Prescaler = psc;
|
||
//Set the clock split: TDTS = Tck_tim //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD>ӷָ<D3B7>:TDTS = Tck_tim
|
||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||
//TIM up count mode //TIM<49><4D><EFBFBD>ϼ<EFBFBD><CFBC><EFBFBD>ģʽ
|
||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||
//Initializes the timebase unit for TIMX based on the parameter specified in TIM_TimeBaseInitStruct
|
||
//<2F><><EFBFBD><EFBFBD>TIM_TimeBaseInitStruct<63><74>ָ<EFBFBD><D6B8><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>TIMx<4D><78>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
|
||
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
|
||
|
||
/*** <20><>ʼ<EFBFBD><CABC>TIM1<4D><31><EFBFBD>벶<EFBFBD><EBB2B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8>1 || Initialize TIM1 for the capture parameter, channel 1 ***/
|
||
//Select input //ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
|
||
//Rising edge capture //<2F><><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
|
||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
|
||
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
|
||
//Configure input frequency division, regardless of frequency //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ,<2C><><EFBFBD><EFBFBD>Ƶ
|
||
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
|
||
//IC1F=0000 Configure input filter //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><CBB2><EFBFBD>
|
||
TIM_ICInitStructure.TIM_ICFilter = 0x0F;
|
||
TIM_ICInit(TIM8, &TIM_ICInitStructure);
|
||
|
||
/*** <20><>ʼ<EFBFBD><CABC>TIM1<4D><31><EFBFBD>벶<EFBFBD><EBB2B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8>2 || Initialize TIM1 for the capture parameter, channel 2 ***/
|
||
//CC1S=01 Select input //ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
|
||
//Rising edge capture //<2F><><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
|
||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
|
||
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
|
||
//Configure input frequency division, regardless of frequency //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ,<2C><><EFBFBD><EFBFBD>Ƶ
|
||
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
|
||
TIM_ICInitStructure.TIM_ICFilter = 0x00; //IC1F=0000 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><CBB2><EFBFBD>
|
||
TIM_ICInit(TIM8, &TIM_ICInitStructure);
|
||
|
||
/*** <20><>ʼ<EFBFBD><CABC>TIM1<4D><31><EFBFBD>벶<EFBFBD><EBB2B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8>3 || Initialize TIM1 for the capture parameter, channel 3 ***/
|
||
//Select input //ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
|
||
//Rising edge capture //<2F><><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
|
||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
|
||
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
|
||
//Configure input frequency division, regardless of frequency //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ,<2C><><EFBFBD><EFBFBD>Ƶ
|
||
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
|
||
//IC1F=0000 Configure input filter //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD>
|
||
TIM_ICInitStructure.TIM_ICFilter = 0x00;
|
||
TIM_ICInit(TIM8, &TIM_ICInitStructure);
|
||
|
||
/*** <20><>ʼ<EFBFBD><CABC>TIM1<4D><31><EFBFBD>벶<EFBFBD><EBB2B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8>4 || Initialize TIM1 for the capture parameter, channel 4 ***/
|
||
//Select input //ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
|
||
//Rising edge capture //<2F><><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
|
||
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
|
||
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
|
||
//Configure input frequency division, regardless of frequency //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ,<2C><><EFBFBD><EFBFBD>Ƶ
|
||
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
|
||
//IC1F=0000 Configure input filter //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD>
|
||
TIM_ICInitStructure.TIM_ICFilter = 0x00;
|
||
TIM_ICInit(TIM8, &TIM_ICInitStructure);
|
||
|
||
/*** interrupt packet initialization || <20>жϷ<D0B6><CFB7><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC> ***/
|
||
//TIM1 interrupts //TIM1<4D>ж<EFBFBD>
|
||
NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn;
|
||
//Preempt priority 0 //<2F><>ռ<EFBFBD><D5BC><EFBFBD>ȼ<EFBFBD>0<EFBFBD><30>
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
|
||
//Level 0 from priority //<2F><><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>0<EFBFBD><30>
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
|
||
//IRQ channels are enabled //IRQͨ<51><CDA8><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
//Initializes the peripheral NVIC register according to the parameters specified in NVIC_InitStruct
|
||
//<2F><><EFBFBD><EFBFBD>NVIC_InitStruct<63><74>ָ<EFBFBD><D6B8><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>NVIC<49>Ĵ<EFBFBD><C4B4><EFBFBD>
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
|
||
//Allow CC1IE,CC2IE,CC3IE,CC4IE to catch interrupts, not allowed update_interrupts
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϣ<D0B6><CFA3><EFBFBD><EFBFBD><EFBFBD>CC1IE,CC2IE,CC3IE,CC4IE<49><45><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
|
||
TIM_ITConfig(TIM8, TIM_IT_CC1|TIM_IT_CC2|TIM_IT_CC3|TIM_IT_CC4, ENABLE);
|
||
//Advanced timer output must be enabled //<2F><EFBFBD><DFBC><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD>
|
||
TIM_CtrlPWMOutputs(TIM8,ENABLE);
|
||
//Enable timer //ʹ<>ܶ<EFBFBD>ʱ<EFBFBD><CAB1>
|
||
TIM_Cmd(TIM8, ENABLE);
|
||
}
|
||
/**************************************************************************
|
||
Function: Model aircraft remote control receiving interrupt, namely timer 8 input capture interrupt
|
||
Input : none
|
||
Output : none
|
||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>ģң<EFBFBD>ؽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>8<EFBFBD><EFBFBD><EFBFBD>벶<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
|
||
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
<EFBFBD><EFBFBD> <20><> ֵ<><D6B5><EFBFBD><EFBFBD>
|
||
**************************************************************************/
|
||
void TIM8_CC_IRQHandler(void)
|
||
{
|
||
//<2F><><EFBFBD>Ӻ<EFBFBD>ģңң<D2A3><D2A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>ˣ<EFBFBD><CBA3>ſ<EFBFBD><C5BF><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>С<EFBFBD><D0A1>
|
||
//After connecting the remote controller of the model aircraft,
|
||
//you need to push down the forward lever to officially control the car of the model aircraft
|
||
if(Remoter_Ch2>1600&&Remote_ON_Flag==0&&Deviation_Count>=CONTROL_DELAY)
|
||
{
|
||
//Model aircraft remote control mark position 1, other marks position 0
|
||
//<2F><>ģң<C4A3>ر<EFBFBD>־λ<D6BE><CEBB>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־λ<D6BE><CEBB>0
|
||
Remote_ON_Flag=1;
|
||
APP_ON_Flag=0;
|
||
PS2_ON_Flag=0;
|
||
CAN_ON_Flag=0;
|
||
//Usart_ON_Flag=0;
|
||
Usart1_ON_Flag=0;
|
||
Usart5_ON_Flag=0;
|
||
}
|
||
|
||
|
||
|
||
// //Channel 1 //ͨ<><CDA8>һ
|
||
if ((TIM8CH1_CAPTURE_STA & 0X80) == 0)
|
||
{
|
||
if (TIM_GetITStatus(TIM8, TIM_IT_CC1) != RESET) //A capture event occurred on channel 1 //ͨ<><CDA8>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
|
||
{
|
||
TIM_ClearITPendingBit(TIM8, TIM_IT_CC1); //Clear the interrupt flag bit //<2F><><EFBFBD><EFBFBD>жϱ<D0B6>־λ
|
||
if (TIM8CH1_CAPTURE_STA & 0X40) //A falling edge is caught //<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
|
||
{
|
||
TIM8CH1_CAPTURE_DOWNVAL = TIM_GetCapture1(TIM8); //Record the timer value at this point //<2F><>¼<EFBFBD>´<EFBFBD>ʱ<EFBFBD>Ķ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||
if (TIM8CH1_CAPTURE_DOWNVAL < TIM8CH1_CAPTURE_UPVAL)
|
||
{
|
||
TIM8_T1 = 9999;
|
||
}
|
||
else
|
||
TIM8_T1 = 0;
|
||
Remoter_Ch1 = TIM8CH1_CAPTURE_DOWNVAL - TIM8CH1_CAPTURE_UPVAL + TIM8_T1; //Time to get the total high level //<2F>õ<EFBFBD><C3B5>ܵĸߵ<C4B8>ƽ<EFBFBD><C6BD>ʱ<EFBFBD><CAB1>
|
||
if(abs(Remoter_Ch1-L_Remoter_Ch1)>500) Remoter_Ch1=L_Remoter_Ch1; //Filter //<2F>˲<EFBFBD>
|
||
L_Remoter_Ch1=Remoter_Ch1;
|
||
|
||
TIM8CH1_CAPTURE_STA = 0; //Capture flag bit to zero //<2F><><EFBFBD><EFBFBD><EFBFBD>־λ<D6BE><CEBB><EFBFBD><EFBFBD>
|
||
TIM_OC1PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //<2F><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
|
||
}
|
||
else
|
||
{
|
||
//When the capture time occurs but not the falling edge, the first time the rising edge is captured, record the timer value at this time
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>䵫<EFBFBD><E4B5AB><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD>أ<EFBFBD><D8A3><EFBFBD>һ<EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>أ<EFBFBD><D8A3><EFBFBD>¼<EFBFBD><C2BC>ʱ<EFBFBD>Ķ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||
TIM8CH1_CAPTURE_UPVAL = TIM_GetCapture1(TIM8); //Obtain rising edge data //<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
TIM8CH1_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //<2F><><EFBFBD><EFBFBD>Ѳ<EFBFBD><D1B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
TIM_OC1PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //<2F><><EFBFBD><EFBFBD>Ϊ<EFBFBD>½<EFBFBD><C2BD>ز<EFBFBD><D8B2><EFBFBD>
|
||
}
|
||
}
|
||
}
|
||
//Channel 2 //ͨ<><CDA8><EFBFBD><EFBFBD>
|
||
if ((TIM8CH2_CAPTURE_STA & 0X80) == 0)
|
||
{
|
||
if (TIM_GetITStatus(TIM8, TIM_IT_CC2) != RESET) //A capture event occurred on channel 2 //ͨ<><CDA8>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
|
||
{
|
||
TIM_ClearITPendingBit(TIM8, TIM_IT_CC2); //Clear the interrupt flag bit //<2F><><EFBFBD><EFBFBD>жϱ<D0B6>־λ
|
||
if (TIM8CH2_CAPTURE_STA & 0X40) //A falling edge is caught //<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
|
||
{
|
||
TIM8CH2_CAPTURE_DOWNVAL = TIM_GetCapture2(TIM8); //Record the timer value at this point //<2F><>¼<EFBFBD>´<EFBFBD>ʱ<EFBFBD>Ķ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||
if (TIM8CH2_CAPTURE_DOWNVAL < TIM8CH2_CAPTURE_UPVAL)
|
||
{
|
||
TIM8_T2 = 9999;
|
||
}
|
||
else
|
||
TIM8_T2 = 0;
|
||
Remoter_Ch2 = TIM8CH2_CAPTURE_DOWNVAL - TIM8CH2_CAPTURE_UPVAL + TIM8_T2; //Time to get the total high level //<2F>õ<EFBFBD><C3B5>ܵĸߵ<C4B8>ƽ<EFBFBD><C6BD>ʱ<EFBFBD><CAB1>
|
||
if(abs(Remoter_Ch2-L_Remoter_Ch2)>500)Remoter_Ch2=L_Remoter_Ch2; //Filter //<2F>˲<EFBFBD>
|
||
L_Remoter_Ch2=Remoter_Ch2;
|
||
|
||
TIM8CH2_CAPTURE_STA = 0; //Capture flag bit to zero //<2F><><EFBFBD><EFBFBD><EFBFBD>־λ<D6BE><CEBB><EFBFBD><EFBFBD>
|
||
TIM_OC2PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //<2F><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
|
||
}
|
||
else
|
||
{
|
||
//When the capture time occurs but not the falling edge, the first time the rising edge is captured, record the timer value at this time
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>䵫<EFBFBD><E4B5AB><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD>أ<EFBFBD><D8A3><EFBFBD>һ<EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>أ<EFBFBD><D8A3><EFBFBD>¼<EFBFBD><C2BC>ʱ<EFBFBD>Ķ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||
TIM8CH2_CAPTURE_UPVAL = TIM_GetCapture2(TIM8); //Obtain rising edge data //<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
TIM8CH2_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //<2F><><EFBFBD><EFBFBD>Ѳ<EFBFBD><D1B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
TIM_OC2PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //<2F><><EFBFBD><EFBFBD>Ϊ<EFBFBD>½<EFBFBD><C2BD>ز<EFBFBD><D8B2><EFBFBD>
|
||
}
|
||
}
|
||
}
|
||
//Channel 3 //ͨ<><CDA8><EFBFBD><EFBFBD>
|
||
if ((TIM8CH3_CAPTURE_STA & 0X80) == 0)
|
||
{
|
||
if (TIM_GetITStatus(TIM8, TIM_IT_CC3) != RESET) //A capture event occurred on channel 3 //ͨ<><CDA8>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
|
||
{
|
||
TIM_ClearITPendingBit(TIM8, TIM_IT_CC3); //Clear the interrupt flag bit //<2F><><EFBFBD><EFBFBD>жϱ<D0B6>־λ
|
||
if (TIM8CH3_CAPTURE_STA & 0X40) //A falling edge is caught //<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
|
||
{
|
||
TIM8CH3_CAPTURE_DOWNVAL = TIM_GetCapture3(TIM8); //Record the timer value at this point //<2F><>¼<EFBFBD>´<EFBFBD>ʱ<EFBFBD>Ķ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||
if (TIM8CH3_CAPTURE_DOWNVAL < TIM8CH3_CAPTURE_UPVAL)
|
||
{
|
||
TIM8_T3 = 9999;
|
||
}
|
||
else
|
||
TIM8_T3 = 0;
|
||
Remoter_Ch3 = TIM8CH3_CAPTURE_DOWNVAL - TIM8CH3_CAPTURE_UPVAL + TIM8_T3; //Time to get the total high level //<2F>õ<EFBFBD><C3B5>ܵĸߵ<C4B8>ƽ<EFBFBD><C6BD>ʱ<EFBFBD><CAB1>
|
||
if(abs(Remoter_Ch3-L_Remoter_Ch3)>500)Remoter_Ch3=L_Remoter_Ch3; //Filter //<2F>˲<EFBFBD>
|
||
L_Remoter_Ch3=Remoter_Ch3;
|
||
TIM8CH3_CAPTURE_STA = 0; //Capture flag bit to zero //<2F><><EFBFBD><EFBFBD><EFBFBD>־λ<D6BE><CEBB><EFBFBD><EFBFBD>
|
||
TIM_OC3PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //<2F><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
|
||
}
|
||
else
|
||
{
|
||
//When the capture time occurs but not the falling edge, the first time the rising edge is captured, record the timer value at this time
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>䵫<EFBFBD><E4B5AB><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD>أ<EFBFBD><D8A3><EFBFBD>һ<EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>أ<EFBFBD><D8A3><EFBFBD>¼<EFBFBD><C2BC>ʱ<EFBFBD>Ķ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||
TIM8CH3_CAPTURE_UPVAL = TIM_GetCapture3(TIM8); //Obtain rising edge data //<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
TIM8CH3_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //<2F><><EFBFBD><EFBFBD>Ѳ<EFBFBD><D1B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
TIM_OC3PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //<2F><><EFBFBD><EFBFBD>Ϊ<EFBFBD>½<EFBFBD><C2BD>ز<EFBFBD><D8B2><EFBFBD>
|
||
}
|
||
}
|
||
}
|
||
//
|
||
|
||
//Channel 4 //ͨ<><CDA8><EFBFBD><EFBFBD>
|
||
if ((TIM8CH4_CAPTURE_STA & 0X80) == 0)
|
||
{
|
||
if (TIM_GetITStatus(TIM8, TIM_IT_CC4) != RESET) //A capture event occurred on channel 4 //ͨ<><CDA8>4<EFBFBD><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
|
||
{
|
||
TIM_ClearITPendingBit(TIM8, TIM_IT_CC4); //Clear the interrupt flag bit //<2F><><EFBFBD><EFBFBD>жϱ<D0B6>־λ
|
||
if (TIM8CH4_CAPTURE_STA & 0X40) //A falling edge is caught //<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
|
||
{
|
||
TIM8CH4_CAPTURE_DOWNVAL = TIM_GetCapture4(TIM8); //Record the timer value at this point //<2F><>¼<EFBFBD>´<EFBFBD>ʱ<EFBFBD>Ķ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||
if (TIM8CH4_CAPTURE_DOWNVAL < TIM8CH4_CAPTURE_UPVAL)
|
||
{
|
||
TIM8_T4 = 9999;
|
||
}
|
||
else
|
||
TIM8_T4 = 0;
|
||
Remoter_Ch4 = TIM8CH4_CAPTURE_DOWNVAL - TIM8CH4_CAPTURE_UPVAL + TIM8_T4; //Time to get the total high level //<2F>õ<EFBFBD><C3B5>ܵĸߵ<C4B8>ƽ<EFBFBD><C6BD>ʱ<EFBFBD><CAB1>
|
||
if(abs(Remoter_Ch4-L_Remoter_Ch4)>500)Remoter_Ch4=L_Remoter_Ch4; //Filter //<2F>˲<EFBFBD>
|
||
L_Remoter_Ch4=Remoter_Ch4;
|
||
TIM8CH4_CAPTURE_STA = 0; //Capture flag bit to zero //<2F><><EFBFBD><EFBFBD><EFBFBD>־λ<D6BE><CEBB><EFBFBD><EFBFBD>
|
||
TIM_OC4PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //<2F><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
|
||
}
|
||
else
|
||
{
|
||
//When the capture time occurs but not the falling edge, the first time the rising edge is captured, record the timer value at this time
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>䵫<EFBFBD><E4B5AB><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD>أ<EFBFBD><D8A3><EFBFBD>һ<EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>أ<EFBFBD><D8A3><EFBFBD>¼<EFBFBD><C2BC>ʱ<EFBFBD>Ķ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||
TIM8CH4_CAPTURE_UPVAL = TIM_GetCapture4(TIM8); //Obtain rising edge data //<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
TIM8CH4_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //<2F><><EFBFBD><EFBFBD>Ѳ<EFBFBD><D1B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
TIM_OC4PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //<2F><><EFBFBD><EFBFBD>Ϊ<EFBFBD>½<EFBFBD><C2BD>ز<EFBFBD><D8B2><EFBFBD>
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/**************************************************************************
|
||
Function: TIM1 Update Interrupt
|
||
Input : none
|
||
Output : none
|
||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>8<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
|
||
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5><EFBFBD><EFBFBD>
|
||
**************************************************************************/
|
||
void TIM8_UP_TIM13_IRQHandler(void)
|
||
{
|
||
//Clear the interrupt flag bit
|
||
//<2F><><EFBFBD><EFBFBD>жϱ<D0B6>־λ
|
||
TIM8->SR&=~(1<<0);
|
||
}
|
||
|
||
void TIM8_SERVO_Init(u16 arr,u16 psc)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStructure; //IO
|
||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //<2F><>ʱ<EFBFBD><CAB1>
|
||
TIM_OCInitTypeDef TIM_OCInitStructure; //PWM<57><4D><EFBFBD>
|
||
|
||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM1ʱ<31><CAB1>ʹ<EFBFBD><CAB9>
|
||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //ʹ<><CAB9>PORTEʱ<45><CAB1>
|
||
|
||
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
|
||
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
|
||
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
|
||
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
|
||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||
|
||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8);
|
||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8);
|
||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8);
|
||
GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_TIM8);
|
||
|
||
|
||
/*** Initialize timer 1 || <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>1 ***/
|
||
//Set the counter to automatically reload //<2F>趨<EFBFBD><E8B6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>װֵ
|
||
TIM_TimeBaseStructure.TIM_Period = arr;
|
||
//Pre-divider //Ԥ<><D4A4>Ƶ<EFBFBD><C6B5>
|
||
TIM_TimeBaseStructure.TIM_Prescaler = psc;
|
||
//Set the clock split: TDTS = Tck_tim //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD>ӷָ<D3B7>:TDTS = Tck_tim
|
||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||
//TIM up count mode //TIM<49><4D><EFBFBD>ϼ<EFBFBD><CFBC><EFBFBD>ģʽ
|
||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||
//Initializes the timebase unit for TIMX based on the parameter specified in TIM_TimeBaseInitStruct
|
||
//<2F><><EFBFBD><EFBFBD>TIM_TimeBaseInitStruct<63><74>ָ<EFBFBD><D6B8><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>TIMx<4D><78>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
|
||
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
|
||
|
||
|
||
//-----------<2D><><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>-----------//
|
||
//Select Timer mode :TIM Pulse Width Modulation mode 1
|
||
//ѡ<><D1A1>ʱ<EFBFBD><CAB1>ģʽ:TIM<49><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD>ģʽ1
|
||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
||
//Compare output enablement
|
||
//<2F>Ƚ<EFBFBD><C8BD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>
|
||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
||
//Set the pulse value of the capture comparison register to be loaded
|
||
//<2F><><EFBFBD>ô<EFBFBD>װ<EFBFBD>벶<EFBFBD><EBB2B6>ȽϼĴ<CFBC><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||
TIM_OCInitStructure.TIM_Pulse = 0;
|
||
//Output polarity :TIM output polarity is higher
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:TIM<49><4D><EFBFBD><EFBFBD>Ƚϼ<C8BD><CFBC>Ը<EFBFBD>
|
||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
|
||
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
|
||
|
||
//Initialize the peripheral TIMX based on the parameter specified in TIM_OCINITSTRUCT
|
||
//<2F><><EFBFBD><EFBFBD>TIM_OCInitStruct<63><74>ָ<EFBFBD><D6B8><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TIMx
|
||
TIM_OC1Init(TIM8, &TIM_OCInitStructure);
|
||
TIM_OC2Init(TIM8, &TIM_OCInitStructure);
|
||
TIM_OC3Init(TIM8, &TIM_OCInitStructure);
|
||
TIM_OC4Init(TIM8, &TIM_OCInitStructure);
|
||
//Channel preload enable
|
||
//ͨ<><CDA8>Ԥװ<D4A4><D7B0>ʹ<EFBFBD><CAB9>
|
||
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);
|
||
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);
|
||
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable);
|
||
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable);
|
||
//-----------<2D><><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>-----------//
|
||
|
||
TIM_CtrlPWMOutputs(TIM8,ENABLE);
|
||
//Enable timer //ʹ<>ܶ<EFBFBD>ʱ<EFBFBD><CAB1>
|
||
TIM_Cmd(TIM8, ENABLE);
|
||
|
||
//The channel value is initialized to 1500, corresponding to the steering gear zero
|
||
//ͨ<><CDA8>ֵ<EFBFBD><D6B5>ʼ<EFBFBD><CABC>Ϊ1500<30><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧֵ
|
||
// TIM8->CCR1=1500;
|
||
// TIM8->CCR2=1500;
|
||
// TIM8->CCR3=1500;
|
||
// TIM8->CCR4=1500;
|
||
}
|
||
|
||
|
||
void TIM12_SERVO_Init(u16 arr,u16 psc)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStructure; //IO
|
||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //<2F><>ʱ<EFBFBD><CAB1>
|
||
TIM_OCInitTypeDef TIM_OCInitStructure; //PWM<57><4D><EFBFBD>
|
||
|
||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM12,ENABLE); //TIM1ʱ<31><CAB1>ʹ<EFBFBD><CAB9>
|
||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //ʹ<><CAB9>PORTEʱ<45><CAB1>
|
||
|
||
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
|
||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_15;
|
||
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
|
||
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
|
||
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
|
||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||
|
||
GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_TIM12);
|
||
GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_TIM12);
|
||
|
||
|
||
/*** Initialize timer 1 || <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>1 ***/
|
||
//Set the counter to automatically reload //<2F>趨<EFBFBD><E8B6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>װֵ
|
||
TIM_TimeBaseStructure.TIM_Period = arr;
|
||
//Pre-divider //Ԥ<><D4A4>Ƶ<EFBFBD><C6B5>
|
||
TIM_TimeBaseStructure.TIM_Prescaler = psc;
|
||
//Set the clock split: TDTS = Tck_tim //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD>ӷָ<D3B7>:TDTS = Tck_tim
|
||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||
//TIM up count mode //TIM<49><4D><EFBFBD>ϼ<EFBFBD><CFBC><EFBFBD>ģʽ
|
||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||
//Initializes the timebase unit for TIMX based on the parameter specified in TIM_TimeBaseInitStruct
|
||
//<2F><><EFBFBD><EFBFBD>TIM_TimeBaseInitStruct<63><74>ָ<EFBFBD><D6B8><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>TIMx<4D><78>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
|
||
TIM_TimeBaseInit(TIM12, &TIM_TimeBaseStructure);
|
||
|
||
|
||
//-----------<2D><><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>-----------//
|
||
//Select Timer mode :TIM Pulse Width Modulation mode 1
|
||
//ѡ<><D1A1>ʱ<EFBFBD><CAB1>ģʽ:TIM<49><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD>ģʽ1
|
||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
||
//Compare output enablement
|
||
//<2F>Ƚ<EFBFBD><C8BD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>
|
||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
||
//Set the pulse value of the capture comparison register to be loaded
|
||
//<2F><><EFBFBD>ô<EFBFBD>װ<EFBFBD>벶<EFBFBD><EBB2B6>ȽϼĴ<CFBC><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||
TIM_OCInitStructure.TIM_Pulse = 0;
|
||
//Output polarity :TIM output polarity is higher
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:TIM<49><4D><EFBFBD><EFBFBD>Ƚϼ<C8BD><CFBC>Ը<EFBFBD>
|
||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
|
||
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
|
||
|
||
//Initialize the peripheral TIMX based on the parameter specified in TIM_OCINITSTRUCT
|
||
//<2F><><EFBFBD><EFBFBD>TIM_OCInitStruct<63><74>ָ<EFBFBD><D6B8><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TIMx
|
||
TIM_OC1Init(TIM12, &TIM_OCInitStructure);
|
||
TIM_OC2Init(TIM12, &TIM_OCInitStructure);
|
||
//Channel preload enable
|
||
//ͨ<><CDA8>Ԥװ<D4A4><D7B0>ʹ<EFBFBD><CAB9>
|
||
TIM_OC1PreloadConfig(TIM12, TIM_OCPreload_Enable);
|
||
TIM_OC2PreloadConfig(TIM12, TIM_OCPreload_Enable);
|
||
//-----------<2D><><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>-----------//
|
||
|
||
|
||
TIM_CtrlPWMOutputs(TIM12,ENABLE);
|
||
//Enable timer //ʹ<>ܶ<EFBFBD>ʱ<EFBFBD><CAB1>
|
||
TIM_Cmd(TIM12, ENABLE);
|
||
|
||
//Initialize both servo channels to the configured steering center.
|
||
TIM12->CCR2=SERVO_INIT;
|
||
TIM12->CCR1=SERVO_INIT;
|
||
|
||
}
|
||
|
||
/**************************************************************************
|
||
Function: Free-running microsecond time base for sensor timestamps
|
||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>뼶<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
|
||
TIM7 counts at 1 MHz (1 tick = 1 us) and wraps every 65.536 ms. An update
|
||
interrupt increments a 32-bit high word, extending the clock to 48 usable
|
||
bits (~8.9 years) that only ever counts up. Timers TIM2-TIM5 are taken by
|
||
the encoders and TIM8 by input capture, so TIM7 is the free APB1 timer.
|
||
TIM7 <20><> 1MHz <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 65.536ms <20><><EFBFBD>ƣ<EFBFBD><C6A3><EFBFBD><EFBFBD>¸<EFBFBD><C2B8>ж<EFBFBD><D0B6><EFBFBD>λ<EFBFBD><CEBB> 32λ<32><CEBB><EFBFBD>ָߣ<D6B8>
|
||
<EFBFBD><EFBFBD>չ<EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>䡣TIM2~TIM5 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>TIM8 <20><><EFBFBD>벶<EFBFBD><EBB2B6><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
|
||
<EFBFBD><EFBFBD> TIM7 <20><><EFBFBD>С<EFBFBD>
|
||
**************************************************************************/
|
||
static volatile uint32_t g_time_high = 0;
|
||
|
||
void TIM7_Init(void)
|
||
{
|
||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||
NVIC_InitTypeDef NVIC_InitStructure;
|
||
|
||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);
|
||
|
||
//APB1 timer clock = 84 MHz, prescaler 84 -> 1 MHz (1 us per tick).
|
||
//APB1 <20><>ʱ<EFBFBD><CAB1>ʱ<EFBFBD><CAB1> 84MHz<48><7A>Ԥ<EFBFBD><D4A4>Ƶ 84 -> 1MHz<48><7A>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD> 1us<75><73>
|
||
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
|
||
TIM_TimeBaseStructure.TIM_Prescaler = 84 - 1;
|
||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||
TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure);
|
||
|
||
TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
|
||
TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
|
||
|
||
//Keep the overflow ISR below configMAX_SYSCALL_INTERRUPT_PRIORITY so it
|
||
//never calls FreeRTOS APIs; it only bumps a counter.
|
||
//<2F>жϲ<D0B6><CFB2><EFBFBD><EFBFBD><EFBFBD> FreeRTOS API<50><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC>ϵͣ<CFB5><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF>ơ<EFBFBD>
|
||
NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
|
||
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
|
||
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
||
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
||
NVIC_Init(&NVIC_InitStructure);
|
||
|
||
TIM_Cmd(TIM7, ENABLE);
|
||
}
|
||
|
||
void TIM7_IRQHandler(void)
|
||
{
|
||
if(TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET)
|
||
{
|
||
TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
|
||
g_time_high++;
|
||
}
|
||
}
|
||
|
||
/**************************************************************************
|
||
Function: Read the 64-bit monotonic microsecond timestamp
|
||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>ȡ 64λ<34><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><CEA2>ʱ<EFBFBD><CAB1><EFBFBD>
|
||
Glitch-free composition: re-read the high word around CNT and, if the
|
||
update flag is pending while CNT is still low, account for the overflow
|
||
that the ISR has not serviced yet.
|
||
<EFBFBD><EFBFBD>ֹ<EFBFBD><EFBFBD>϶<EFBFBD><EFBFBD><EFBFBD>ѣ<EFBFBD><EFBFBD><EFBFBD> CNT <20><>Χ<EFBFBD><CEA7><EFBFBD>ζ<EFBFBD><CEB6>߰<EFBFBD><DFB0>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ط<EFBFBD><D8B7><EFBFBD><EFBFBD><EFBFBD> CNT <20><>ϵ<EFBFBD>ͣ<EFBFBD>
|
||
˵<EFBFBD><EFBFBD> ISR <20><>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD>ûأ<C3BB><D8A3>ֶ<EFBFBD><D6B6><EFBFBD>λ<EFBFBD><CEBB>
|
||
**************************************************************************/
|
||
uint64_t mcu_time_us(void)
|
||
{
|
||
uint32_t high1, high2, cnt, sr;
|
||
|
||
do {
|
||
high1 = g_time_high;
|
||
cnt = TIM7->CNT;
|
||
sr = TIM7->SR;
|
||
high2 = g_time_high;
|
||
} while(high1 != high2);
|
||
|
||
//Overflow happened but the update ISR has not run yet.
|
||
//<2F>ѻ<EFBFBD><D1BB>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>¸<EFBFBD><C2B8>ж<EFBFBD><D0B6><EFBFBD>δִ<CEB4>С<EFBFBD>
|
||
if((sr & TIM_SR_UIF) && cnt < 0x8000U)
|
||
high1++;
|
||
|
||
return ((uint64_t)high1 << 16) | cnt;
|
||
}
|
||
|