完善阿克曼控制与高速串口遥测

- 校正舵机中位、转向符号和阿克曼后轮差速模型\n- 增加航向角速度辅助及遥控通道调试开关\n- 将速度环提升至 200Hz,并按实际 dt 计算 PI 积分\n- 将 IMU 启动校准缩短为 2 秒\n- 为 USART3 增加 DMA 发送和 MCU 采样时间戳
This commit is contained in:
cyy_mac
2026-08-12 18:51:48 +08:00
parent 576784bb4d
commit 93ca37e36c
17 changed files with 2151 additions and 932 deletions

View File

@@ -13,14 +13,14 @@
#define FLASH_MEM_START ((void*)0x1800)
#define q30 1073741824.0f
short gyro[3], accel[3], sensors;
//零点漂移计数
//<EFBFBD><EFBFBD><EFBFBD>Ư<EFBFBD>Ƽ<EFBFBD><EFBFBD><EFBFBD>
int Deviation_Count;
short sum_gyro[3];
short sum_accel[3];
// Gyro static error, raw data
//陀螺仪静差,原始数据
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><EFBFBD>ԭʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
short Deviation_gyro[3],Original_gyro[3];
short Deviation_accel[3],Original_accel[3];
float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f;
@@ -55,11 +55,11 @@ void MPU6050_task(void *pvParameters)
while(1)
{
//This task runs at 100Hz
//此任务以100Hz的频率运行
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>100Hz<EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
vTaskDelayUntil(&lastWakeTime, F2T(RATE_100_HZ));
//Read the gyroscope zero before starting
//开机前,读取陀螺仪零点
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(Deviation_Count<CONTROL_DELAY)
{
Deviation_Count++;
@@ -78,10 +78,14 @@ void MPU6050_task(void *pvParameters)
memcpy(Deviation_accel,accel,sizeof(accel));
}
MPU_Get_Gyroscope(); //得到陀螺仪数据
MPU_Get_Accelscope(); //获得加速度计值(原始值)
//Stamp just before the I2C burst read, as close to the physical IMU
//sample as we can get without a data-ready interrupt.
//<2F><> I2C <20><>ȡǰ<C8A1><C7B0>㣬<EFBFBD>ھ<EFBFBD><DABE><EFBFBD> DRDY <20>жϵ<D0B6><CFB5><EFBFBD><EFBFBD><EFBFBD>¾<EFBFBD><C2BE><EFBFBD><EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>̡<EFBFBD>
g_imu_sample_time_us = mcu_time_us();
MPU_Get_Gyroscope(); //<2F>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
MPU_Get_Accelscope(); //<2F><>ü<EFBFBD><C3BC>ٶȼ<D9B6>ֵ(ԭʼֵ)
}
}
}
//static unsigned short inv_orientation_matrix_to_scalar(
// const signed char *mtx)
@@ -132,17 +136,17 @@ int16_t Gx_offset=0,Gy_offset=0,Gz_offset=0;
/**************************************************************************
Function: The new ADC data is updated to FIFO array for filtering
Input : ax,ay,az:x,y, z-axis acceleration data;gx,gy,gz:x. Y, z-axis angular acceleration data
Input : ax<EFBFBD><EFBFBD>ay<EFBFBD><EFBFBD>az<EFBFBD><EFBFBD>x<EFBFBD><EFBFBD>y, z-axis acceleration data<EFBFBD><EFBFBD>gx<EFBFBD><EFBFBD>gy<EFBFBD><EFBFBD>gz<EFBFBD><EFBFBD>x. Y, z-axis angular acceleration data
Output : none
函数功能:将新的ADC数据更新到 FIFO数组,进行滤波处理
入口参数:ax,ay,az:x,y,z轴加速度数据;gx,gy,gz:x,y,z轴角加速度数据
返回 值:无
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>ADC<EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD><EFBFBD>µ<EFBFBD> FIFO<46><4F><EFBFBD>飬<EFBFBD><E9A3AC><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ax<EFBFBD><EFBFBD>ay<EFBFBD><EFBFBD>az<EFBFBD><EFBFBD>x<EFBFBD><EFBFBD>y<EFBFBD><EFBFBD>z<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>gx<EFBFBD><EFBFBD>gy<EFBFBD><EFBFBD>gz<EFBFBD><EFBFBD>x<EFBFBD><EFBFBD>y<EFBFBD><EFBFBD>z<EFBFBD><EFBFBD>Ǽ<EFBFBD><EFBFBD>ٶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5><EFBFBD><EFBFBD>
**************************************************************************/
void MPU6050_newValues(int16_t ax,int16_t ay,int16_t az,int16_t gx,int16_t gy,int16_t gz)
{
unsigned char i ;
int32_t sum=0;
for(i=1;i<10;i++){ //FIFO 操作
for(i=1;i<10;i++){ //FIFO <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
MPU6050_FIFO[0][i-1]=MPU6050_FIFO[0][i];
MPU6050_FIFO[1][i-1]=MPU6050_FIFO[1][i];
MPU6050_FIFO[2][i-1]=MPU6050_FIFO[2][i];
@@ -150,7 +154,7 @@ MPU6050_FIFO[3][i-1]=MPU6050_FIFO[3][i];
MPU6050_FIFO[4][i-1]=MPU6050_FIFO[4][i];
MPU6050_FIFO[5][i-1]=MPU6050_FIFO[5][i];
}
MPU6050_FIFO[0][9]=ax;//将新的数据放置到 数据的最后面
MPU6050_FIFO[0][9]=ax;//<EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݷ<EFBFBD><EFBFBD>õ<EFBFBD> <20><><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
MPU6050_FIFO[1][9]=ay;
MPU6050_FIFO[2][9]=az;
MPU6050_FIFO[3][9]=gx;
@@ -158,7 +162,7 @@ MPU6050_FIFO[4][9]=gy;
MPU6050_FIFO[5][9]=gz;
sum=0;
for(i=0;i<10;i++){ //求当前数组的合,再取平均值
for(i=0;i<10;i++){ //<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĺϣ<EFBFBD><EFBFBD><EFBFBD>ȡƽ<EFBFBD><EFBFBD>ֵ
sum+=MPU6050_FIFO[0][i];
}
MPU6050_FIFO[0][10]=sum/10;
@@ -196,11 +200,11 @@ MPU6050_FIFO[5][10]=sum/10;
/**************************************************************************
Function: Setting the clock source of mpu6050
Input : source:Clock source number
Input : source<EFBFBD><EFBFBD>Clock source number
Output : none
函数功能:设置 MPU6050 的时钟源
入口参数:source:时钟源编号
返回 值:无
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MPU6050 <EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>Դ
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>source<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5><EFBFBD><EFBFBD>
* CLK_SEL | Clock Source
* --------+--------------------------------------
* 0 | Internal oscillator
@@ -231,27 +235,27 @@ void MPU6050_setFullScaleGyroRange(uint8_t range) {
/**************************************************************************
Function: Setting the maximum range of mpu6050 accelerometer
Input : range:Acceleration maximum range number
Input : range<EFBFBD><EFBFBD>Acceleration maximum range number
Output : none
函数功能:设置 MPU6050 加速度计的最大量程
入口参数:range:加速度最大量程编号
返回 值:无
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MPU6050 <20><><EFBFBD>ٶȼƵ<C8BC><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>range<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̱<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5><EFBFBD><EFBFBD>
**************************************************************************/
//#define MPU6050_ACCEL_FS_2 0x00 //===最大量程+-2G
//#define MPU6050_ACCEL_FS_4 0x01 //===最大量程+-4G
//#define MPU6050_ACCEL_FS_8 0x02 //===最大量程+-8G
//#define MPU6050_ACCEL_FS_16 0x03 //===最大量程+-16G
//#define MPU6050_ACCEL_FS_2 0x00 //===<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+-2G
//#define MPU6050_ACCEL_FS_4 0x01 //===<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+-4G
//#define MPU6050_ACCEL_FS_8 0x02 //===<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+-8G
//#define MPU6050_ACCEL_FS_16 0x03 //===<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+-16G
void MPU6050_setFullScaleAccelRange(uint8_t range) {
I2C_WriteBits(devAddr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, range);
}
/**************************************************************************
Function: Set mpu6050 to sleep mode or not
Input : enable:1,sleep;0,work;
Input : enable<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>sleep<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>work<EFBFBD><EFBFBD>
Output : none
函数功能:设置 MPU6050 是否进入睡眠模式
入口参数:enable:1,睡觉;0,工作;
返回 值:无
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MPU6050 <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>˯<EFBFBD><CBAF>ģʽ
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>enable<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>˯<EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5><EFBFBD><EFBFBD>
**************************************************************************/
void MPU6050_setSleepEnabled(uint8_t enabled) {
I2C_WriteOneBit(devAddr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, enabled);
@@ -261,9 +265,9 @@ void MPU6050_setSleepEnabled(uint8_t enabled) {
Function: Read identity
Input : none
Output : 0x68
函数功能:读取 MPU6050 WHO_AM_I 标识
入口参数:无
返回 值:0x68
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>ȡ MPU6050 WHO_AM_I <EFBFBD><EFBFBD>ʶ
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5>0x68
**************************************************************************/
uint8_t MPU6050_getDeviceID(void) {
@@ -277,10 +281,10 @@ uint8_t MPU6050_getDeviceID(void) {
/**************************************************************************
Function: Check whether mpu6050 is connected
Input : none
Output : 1:Connected;0:Not connected
函数功能:检测MPU6050 是否已经连接
入口参数:无
返回 值:1:已连接;0:未连接
Output : 1<EFBFBD><EFBFBD>Connected<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>Not connected
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>MPU6050 <20>Ƿ<EFBFBD><C7B7>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>0<EFBFBD><30>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>
**************************************************************************/
uint8_t MPU6050_testConnection(void) {
if(MPU6050_getDeviceID() == 0x68) //0b01101000;
@@ -290,11 +294,11 @@ uint8_t MPU6050_testConnection(void) {
/**************************************************************************
Function: Setting whether mpu6050 is the host of aux I2C cable
Input : enable:1,yes;0;not
Input : enable<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>yes<EFBFBD><EFBFBD>0;not
Output : none
函数功能:设置 MPU6050 是否为AUX I2C线的主机
入口参数:enable:1,是;0:否
返回 值:无
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MPU6050 <EFBFBD>Ƿ<EFBFBD>ΪAUX I2C<EFBFBD>ߵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>enable<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD>0<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5><EFBFBD><EFBFBD>
**************************************************************************/
void MPU6050_setI2CMasterModeEnabled(uint8_t enabled) {
I2C_WriteOneBit(devAddr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_MST_EN_BIT, enabled);
@@ -302,11 +306,11 @@ void MPU6050_setI2CMasterModeEnabled(uint8_t enabled) {
/**************************************************************************
Function: Setting whether mpu6050 is the host of aux I2C cable
Input : enable:1,yes;0;not
Input : enable<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>yes<EFBFBD><EFBFBD>0;not
Output : none
函数功能:设置 MPU6050 是否为AUX I2C线的主机
入口参数:enable:1,是;0:否
返回 值:无
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MPU6050 <EFBFBD>Ƿ<EFBFBD>ΪAUX I2C<EFBFBD>ߵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>enable<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD>0<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5><EFBFBD><EFBFBD>
**************************************************************************/
void MPU6050_setI2CBypassEnabled(uint8_t enabled) {
I2C_WriteOneBit(devAddr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_I2C_BYPASS_EN_BIT, enabled);
@@ -316,38 +320,38 @@ void MPU6050_setI2CBypassEnabled(uint8_t enabled) {
Function: initialization Mpu6050 to enter the available state
Input : none
Output : none
函数功能:初始化 MPU6050 以进入可用状态
入口参数:无
返回 值:无
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD> MPU6050 <20>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5><EFBFBD><EFBFBD>
**************************************************************************/
u8 MPU6050_initialize(void)
{
u8 res;
//IIC_Init(); //Initialize the IIC bus //初始化IIC总线
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_1,0X80); //Reset MPUrobot_select_init.h //复位MPUrobot_select_init.h
delay_ms(200); //Delay 200 ms //延时200ms
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_1,0X00); //Wake mpurobot_select_init.h //唤醒MPUrobot_select_init.h
//IIC_Init(); //Initialize the IIC bus //<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>IIC<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_1,0X80); //Reset MPUrobot_select_init.h //<EFBFBD><EFBFBD>λMPUrobot_select_init.h
delay_ms(200); //Delay 200 ms //<EFBFBD><EFBFBD>ʱ200ms
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_1,0X00); //Wake mpurobot_select_init.h //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>MPUrobot_select_init.h
//MPU6050_Set_Gyro_Fsr(1); //Gyroscope sensor //陀螺仪传感器,±500dps=±500°/s ±32768 (gyro/32768*500)*PI/180(rad/s)=gyro/3754.9(rad/s)
//MPU6050_Set_Gyro_Fsr(1); //Gyroscope sensor //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>500dps=<EFBFBD><EFBFBD>500<EFBFBD><EFBFBD>/s <EFBFBD><EFBFBD>32768 (gyro/32768*500)*PI/180(rad/s)=gyro/3754.9(rad/s)
MPU6050_setFullScaleGyroRange(MPU6050_GYRO_FS_500);
//MPU6050_Set_Accel_Fsr(0); //Acceleration sensor //加速度传感器,±2g=±2*9.8m/s^2 ±32768 accel/32768*19.6=accel/1671.84
//MPU6050_Set_Accel_Fsr(0); //Acceleration sensor //<EFBFBD><EFBFBD><EFBFBD>ٶȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>2g=<EFBFBD><EFBFBD>2*9.8m/s^2 <EFBFBD><EFBFBD>32768 accel/32768*19.6=accel/1671.84
MPU6050_setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
MPU6050_Set_Rate(50); //Set the sampling rate to 50Hz //设置采样率50Hz
MPU6050_Set_Rate(50); //Set the sampling rate to 50Hz //<EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>50Hz
I2C_WriteOneByte(devAddr,MPU6050_RA_INT_ENABLE,0X00); //Turn off all interrupts //关闭所有中断
I2C_WriteOneByte(devAddr,MPU6050_RA_USER_CTRL,0X00); //The I2C main mode is off //I2C主模式关闭
I2C_WriteOneByte(devAddr,MPU6050_RA_FIFO_EN,0X00); //Close the FIFO //关闭FIFO
I2C_WriteOneByte(devAddr,MPU6050_RA_INT_ENABLE,0X00); //Turn off all interrupts //<EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
I2C_WriteOneByte(devAddr,MPU6050_RA_USER_CTRL,0X00); //The I2C main mode is off //I2C<EFBFBD><EFBFBD>ģʽ<EFBFBD>ر<EFBFBD>
I2C_WriteOneByte(devAddr,MPU6050_RA_FIFO_EN,0X00); //Close the FIFO //<EFBFBD>ر<EFBFBD>FIFO
//The INT pin is low, enabling bypass mode to read the magnetometer directly
//INT引脚低电平有效,开启bypass模式,可以直接读取磁力计
//INT<EFBFBD><EFBFBD><EFBFBD>ŵ͵<EFBFBD>ƽ<EFBFBD><EFBFBD>Ч<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>bypassģʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>Ӷ<EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
I2C_WriteOneByte(devAddr,MPU6050_RA_INT_PIN_CFG,0X80);
//Read the ID of MPU6050
//读取MPU6050的ID
//<EFBFBD><EFBFBD>ȡMPU6050<EFBFBD><EFBFBD>ID
res=I2C_ReadOneByte(devAddr,MPU6050_RA_WHO_AM_I);
if(res==MPU6050_DEFAULT_ADDRESS) //The device ID is correct, The correct device ID depends on the AD pin //器件ID正确, 器件ID的正确取决于AD引脚
if(res==MPU6050_DEFAULT_ADDRESS) //The device ID is correct, The correct device ID depends on the AD pin //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID<EFBFBD><EFBFBD>ȷ, <20><><EFBFBD><EFBFBD>ID<49><44><EFBFBD><EFBFBD>ȷȡ<C8B7><C8A1><EFBFBD><EFBFBD>AD<41><44><EFBFBD><EFBFBD>
{
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_1,0X01); //Set CLKSEL,PLL X axis as reference //设置CLKSEL,PLL X轴为参考
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_2,0X00); //Acceleration and gyroscope both work //加速度与陀螺仪都工作
MPU6050_Set_Rate(50); //Set the sampling rate to 50Hz //设置采样率为50Hz
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_1,0X01); //Set CLKSEL,PLL X axis as reference //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>CLKSEL,PLL X<EFBFBD><EFBFBD>Ϊ<EFBFBD>ο<EFBFBD>
I2C_WriteOneByte(devAddr,MPU6050_RA_PWR_MGMT_2,0X00); //Acceleration and gyroscope both work //<EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
MPU6050_Set_Rate(50); //Set the sampling rate to 50Hz //<EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ50Hz
}else return 1;
return 0;
@@ -357,9 +361,9 @@ u8 MPU6050_initialize(void)
Function: Initialization of DMP in mpu6050
Input : none
Output : none
函数功能:MPU6050内置DMP的初始化
入口参数:无
返回 值:无
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD>MPU6050<EFBFBD><EFBFBD><EFBFBD><EFBFBD>DMP<EFBFBD>ij<EFBFBD>ʼ<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5><EFBFBD><EFBFBD>
**************************************************************************/
//void DMP_Init(void)
//{
@@ -395,9 +399,9 @@ Output : none
Function: Read the attitude information of DMP in mpu6050
Input : none
Output : none
函数功能:读取MPU6050内置DMP的姿态信息
入口参数:无
返回 值:无
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>ȡMPU6050<EFBFBD><EFBFBD><EFBFBD><EFBFBD>DMP<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD>Ϣ
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5><EFBFBD><EFBFBD>
**************************************************************************/
//void Read_DMP(void)
//{
@@ -405,16 +409,16 @@ Output : none
// unsigned char more;
// long quat[4];
// dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors, &more); //读取DMP数据
// dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors, &more); //<EFBFBD><EFBFBD>ȡDMP<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// if (sensors & INV_WXYZ_QUAT )
// {
// q0=quat[0] / q30;
// q1=quat[1] / q30;
// q2=quat[2] / q30;
// q3=quat[3] / q30; //四元数
// Roll = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; //计算出横滚角
// Pitch = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // 计算出俯仰角
// Yaw = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3; //计算出偏航角
// q3=quat[3] / q30; //<EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD>
// Roll = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Pitch = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Yaw = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3; //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// }
//}
@@ -422,16 +426,16 @@ Output : none
Function: Read mpu6050 built-in temperature sensor data
Input : none
Output : Centigrade temperature
函数功能:读取MPU6050内置温度传感器数据
入口参数:无
返回 值:摄氏温度
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>ȡMPU6050<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> ֵ<><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
**************************************************************************/
int Read_Temperature(void)
{
float Temp;
Temp=(I2C_ReadOneByte(devAddr,MPU6050_RA_TEMP_OUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_TEMP_OUT_L);
if(Temp>32768) Temp-=65536; //数据类型转换
Temp=(36.53f+Temp/340)*10; //温度放大十倍存放
if(Temp>32768) Temp-=65536; //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>
Temp=(36.53f+Temp/340)*10; //<EFBFBD>¶ȷŴ<EFBFBD>ʮ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return (int)Temp;
}
@@ -439,9 +443,9 @@ int Read_Temperature(void)
Function: Initialize TIM2 as the encoder interface mode
Input : LPF: Digital low-pass filtering frequency (Hz)
Output : 0: Settings successful, others: Settings failed
函数功能:设置MPUrobot_select_init.h的数字低通滤波器
入口参数:lpf:数字低通滤波频率(Hz)
返回 值:0:设置成功, 其他:设置失败
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MPUrobot_select_init.h<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>ͨ<EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>lpf:<3A><><EFBFBD>ֵ<EFBFBD>ͨ<EFBFBD>˲<EFBFBD>Ƶ<EFBFBD><C6B5>(Hz)
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5>0:<3A><><EFBFBD>óɹ<C3B3>, <20><><EFBFBD><EFBFBD>:<3A><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
**************************************************************************/
unsigned char MPU6050_Set_LPF(u16 lpf)
{
@@ -452,15 +456,15 @@ unsigned char MPU6050_Set_LPF(u16 lpf)
else if(lpf>=20)data=4;
else if(lpf>=10)data=5;
else data=6;
return I2C_WriteOneByte(devAddr,MPU6050_RA_CONFIG,data); //Set the digital lowpass filter//设置数字低通滤波器
return I2C_WriteOneByte(devAddr,MPU6050_RA_CONFIG,data); //Set the digital lowpass filter//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>ͨ<EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD>
}
/**************************************************************************
Function: Initialize TIM2 as the encoder interface mode
Input : rate:4~1000(Hz)
Output : 0: Settings successful, others: Settings failed
函数功能:设置MPUrobot_select_init.h的采样率(假定Fs=1KHz)
入口参数:rate:4~1000(Hz)
返回 值:0:设置成功, 其他:设置失败
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MPUrobot_select_init.h<EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>ٶ<EFBFBD>Fs=1KHz)
<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>rate:4~1000(Hz)
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ֵ<><D6B5>0:<3A><><EFBFBD>óɹ<C3B3>, <20><><EFBFBD><EFBFBD>:<3A><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
**************************************************************************/
unsigned char MPU6050_Set_Rate(u16 rate)
{
@@ -468,42 +472,42 @@ unsigned char MPU6050_Set_Rate(u16 rate)
if(rate>1000)rate=1000;
if(rate<4)rate=4;
data=1000/rate-1;
data=I2C_WriteOneByte(devAddr,MPU6050_RA_SMPLRT_DIV,data); //Set the digital lowpass filter//设置数字低通滤波器
return MPU6050_Set_LPF(rate/2); //Automatically sets LPF to half of the sampling rate //自动设置LPF为采样率的一半
data=I2C_WriteOneByte(devAddr,MPU6050_RA_SMPLRT_DIV,data); //Set the digital lowpass filter//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>ͨ<EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD>
return MPU6050_Set_LPF(rate/2); //Automatically sets LPF to half of the sampling rate //<EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>LPFΪ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>һ<EFBFBD><EFBFBD>
}
/**************************************************************************
Function: Initialize TIM2 as the encoder interface mode
Input : Gx, Gy, Gz: raw readings (plus or minus) of the x,y, and z axes of the gyroscope
Output : 0: success, others: error code
函数功能:获得陀螺仪值(原始值)
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ(ԭʼֵ)
**************************************************************************/
void MPU_Get_Gyroscope(void)
{
gyro[0]=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_XOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_XOUT_L); //读取X轴陀螺仪
gyro[1]=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_YOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_YOUT_L); //读取Y轴陀螺仪
gyro[2]=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_L); //读取Z轴陀螺仪
gyro[0]=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_XOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_XOUT_L); //<EFBFBD><EFBFBD>ȡX<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
gyro[1]=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_YOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_YOUT_L); //<EFBFBD><EFBFBD>ȡY<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
gyro[2]=(I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_GYRO_ZOUT_L); //<EFBFBD><EFBFBD>ȡZ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(Deviation_Count<CONTROL_DELAY) // 10 seconds before starting //开机前10秒
if(Deviation_Count<CONTROL_DELAY) // 10 seconds before starting //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ10<EFBFBD><EFBFBD>
{
Led_Count=1; //LED high frequency flashing //LED高频闪烁
Flag_Stop=1; //The software fails to flag location 1 //软件失能标志位置1
Led_Count=1; //LED high frequency flashing //LED<EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD>˸
Flag_Stop=1; //The software fails to flag location 1 //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܱ<EFBFBD>־λ<EFBFBD><EFBFBD>1
}
else //10 seconds after starting //开机10秒后
else //10 seconds after starting //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>10<EFBFBD><EFBFBD><EFBFBD>
{
if(Deviation_Count==CONTROL_DELAY)
Flag_Stop=0; //The software fails to flag location 0 //软件失能标志位置0
Led_Count=300; //The LED returns to normal flicker frequency //LED恢复正常闪烁频率
Flag_Stop=0; //The software fails to flag location 0 //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܱ<EFBFBD>־λ<EFBFBD><EFBFBD>0
Led_Count=300; //The LED returns to normal flicker frequency //LED<EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˸Ƶ<EFBFBD><EFBFBD>
//Save the raw data to update zero by clicking the user button
//保存原始数据用于单击用户按键更新零点
//<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>
Original_gyro[0] =gyro[0];
Original_gyro[1] =gyro[1];
Original_gyro[2]= gyro[2];
//Removes zero drift data
//去除零点漂移的数据
//ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ư<EFBFBD>Ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
gyro[0] =Original_gyro[0]-Deviation_gyro[0];
gyro[1] =Original_gyro[1]-Deviation_gyro[1];
gyro[2]= Original_gyro[2]-Deviation_gyro[2];
@@ -514,28 +518,28 @@ void MPU_Get_Gyroscope(void)
Function: Initialize TIM2 as the encoder interface mode
Input : Gx, Gy, Gz: raw readings (plus or minus) of the x,y, and z axes of the gyroscope
Output : 0: success, others: error code
函数功能:获得加速度计值(原始值)
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD>ü<EFBFBD><EFBFBD>ٶȼ<EFBFBD>ֵ(ԭʼֵ)
**************************************************************************/
void MPU_Get_Accelscope(void)
{
accel[0]=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_XOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_XOUT_L); //读取X轴加速度计
accel[1]=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_YOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_YOUT_L); //读取X轴加速度计
accel[2]=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_ZOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_ZOUT_L); //读取Z轴加速度计
accel[0]=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_XOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_XOUT_L); //<EFBFBD><EFBFBD>ȡX<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶȼ<EFBFBD>
accel[1]=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_YOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_YOUT_L); //<EFBFBD><EFBFBD>ȡX<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶȼ<EFBFBD>
accel[2]=(I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_ZOUT_H)<<8)+I2C_ReadOneByte(devAddr,MPU6050_RA_ACCEL_ZOUT_L); //<EFBFBD><EFBFBD>ȡZ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶȼ<EFBFBD>
if(Deviation_Count<CONTROL_DELAY) // 10 seconds before starting //开机前10秒
if(Deviation_Count<CONTROL_DELAY) // 10 seconds before starting //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ10<EFBFBD><EFBFBD>
{
}
else //10 seconds after starting //开机10秒后
else //10 seconds after starting //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>10<EFBFBD><EFBFBD><EFBFBD>
{
//Save the raw data to update zero by clicking the user button
//保存原始数据用于单击用户按键更新零点
//<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>
Original_accel[0] =accel[0];
Original_accel[1] =accel[1];
Original_accel[2]= accel[2];
//Removes zero drift data
//去除零点漂移的数据
//ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ư<EFBFBD>Ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
accel[0] =Original_accel[0]-Deviation_accel[0];
accel[1] =Original_accel[1]-Deviation_accel[1];
accel[2]= Original_accel[2]-Deviation_accel[2]+16384;

View File

@@ -49,7 +49,7 @@
#define EN PDin(3)
#define Servo_PWM TIM12->CCR2
#define SERVO_INIT 1590 //Servo zero point //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define SERVO_INIT 1670 //Servo straight-ahead point (calibrated 1/R~=0) //<2F><>ֱ<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD>
void Enable_Pin(void);
void Servo_PWM_Init(u16 arr,u16 psc);

View File

@@ -2,28 +2,28 @@
//Input the capture flag for channel 1,
//the capture flag for the higher bits, and the overflow flag for the lower 6 bits
//通道1输入捕获标志,高两位做捕获标志,低6位做溢出标志
//ͨ<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD>벶<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>6λ<EFBFBD><EFBFBD><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
//通道2输入捕获标志,高两位做捕获标志,低6位做溢出标志
//ͨ<EFBFBD><EFBFBD>2<EFBFBD><EFBFBD><EFBFBD>벶<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>6λ<EFBFBD><EFBFBD><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
//通道3输入捕获标志,高两位做捕获标志,低6位做溢出标志
//ͨ<EFBFBD><EFBFBD>3<EFBFBD><EFBFBD><EFBFBD>벶<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>6λ<EFBFBD><EFBFBD><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
//通道4输入捕获标志,高两位做捕获标志,低6位做溢出标志
//ͨ<EFBFBD><EFBFBD>4<EFBFBD><EFBFBD><EFBFBD>벶<EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD>6λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
u8 TIM8CH4_CAPTURE_STA = 0;
u16 TIM8CH4_CAPTURE_UPVAL;
u16 TIM8CH4_CAPTURE_DOWNVAL;
@@ -34,19 +34,19 @@ u32 TIM8_T3;
u32 TIM8_T4;
//Variables related to remote control acquisition of model aircraft
//航模遥控采集相关变量
//<EFBFBD><EFBFBD>ģң<EFBFBD>زɼ<EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD>
int Remoter_Ch1=1500,Remoter_Ch2=1500,Remoter_Ch3=1500,Remoter_Ch4=1500;
//Model aircraft remote control receiver variable
//航模遥控接收变量
//<EFBFBD><EFBFBD>ģң<EFBFBD>ؽ<EFBFBD><EFBFBD>ձ<EFBFBD><EFBFBD><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
函数功能:航模遥控初始化函数,定时器1输入捕获初始化
入口参数:arr:自动重装值,psc:时钟预分频数
返 回 值:无
<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)
{
@@ -55,14 +55,14 @@ void TIM8_Cap_Init(u16 arr, u16 psc)
NVIC_InitTypeDef NVIC_InitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM1时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能PORTE时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM1ʱ<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //ʹ<EFBFBD><EFBFBD>PORTEʱ<EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; //GPIOC
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//<EFBFBD><EFBFBD><EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //<EFBFBD>ٶ<EFBFBD>100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //<EFBFBD><EFBFBD><EFBFBD>츴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8);
@@ -70,104 +70,104 @@ void TIM8_Cap_Init(u16 arr, u16 psc)
GPIO_PinAFConfig(GPIOC,GPIO_PinSource8,GPIO_AF_TIM8);
GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_TIM8);
/*** Initialize timer 1 || 初始化定时器1 ***/
//Set the counter to automatically reload //设定计数器自动重装值
/*** Initialize timer 1 || <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>1 ***/
//Set the counter to automatically reload //<EFBFBD>趨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD>װֵ
TIM_TimeBaseStructure.TIM_Period = arr;
//Pre-divider //预分频器
//Pre-divider //Ԥ<EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD>
TIM_TimeBaseStructure.TIM_Prescaler = psc;
//Set the clock split: TDTS = Tck_tim //设置时钟分割:TDTS = Tck_tim
//Set the clock split: TDTS = Tck_tim //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ӷָ<EFBFBD>:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
//TIM up count mode //TIM向上计数模式
//TIM up count mode //TIM<EFBFBD><EFBFBD><EFBFBD>ϼ<EFBFBD><EFBFBD><EFBFBD>ģʽ
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//Initializes the timebase unit for TIMX based on the parameter specified in TIM_TimeBaseInitStruct
//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>TIM_TimeBaseInitStruct<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>TIMx<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
/*** 初始化TIM1输入捕获参数,通道1 || Initialize TIM1 for the capture parameter, channel 1 ***/
//Select input //选择输入端
/*** <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>TIM1<EFBFBD><EFBFBD><EFBFBD>벶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>1 || Initialize TIM1 for the capture parameter, channel 1 ***/
//Select input //ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
//Rising edge capture //上升沿捕获
//Rising edge capture //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
//Configure input frequency division, regardless of frequency //配置输入分频,不分频
//Configure input frequency division, regardless of frequency //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ,<2C><><EFBFBD><EFBFBD>Ƶ
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
//IC1F=0000 Configure input filter //配置输入滤波器
//IC1F=0000 Configure input filter //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD>
TIM_ICInitStructure.TIM_ICFilter = 0x0F;
TIM_ICInit(TIM8, &TIM_ICInitStructure);
/*** 初始化TIM1输入捕获参数,通道2 || Initialize TIM1 for the capture parameter, channel 2 ***/
//CC1S=01 Select input //选择输入端
/*** <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>TIM1<EFBFBD><EFBFBD><EFBFBD>벶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>2 || Initialize TIM1 for the capture parameter, channel 2 ***/
//CC1S=01 Select input //ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
//Rising edge capture //上升沿捕获
//Rising edge capture //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
//Configure input frequency division, regardless of frequency //配置输入分频,不分频
//Configure input frequency division, regardless of frequency //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ,<2C><><EFBFBD><EFBFBD>Ƶ
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x00; //IC1F=0000 配置输入滤波器
TIM_ICInitStructure.TIM_ICFilter = 0x00; //IC1F=0000 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD>
TIM_ICInit(TIM8, &TIM_ICInitStructure);
/*** 初始化TIM1输入捕获参数,通道3 || Initialize TIM1 for the capture parameter, channel 3 ***/
//Select input //选择输入端
/*** <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>TIM1<EFBFBD><EFBFBD><EFBFBD>벶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>3 || Initialize TIM1 for the capture parameter, channel 3 ***/
//Select input //ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
//Rising edge capture //上升沿捕获
//Rising edge capture //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
//Configure input frequency division, regardless of frequency //配置输入分频,不分频
//Configure input frequency division, regardless of frequency //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ,<2C><><EFBFBD><EFBFBD>Ƶ
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
//IC1F=0000 Configure input filter //配置输入滤波器,不滤波
//IC1F=0000 Configure input filter //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD>
TIM_ICInitStructure.TIM_ICFilter = 0x00;
TIM_ICInit(TIM8, &TIM_ICInitStructure);
/*** 初始化TIM1输入捕获参数,通道4 || Initialize TIM1 for the capture parameter, channel 4 ***/
//Select input //选择输入端
/*** <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>TIM1<EFBFBD><EFBFBD><EFBFBD>벶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>4 || Initialize TIM1 for the capture parameter, channel 4 ***/
//Select input //ѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM_ICInitStructure.TIM_Channel = TIM_Channel_4;
//Rising edge capture //上升沿捕获
//Rising edge capture //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
//Configure input frequency division, regardless of frequency //配置输入分频,不分频
//Configure input frequency division, regardless of frequency //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ,<2C><><EFBFBD><EFBFBD>Ƶ
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
//IC1F=0000 Configure input filter //配置输入滤波器,不滤波
//IC1F=0000 Configure input filter //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD>
TIM_ICInitStructure.TIM_ICFilter = 0x00;
TIM_ICInit(TIM8, &TIM_ICInitStructure);
/*** interrupt packet initialization || 中断分组初始化 ***/
//TIM1 interrupts //TIM1中断
/*** interrupt packet initialization || <EFBFBD>жϷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD> ***/
//TIM1 interrupts //TIM1<EFBFBD>ж<EFBFBD>
NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn;
//Preempt priority 0 //先占优先级0级
//Preempt priority 0 //<EFBFBD><EFBFBD>ռ<EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>0<EFBFBD><EFBFBD>
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
//Level 0 from priority //从优先级0级
//Level 0 from priority //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>0<EFBFBD><EFBFBD>
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
//IRQ channels are enabled //IRQ通道被使能
//IRQ channels are enabled //IRQͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//Initializes the peripheral NVIC register according to the parameters specified in NVIC_InitStruct
//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>NVIC_InitStruct<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>NVIC<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>
NVIC_Init(&NVIC_InitStructure);
//Allow CC1IE,CC2IE,CC3IE,CC4IE to catch interrupts, not allowed update_interrupts
//不允许更新中断,允许CC1IE,CC2IE,CC3IE,CC4IE捕获中断
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CC1IE,CC2IE,CC3IE,CC4IE<EFBFBD><EFBFBD><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 //高级定时器输出必须使能这句
//Advanced timer output must be enabled //<EFBFBD>߼<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM_CtrlPWMOutputs(TIM8,ENABLE);
//Enable timer //使能定时器
//Enable timer //ʹ<EFBFBD>ܶ<EFBFBD>ʱ<EFBFBD><EFBFBD>
TIM_Cmd(TIM8, ENABLE);
}
/**************************************************************************
Function: Model aircraft remote control receiving interrupt, namely timer 8 input capture interrupt
Input : none
Output : none
函数功能:航模遥控接收中断,即定时器8输入捕获中断
入口参数:无
返 回 值:无
<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)
{
//连接航模遥遥控器后,需要推下前进杆,才可以正式航模控制小车
//<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>
//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
//航模遥控标志位置1,其它标志位置0
//<EFBFBD><EFBFBD>ģң<EFBFBD>ر<EFBFBD>־λ<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־λ<EFBFBD><EFBFBD>0
Remote_ON_Flag=1;
APP_ON_Flag=0;
PS2_ON_Flag=0;
@@ -179,131 +179,131 @@ void TIM8_CC_IRQHandler(void)
// //Channel 1 //通道一
// //Channel 1 //ͨ<EFBFBD><EFBFBD>һ
if ((TIM8CH1_CAPTURE_STA & 0X80) == 0)
{
if (TIM_GetITStatus(TIM8, TIM_IT_CC1) != RESET) //A capture event occurred on channel 1 //通道1发生捕获事件
if (TIM_GetITStatus(TIM8, TIM_IT_CC1) != RESET) //A capture event occurred on channel 1 //ͨ<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
{
TIM_ClearITPendingBit(TIM8, TIM_IT_CC1); //Clear the interrupt flag bit //清除中断标志位
if (TIM8CH1_CAPTURE_STA & 0X40) //A falling edge is caught //捕获到一个下降沿
TIM_ClearITPendingBit(TIM8, TIM_IT_CC1); //Clear the interrupt flag bit //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϱ<EFBFBD>־λ
if (TIM8CH1_CAPTURE_STA & 0X40) //A falling edge is caught //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><EFBFBD><EFBFBD>
{
TIM8CH1_CAPTURE_DOWNVAL = TIM_GetCapture1(TIM8); //Record the timer value at this point //记录下此时的定时器计数值
TIM8CH1_CAPTURE_DOWNVAL = TIM_GetCapture1(TIM8); //Record the timer value at this point //<EFBFBD><EFBFBD>¼<EFBFBD>´<EFBFBD>ʱ<EFBFBD>Ķ<EFBFBD>ʱ<EFBFBD><EFBFBD><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 //得到总的高电平的时间
if(abs(Remoter_Ch1-L_Remoter_Ch1)>500) Remoter_Ch1=L_Remoter_Ch1; //Filter //滤波
Remoter_Ch1 = TIM8CH1_CAPTURE_DOWNVAL - TIM8CH1_CAPTURE_UPVAL + TIM8_T1; //Time to get the total high level //<EFBFBD>õ<EFBFBD><EFBFBD>ܵĸߵ<EFBFBD>ƽ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
if(abs(Remoter_Ch1-L_Remoter_Ch1)>500) Remoter_Ch1=L_Remoter_Ch1; //Filter //<EFBFBD>˲<EFBFBD>
L_Remoter_Ch1=Remoter_Ch1;
TIM8CH1_CAPTURE_STA = 0; //Capture flag bit to zero //捕获标志位清零
TIM_OC1PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //设置为上升沿捕获
TIM8CH1_CAPTURE_STA = 0; //Capture flag bit to zero //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM_OC1PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><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
//发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
TIM8CH1_CAPTURE_UPVAL = TIM_GetCapture1(TIM8); //Obtain rising edge data //获取上升沿数据
TIM8CH1_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //标记已捕获到上升沿
TIM_OC1PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //设置为下降沿捕获
//<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>Ķ<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
TIM8CH1_CAPTURE_UPVAL = TIM_GetCapture1(TIM8); //Obtain rising edge data //<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM8CH1_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM_OC1PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>½<EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>
}
}
}
//Channel 2 //通道二
//Channel 2 //ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ((TIM8CH2_CAPTURE_STA & 0X80) == 0)
{
if (TIM_GetITStatus(TIM8, TIM_IT_CC2) != RESET) //A capture event occurred on channel 2 //通道2发生捕获事件
if (TIM_GetITStatus(TIM8, TIM_IT_CC2) != RESET) //A capture event occurred on channel 2 //ͨ<EFBFBD><EFBFBD>2<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
{
TIM_ClearITPendingBit(TIM8, TIM_IT_CC2); //Clear the interrupt flag bit //清除中断标志位
if (TIM8CH2_CAPTURE_STA & 0X40) //A falling edge is caught //捕获到一个下降沿
TIM_ClearITPendingBit(TIM8, TIM_IT_CC2); //Clear the interrupt flag bit //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϱ<EFBFBD>־λ
if (TIM8CH2_CAPTURE_STA & 0X40) //A falling edge is caught //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><EFBFBD><EFBFBD>
{
TIM8CH2_CAPTURE_DOWNVAL = TIM_GetCapture2(TIM8); //Record the timer value at this point //记录下此时的定时器计数值
TIM8CH2_CAPTURE_DOWNVAL = TIM_GetCapture2(TIM8); //Record the timer value at this point //<EFBFBD><EFBFBD>¼<EFBFBD>´<EFBFBD>ʱ<EFBFBD>Ķ<EFBFBD>ʱ<EFBFBD><EFBFBD><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 //得到总的高电平的时间
if(abs(Remoter_Ch2-L_Remoter_Ch2)>500)Remoter_Ch2=L_Remoter_Ch2; //Filter //滤波
Remoter_Ch2 = TIM8CH2_CAPTURE_DOWNVAL - TIM8CH2_CAPTURE_UPVAL + TIM8_T2; //Time to get the total high level //<EFBFBD>õ<EFBFBD><EFBFBD>ܵĸߵ<EFBFBD>ƽ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
if(abs(Remoter_Ch2-L_Remoter_Ch2)>500)Remoter_Ch2=L_Remoter_Ch2; //Filter //<EFBFBD>˲<EFBFBD>
L_Remoter_Ch2=Remoter_Ch2;
TIM8CH2_CAPTURE_STA = 0; //Capture flag bit to zero //捕获标志位清零
TIM_OC2PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //设置为上升沿捕获
TIM8CH2_CAPTURE_STA = 0; //Capture flag bit to zero //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM_OC2PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><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
//发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
TIM8CH2_CAPTURE_UPVAL = TIM_GetCapture2(TIM8); //Obtain rising edge data //获取上升沿数据
TIM8CH2_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //标记已捕获到上升沿
TIM_OC2PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //设置为下降沿捕获
//<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>Ķ<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
TIM8CH2_CAPTURE_UPVAL = TIM_GetCapture2(TIM8); //Obtain rising edge data //<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM8CH2_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM_OC2PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>½<EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>
}
}
}
//Channel 3 //通道三
//Channel 3 //ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ((TIM8CH3_CAPTURE_STA & 0X80) == 0)
{
if (TIM_GetITStatus(TIM8, TIM_IT_CC3) != RESET) //A capture event occurred on channel 3 //通道3发生捕获事件
if (TIM_GetITStatus(TIM8, TIM_IT_CC3) != RESET) //A capture event occurred on channel 3 //ͨ<EFBFBD><EFBFBD>3<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
{
TIM_ClearITPendingBit(TIM8, TIM_IT_CC3); //Clear the interrupt flag bit //清除中断标志位
if (TIM8CH3_CAPTURE_STA & 0X40) //A falling edge is caught //捕获到一个下降沿
TIM_ClearITPendingBit(TIM8, TIM_IT_CC3); //Clear the interrupt flag bit //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϱ<EFBFBD>־λ
if (TIM8CH3_CAPTURE_STA & 0X40) //A falling edge is caught //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><EFBFBD><EFBFBD>
{
TIM8CH3_CAPTURE_DOWNVAL = TIM_GetCapture3(TIM8); //Record the timer value at this point //记录下此时的定时器计数值
TIM8CH3_CAPTURE_DOWNVAL = TIM_GetCapture3(TIM8); //Record the timer value at this point //<EFBFBD><EFBFBD>¼<EFBFBD>´<EFBFBD>ʱ<EFBFBD>Ķ<EFBFBD>ʱ<EFBFBD><EFBFBD><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 //得到总的高电平的时间
if(abs(Remoter_Ch3-L_Remoter_Ch3)>500)Remoter_Ch3=L_Remoter_Ch3; //Filter //滤波
Remoter_Ch3 = TIM8CH3_CAPTURE_DOWNVAL - TIM8CH3_CAPTURE_UPVAL + TIM8_T3; //Time to get the total high level //<EFBFBD>õ<EFBFBD><EFBFBD>ܵĸߵ<EFBFBD>ƽ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
if(abs(Remoter_Ch3-L_Remoter_Ch3)>500)Remoter_Ch3=L_Remoter_Ch3; //Filter //<EFBFBD>˲<EFBFBD>
L_Remoter_Ch3=Remoter_Ch3;
TIM8CH3_CAPTURE_STA = 0; //Capture flag bit to zero //捕获标志位清零
TIM_OC3PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //设置为上升沿捕获
TIM8CH3_CAPTURE_STA = 0; //Capture flag bit to zero //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM_OC3PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><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
//发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
TIM8CH3_CAPTURE_UPVAL = TIM_GetCapture3(TIM8); //Obtain rising edge data //获取上升沿数据
TIM8CH3_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //标记已捕获到上升沿
TIM_OC3PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //设置为下降沿捕获
//<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>Ķ<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
TIM8CH3_CAPTURE_UPVAL = TIM_GetCapture3(TIM8); //Obtain rising edge data //<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM8CH3_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM_OC3PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>½<EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>
}
}
}
//
//Channel 4 //通道四
//Channel 4 //ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ((TIM8CH4_CAPTURE_STA & 0X80) == 0)
{
if (TIM_GetITStatus(TIM8, TIM_IT_CC4) != RESET) //A capture event occurred on channel 4 //通道4发生捕获事件
if (TIM_GetITStatus(TIM8, TIM_IT_CC4) != RESET) //A capture event occurred on channel 4 //ͨ<EFBFBD><EFBFBD>4<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
{
TIM_ClearITPendingBit(TIM8, TIM_IT_CC4); //Clear the interrupt flag bit //清除中断标志位
if (TIM8CH4_CAPTURE_STA & 0X40) //A falling edge is caught //捕获到一个下降沿
TIM_ClearITPendingBit(TIM8, TIM_IT_CC4); //Clear the interrupt flag bit //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϱ<EFBFBD>־λ
if (TIM8CH4_CAPTURE_STA & 0X40) //A falling edge is caught //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><EFBFBD><EFBFBD>
{
TIM8CH4_CAPTURE_DOWNVAL = TIM_GetCapture4(TIM8); //Record the timer value at this point //记录下此时的定时器计数值
TIM8CH4_CAPTURE_DOWNVAL = TIM_GetCapture4(TIM8); //Record the timer value at this point //<EFBFBD><EFBFBD>¼<EFBFBD>´<EFBFBD>ʱ<EFBFBD>Ķ<EFBFBD>ʱ<EFBFBD><EFBFBD><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 //得到总的高电平的时间
if(abs(Remoter_Ch4-L_Remoter_Ch4)>500)Remoter_Ch4=L_Remoter_Ch4; //Filter //滤波
Remoter_Ch4 = TIM8CH4_CAPTURE_DOWNVAL - TIM8CH4_CAPTURE_UPVAL + TIM8_T4; //Time to get the total high level //<EFBFBD>õ<EFBFBD><EFBFBD>ܵĸߵ<EFBFBD>ƽ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
if(abs(Remoter_Ch4-L_Remoter_Ch4)>500)Remoter_Ch4=L_Remoter_Ch4; //Filter //<EFBFBD>˲<EFBFBD>
L_Remoter_Ch4=Remoter_Ch4;
TIM8CH4_CAPTURE_STA = 0; //Capture flag bit to zero //捕获标志位清零
TIM_OC4PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //设置为上升沿捕获
TIM8CH4_CAPTURE_STA = 0; //Capture flag bit to zero //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM_OC4PolarityConfig(TIM8, TIM_ICPolarity_Rising); //Set to rising edge capture //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><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
//发生捕获时间但不是下降沿,第一次捕获到上升沿,记录此时的定时器计数值
TIM8CH4_CAPTURE_UPVAL = TIM_GetCapture4(TIM8); //Obtain rising edge data //获取上升沿数据
TIM8CH4_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //标记已捕获到上升沿
TIM_OC4PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //设置为下降沿捕获
//<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>Ķ<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
TIM8CH4_CAPTURE_UPVAL = TIM_GetCapture4(TIM8); //Obtain rising edge data //<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM8CH4_CAPTURE_STA |= 0X40; //The flag has been caught on the rising edge //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
TIM_OC4PolarityConfig(TIM8, TIM_ICPolarity_Falling); //Set to Falling Edge Capture //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>½<EFBFBD><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>
}
}
}
@@ -312,25 +312,25 @@ void TIM8_CC_IRQHandler(void)
Function: TIM1 Update Interrupt
Input : none
Output : none
函数功能:定时器8更新中断
入口参数:无
返回 值:无
<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
//清除中断标志位
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϱ<EFBFBD>־λ
TIM8->SR&=~(1<<0);
}
void TIM8_SERVO_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure; //IO
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定时器
TIM_OCInitTypeDef TIM_OCInitStructure; //PWM输出
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
TIM_OCInitTypeDef TIM_OCInitStructure; //PWM<EFBFBD><EFBFBD><EFBFBD>
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM1时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能PORTE时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); //TIM1ʱ<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //ʹ<EFBFBD><EFBFBD>PORTEʱ<EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
@@ -345,55 +345,55 @@ void TIM8_SERVO_Init(u16 arr,u16 psc)
GPIO_PinAFConfig(GPIOC,GPIO_PinSource9,GPIO_AF_TIM8);
/*** Initialize timer 1 || 初始化定时器1 ***/
//Set the counter to automatically reload //设定计数器自动重装值
/*** Initialize timer 1 || <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>1 ***/
//Set the counter to automatically reload //<EFBFBD>趨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD>װֵ
TIM_TimeBaseStructure.TIM_Period = arr;
//Pre-divider //预分频器
//Pre-divider //Ԥ<EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD>
TIM_TimeBaseStructure.TIM_Prescaler = psc;
//Set the clock split: TDTS = Tck_tim //设置时钟分割:TDTS = Tck_tim
//Set the clock split: TDTS = Tck_tim //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ӷָ<EFBFBD>:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
//TIM up count mode //TIM向上计数模式
//TIM up count mode //TIM<EFBFBD><EFBFBD><EFBFBD>ϼ<EFBFBD><EFBFBD><EFBFBD>ģʽ
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//Initializes the timebase unit for TIMX based on the parameter specified in TIM_TimeBaseInitStruct
//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>TIM_TimeBaseInitStruct<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>TIMx<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
//-----------舵机初始化-----------//
//-----------<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>-----------//
//Select Timer mode :TIM Pulse Width Modulation mode 1
//选择定时器模式:TIM脉冲宽度调制模式1
//ѡ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>ģʽ:TIM<49><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD>ģʽ1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
//Compare output enablement
//比较输出使能
//<EFBFBD>Ƚ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
//Set the pulse value of the capture comparison register to be loaded
//设置待装入捕获比较寄存器的脉冲值
//<EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD>װ<EFBFBD>벶<EFBFBD><EFBFBD>ȽϼĴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
TIM_OCInitStructure.TIM_Pulse = 0;
//Output polarity :TIM output polarity is higher
//输出极性:TIM输出比较极性高
//<EFBFBD><EFBFBD><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
//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>TIM_OCInitStruct<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><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
//通道预装载使能
//ͨ<EFBFBD><EFBFBD>Ԥװ<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable);
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable);
//-----------舵机初始化-----------//
//-----------<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>-----------//
TIM_CtrlPWMOutputs(TIM8,ENABLE);
//Enable timer //使能定时器
//Enable timer //ʹ<EFBFBD>ܶ<EFBFBD>ʱ<EFBFBD><EFBFBD>
TIM_Cmd(TIM8, ENABLE);
//The channel value is initialized to 1500, corresponding to the steering gear zero
//通道值初始化为1500,舵机零点对应值
//ͨ<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>Ϊ1500<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧֵ
// TIM8->CCR1=1500;
// TIM8->CCR2=1500;
// TIM8->CCR3=1500;
@@ -404,11 +404,11 @@ void TIM8_SERVO_Init(u16 arr,u16 psc)
void TIM12_SERVO_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure; //IO
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定时器
TIM_OCInitTypeDef TIM_OCInitStructure; //PWM输出
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
TIM_OCInitTypeDef TIM_OCInitStructure; //PWM<EFBFBD><EFBFBD><EFBFBD>
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM12,ENABLE); //TIM1时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能PORTE时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM12,ENABLE); //TIM1ʱ<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //ʹ<EFBFBD><EFBFBD>PORTEʱ<EFBFBD><EFBFBD>
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_15;
@@ -421,48 +421,48 @@ void TIM12_SERVO_Init(u16 arr,u16 psc)
GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_TIM12);
/*** Initialize timer 1 || 初始化定时器1 ***/
//Set the counter to automatically reload //设定计数器自动重装值
/*** Initialize timer 1 || <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>1 ***/
//Set the counter to automatically reload //<EFBFBD>趨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD>װֵ
TIM_TimeBaseStructure.TIM_Period = arr;
//Pre-divider //预分频器
//Pre-divider //Ԥ<EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD>
TIM_TimeBaseStructure.TIM_Prescaler = psc;
//Set the clock split: TDTS = Tck_tim //设置时钟分割:TDTS = Tck_tim
//Set the clock split: TDTS = Tck_tim //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ӷָ<EFBFBD>:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
//TIM up count mode //TIM向上计数模式
//TIM up count mode //TIM<EFBFBD><EFBFBD><EFBFBD>ϼ<EFBFBD><EFBFBD><EFBFBD>ģʽ
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//Initializes the timebase unit for TIMX based on the parameter specified in TIM_TimeBaseInitStruct
//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>TIM_TimeBaseInitStruct<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>TIMx<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
TIM_TimeBaseInit(TIM12, &TIM_TimeBaseStructure);
//-----------舵机初始化-----------//
//-----------<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>-----------//
//Select Timer mode :TIM Pulse Width Modulation mode 1
//选择定时器模式:TIM脉冲宽度调制模式1
//ѡ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>ģʽ:TIM<49><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD>ģʽ1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
//Compare output enablement
//比较输出使能
//<EFBFBD>Ƚ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
//Set the pulse value of the capture comparison register to be loaded
//设置待装入捕获比较寄存器的脉冲值
//<EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD>װ<EFBFBD>벶<EFBFBD><EFBFBD>ȽϼĴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
TIM_OCInitStructure.TIM_Pulse = 0;
//Output polarity :TIM output polarity is higher
//输出极性:TIM输出比较极性高
//<EFBFBD><EFBFBD><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
//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>TIM_OCInitStruct<EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TIMx
TIM_OC1Init(TIM12, &TIM_OCInitStructure);
TIM_OC2Init(TIM12, &TIM_OCInitStructure);
//Channel preload enable
//通道预装载使能
//ͨ<EFBFBD><EFBFBD>Ԥװ<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>
TIM_OC1PreloadConfig(TIM12, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM12, TIM_OCPreload_Enable);
//-----------舵机初始化-----------//
//-----------<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>-----------//
TIM_CtrlPWMOutputs(TIM12,ENABLE);
//Enable timer //使能定时器
//Enable timer //ʹ<EFBFBD>ܶ<EFBFBD>ʱ<EFBFBD><EFBFBD>
TIM_Cmd(TIM12, ENABLE);
//Initialize both servo channels to the configured steering center.
@@ -471,3 +471,83 @@ void TIM12_SERVO_Init(u16 arr,u16 psc)
}
/**************************************************************************
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;
}

View File

@@ -4,6 +4,8 @@
void TIM8_Cap_Init(u16 arr, u16 psc);
void TIM12_SERVO_Init(u16 arr,u16 psc);
void TIM8_SERVO_Init(u16 arr,u16 psc);
void TIM7_Init(void);
uint64_t mcu_time_us(void);
extern int L_Remoter_Ch1,L_Remoter_Ch2,L_Remoter_Ch3,L_Remoter_Ch4;
extern int Remoter_Ch1,Remoter_Ch2,Remoter_Ch3,Remoter_Ch4;

File diff suppressed because it is too large Load Diff

View File

@@ -10,33 +10,41 @@
#define FRAME_HEADER 0X7B //Frame_header //֡ͷ
#define FRAME_TAIL 0X7D //Frame_tail //֡β
#define SEND_DATA_SIZE 24
//Frame grew 24 -> 44: appended session_id(4) + two 64-bit sample
//timestamps(8+8) before the checksum/tail. Bytes 0..21 keep the legacy
//layout so old parsers stay compatible; new fields live in the tail.
//֡<><D6A1> 24 -> 44<34><34><EFBFBD><EFBFBD>У<EFBFBD><D0A3>/֡βǰ׷<C7B0><D7B7><EFBFBD><EFBFBD> session_id(4) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 64λ<34><CEBB><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>(8+8)<29><>
//<2F>ֽ<EFBFBD> 0..21 <20><><EFBFBD>ֽ<EFBFBD>ϲ<EFBFBD><CFB2>֣<EFBFBD><D6A3>¾ֽ<C2BE><D6BD><EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD>
#define SEND_DATA_SIZE 44
#define RECEIVE_DATA_SIZE 11
/*****A structure for storing triaxial data of a gyroscope accelerometer*****/
/*****用于存放陀螺仪加速度计三轴数据的结构体*********************************/
/*****<EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǽ<EFBFBD><EFBFBD>ٶȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĽṹ<EFBFBD><EFBFBD>*********************************/
typedef struct __Mpu6050_Data_
{
short X_data; //2 bytes //2个字节
short Y_data; //2 bytes //2个字节
short Z_data; //2 bytes //2个字节
short X_data; //2 bytes //2<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
short Y_data; //2 bytes //2<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
short Z_data; //2 bytes //2<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
}Mpu6050_Data;
/*******The structure of the serial port sending data************/
/*******串口发送数据的结构体*************************************/
/*******<EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĽṹ<EFBFBD><EFBFBD>*************************************/
typedef struct _SEND_DATA_
{
unsigned char buffer[SEND_DATA_SIZE];
struct _Sensor_Str_
{
unsigned char Frame_Header; //1个字节
short X_speed; //2 bytes //2个字节
short Y_speed; //2 bytes //2个字节
short Z_speed; //2 bytes //2个字节
short Power_Voltage; //2 bytes //2个字节
Mpu6050_Data Accelerometer; //6 bytes //6个字节
Mpu6050_Data Gyroscope; //6 bytes //6个字节
unsigned char Frame_Tail; //1 bytes //1个字节
unsigned char Frame_Header; //1<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
short X_speed; //2 bytes //2<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
short Y_speed; //2 bytes //2<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
short Z_speed; //2 bytes //2<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
short Power_Voltage; //2 bytes //2<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
Mpu6050_Data Accelerometer; //6 bytes //6<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
Mpu6050_Data Gyroscope; //6 bytes //6<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
unsigned int Session_Id; //4 bytes: MCU boot session ID //<2F><>MCU<43><55><EFBFBD><EFBFBD><EFBFBD>ỰID
unsigned long long Speed_Time_us; //8 bytes: encoder sample time //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
unsigned long long Imu_Time_us; //8 bytes: IMU sample time //IMU<4D><55><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
unsigned char Frame_Tail; //1 bytes //1<><31><EFBFBD>ֽ<EFBFBD>
}Sensor_Str;
}SEND_DATA;
@@ -45,14 +53,21 @@ typedef struct _RECEIVE_DATA_
unsigned char buffer[RECEIVE_DATA_SIZE];
struct _Control_Str_
{
unsigned char Frame_Header; //1 bytes //1个字节
float X_speed; //4 bytes //4个字节
float Y_speed; //4 bytes //4个字节
float Z_speed; //4 bytes //4个字节
unsigned char Frame_Tail; //1 bytes //1个字节
unsigned char Frame_Header; //1 bytes //1<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
float X_speed; //4 bytes //4<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
float Y_speed; //4 bytes //4<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
float Z_speed; //4 bytes //4<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
unsigned char Frame_Tail; //1 bytes //1<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
}Control_Str;
}RECEIVE_DATA;
//Sample timestamps captured at acquisition time by their owning tasks, and
//the per-boot session ID. Read by data_transition() when packing the frame.
//<2F>ɸ<EFBFBD><C9B8>Բɼ<D4B2><C9BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>лỰID<49><44>
//<2F><> data_transition() <20><><EFBFBD>֡ʱ<D6A1><CAB1>ȡ<EFBFBD><C8A1>
extern volatile unsigned long long g_speed_sample_time_us;
extern volatile unsigned long long g_imu_sample_time_us;
extern volatile unsigned int g_session_id;
void data_task(void *pvParameters);
void data_transition(void);
@@ -64,6 +79,7 @@ void CAN_SEND(void);
void uart1_init(u32 bound);
void uart2_init(u32 bound);
void uart3_init(u32 bound);
void uart3_dma_tx_init(void);
void uart5_init(u32 bound);
int USART1_IRQHandler(void);