Files
origincar_controller/HARDWARE/timer.c
cyy_mac 93ca37e36c 完善阿克曼控制与高速串口遥测
- 校正舵机中位、转向符号和阿克曼后轮差速模型\n- 增加航向角速度辅助及遥控通道调试开关\n- 将速度环提升至 200Hz,并按实际 dt 计算 PI 积分\n- 将 IMU 启动校准缩短为 2 秒\n- 为 USART3 增加 DMA 发送和 MCU 采样时间戳
2026-08-12 18:51:48 +08:00

554 lines
27 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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><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><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><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><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;
}