上面几篇帖子已经写完控制流程还剩一点没说
if(PPM_Isr_Cnt==100)//PPM接收正常才进行传感器标定检测
{
Accel_Calibration_Check();//加速度标定检测
Mag_Calibration_Check();//磁力计标定检测
}
Bling_Working(Bling_Mode);//状态指示灯
//DMA_Send_StateMachine();//DMA传输,只使用山外上位机
//ANO_SEND_StateMachine();//DMA传输,只使用ANO地面站
DMA_SEND_Tradeoff();//DMA传输,两路地面站机同时工作
TIM_ClearITPendingBit(TIM4,TIM_FLAG_Update);
}
对于变量PPM_Isr_Cnt,它是一个全局变量uint16 PPM_Isr_Cnt=0;
PPM的中断函数
uint16 PPM_Sample_Cnt=0;
uint16 PPM_Isr_Cnt=0;
u32 Last_PPM_Time=0;
u32 PPM_Time=0;
u16 PPM_Time_Delta=0;
u16 PPM_Time_Max=0;
uint16 PPM_Start_Time=0;
uint16 PPM_Finished_Time=0;
uint16 PPM_Is_Okay=0;
uint16 PPM_Databuf[8]={0};
/***************************************************
函数名: void EXTI9_5_IRQHandler(void)
说明: PPM接收中断函数
入口: 无
出口: 无
备注: 程序初始化后、始终运行
****************************************************/
void EXTI9_5_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line8) != RESET)
{
//系统运行时间获取,单位us
Last_PPM_Time=PPM_Time;
PPM_Time=10000*TIME_ISR_CNT
+TIM2->CNT/2;//us
PPM_Time_Delta=PPM_Time-Last_PPM_Time;
//PPM中断进入判断
if(PPM_Isr_Cnt<100) PPM_Isr_Cnt++;
//PPM解析开始
if(PPM_Is_Okay==1)
{
PPM_Sample_Cnt++;
//对应通道写入缓冲区
PPM_Databuf[PPM_Sample_Cnt-1]=PPM_Time_Delta;
//单次解析结束
if(PPM_Sample_Cnt>=8)
PPM_Is_Okay=0;
}
if(PPM_Time_Delta>=2050)//帧结束电平至少2ms=2000us
{
PPM_Is_Okay=1;
PPM_Sample_Cnt=0;
}
}
EXTI_ClearITPendingBit(EXTI_Line8);
}
PPM_Isr_Cnt在小于100时,每次中断发生自加一次,直到等于100;
然后
Accel_Calibration_Check();//加速度标定检测
Mag_Calibration_Check();//磁力计标定检测
对于加速度
uint8_t flight_direction=6;
uint8_t Accel_Calibration_Flag=0;//加速度计校准模式
uint8_t Accel_Calibration_Finished[6]={0,0,0,0,0,0};//对应面校准完成标志位
uint8_t Accel_Calibration_All_Finished=0;//6面校准全部校准完成标志位
uint16_t Accel_Calibration_Makesure_Cnt=0;
uint16_t Accel_flight_direction_cnt=0;
void Accel_Calibration_Check(void)
{
uint16_t i=0;
if(Throttle_Control==1000&&Yaw_Control>=80&&Roll_Control<=-40&&Pitch_Control>=40)
{
Accel_Calibration_Makesure_Cnt++;
}
if(Throttle_Control==1000
&&Yaw_Control>=80
&&Roll_Control<=-40
&&Pitch_Control>=40
&&Accel_Calibration_Makesure_Cnt>=200*3)//持续三秒
{
Bling_Mode=1;
Accel_Calibration_Flag=1;//加速度校准模式
Cal_Flag=0;
Bling_Set(&Light_1,1000,100,0.5,0,GPIOC,GPIO_Pin_4,1);
Bling_Set(&Light_2,1000,100,0.5,0,GPIOC,GPIO_Pin_5,1);
Bling_Set(&Light_3,1000,100,0.5,0,GPIOC,GPIO_Pin_10,1);
flight_direction=6;
Accel_Calibration_All_Finished=0;//全部校准完成标志位清零
Accel_Calibration_Makesure_Cnt=0;
for(i=0;i<6;i++)
{
Accel_Calibration_Finished[i]=0;//对应面标志位清零
acce_sample[i].x=0; //清空对应面的加速度计量
acce_sample[i].y=0; //清空对应面的加速度计量
acce_sample[i].z=0; //清空对应面的加速度计量
}
Page_Number=10;//OLED加速度计矫正页面
Reset_Mag_Calibartion(1);
}
if(Accel_Calibration_Flag==1)
{
if(Throttle_Control==1000&&Yaw_Control<=-80&&Roll_Control==0&&Pitch_Control==0)
{
Accel_flight_direction_cnt++;
if(Accel_flight_direction_cnt>=4*25)//100ms
flight_direction=0;
}
else if(Throttle_Control==1000&&Yaw_Control==0&&Roll_Control>=40&&Pitch_Control==0)
{
Accel_flight_direction_cnt++;
if(Accel_flight_direction_cnt>=4*25)//100ms
flight_direction=1;
}
else if(Throttle_Control==1000&&Yaw_Control==0&&Roll_Control<=-40&&Pitch_Control==0)
{
Accel_flight_direction_cnt++;
if(Accel_flight_direction_cnt>=4*25)//100ms
flight_direction=2;
}
else if(Throttle_Control==1000&&Yaw_Control==0&&Roll_Control==0&&Pitch_Control>=40)
{
Accel_flight_direction_cnt++;
if(Accel_flight_direction_cnt>=4*25)//100ms
flight_direction=3;
}
else if(Throttle_Control==1000&&Yaw_Control==0&&Roll_Control==0&&Pitch_Control<=-40)
{
Accel_flight_direction_cnt++;
if(Accel_flight_direction_cnt>=4*25)//100ms
flight_direction=4;
}
else if(Throttle_Control==1000&&Yaw_Control>80&&Roll_Control==0&&Pitch_Control==0)
{
Accel_flight_direction_cnt++;
if(Accel_flight_direction_cnt>=4*25)//100ms
flight_direction=5;
}
else
{
Accel_flight_direction_cnt/=2;
}
if(Accel_flight_direction_cnt>=200) Accel_flight_direction_cnt=0;
}
}
加速度检测,每次
这个过程可以分为两部分,一部分是根据遥控器摇杆确认加速度是否需要校准,如需要收集数据,另外引入磁力计校准,另一部分根据摇杆确认flight_direction的值,
校准就是把所有的数据清零??
其中Reset_Mag_Calibartion函数
void Reset_Mag_Calibartion(uint8_t Type)
{
uint16 i=0;
for(i=0;i<12;i++)
{
Mag_360_Flag[0][i]=0;//清空采集角点
Mag_360_Flag[1][i]=0;//清空采集角点
}
Mag_Is_Okay_Flag[0]=0;
Mag_Is_Okay_Flag[1]=0;
Mag_Calibration_Mode=2;
if(Type==1) Mag_Calibration_Flag=0;
}
对于Mag_Calibration_Check
/***********磁力计中心矫正,取单轴最大、最小值平均******/
uint8_t Mag_Calibration_Flag=0,Mag_Calibration_All_Finished;
uint8_t Mag_Calibration_Finished[2]={0};
uint16_t Mag_Calibration_Makesure_Cnt=0;
uint8_t Mag_Calibration_Mode=2;
uint16_t Mag_Calibration_Cnt=0;
/*********************************************/
const int16_t Mag_360_define[12]={
0,30,60,90,
120,150,180,210,
240,270,300,330
};//磁力计矫正遍历角度,确保数据采集充分
uint8_t Mag_360_Flag[2][12]={0};
uint16_t Mag_Is_Okay_Flag[2];
Calibration Mag;
Mag_Unit DataMag;
Mag_Unit Mag_Offset_Read={
0,0,0,
};
void Mag_Calibration_Check(void)
{
uint16_t i=0,j=0;
if(Throttle_Control==1000&&Yaw_Control>=80&&Roll_Control>=40&&Pitch_Control>=40) Mag_Calibration_Makesure_Cnt++;
if(Throttle_Control==1000
&&Yaw_Control>=80
&&Roll_Control>=40
&&Pitch_Control>=40
&&Mag_Calibration_Makesure_Cnt>250*4//持续4S
)//进入磁力计校准模式
{
Bling_Mode=2;
Mag_Calibration_Flag=1;//磁力计校准模式
Mag_Calibration_Mode=2;
Bling_Set(&Light_1,1000,500,0.2,0,GPIOC,GPIO_Pin_4,1);
Bling_Set(&Light_2,1000,500,0.5,0,GPIOC,GPIO_Pin_5,1);
Bling_Set(&Light_3,1000,500,0.7,0,GPIOC,GPIO_Pin_10,1);
Mag_Calibration_Makesure_Cnt=0;
Mag_Calibration_All_Finished=0;//全部校准完成标志位清零
for(i=0;i<2;i++)
{
Mag_Calibration_Finished[i]=0;//对应面标志位清零
for(j=0;j<12;j++) {Mag_360_Flag[i][j]=0;}
}
Page_Number=11;
Reset_Accel_Calibartion(1);
}
if(Mag_Calibration_Flag==1)
{
if(Throttle_Control==1000
&&Yaw_Control<=-80
&&Roll_Control==0
&&Pitch_Control==0) //第一面矫正
{
Mag_Calibration_Cnt++;
if(Mag_Calibration_Cnt>=4*25)
{
Mag_Calibration_Mode=0;
Mag_Is_Okay_Flag[1]=0;//单面数据采集完成标志位置0
for(i=0;i<12;i++) Mag_360_Flag[1][i]=0;//清空采集角遍历数据点
}
}
else if(Throttle_Control==1000
&&Yaw_Control>80
&&Roll_Control==0
&&Pitch_Control==0) //第二面矫正
{
Mag_Calibration_Cnt++;
if(Mag_Calibration_Cnt>=4*25)
{
Mag_Calibration_Mode=1;
Mag_Is_Okay_Flag[1]=0;//单面数据采集完成标志位置0
for(i=0;i<12;i++) Mag_360_Flag[1][i]=0;//清空采集角遍历数据点
}
}
else
{
Mag_Calibration_Cnt/=2;
}
if(Mag_Calibration_Cnt>=200) Mag_Calibration_Cnt=200;
}
}
不懂原理唉,不知道为什么?查查在完整吧!
Bling_Working(Bling_Mode);//状态指示灯
//DMA_Send_StateMachine();//DMA传输,只使用山外上位机
//ANO_SEND_StateMachine();//DMA传输,只使用ANO地面站
DMA_SEND_Tradeoff();//DMA传输,两路地面站机同时工作
从这里看飞控可以选择DMA传输,先从一个开始吧!
这里用的是
uint16_t DMA_SEND_CNT=0;
//由于共用同一个DMA,不能同时发否则会有一个丢帧
void DMA_SEND_Tradeoff(void)
{
DMA_SEND_CNT++;
if(DMA_SEND_CNT<=16&&DMA_SEND_CNT>=4)
{
DMA_Send_StateMachine();//DMA传输
}
else if(DMA_SEND_CNT==20)//100ms进入一次
{
ANO_SEND_StateMachine();
DMA_SEND_CNT=0;
}
}
通过DMA_SEND_CNT来判断进入那一个函数即地面站
先追DMA_Send_StateMachine()
DMA_Vcan_Buff Vcan_Buff;
#define DMA_SEND_PERIOD 3//4*5=20ms,周期太小不易于观察波形
void DMA_Send_StateMachine(void)
{
static uint16_t DMA_Send_Cnt=0;
DMA_Send_Cnt++;
if(DMA_Send_Cnt>=DMA_SEND_PERIOD)
{
Vcan_Buff.Head=0xfc030000;
/*
Vcan_Buff.DataBuf[0]=Pitch;
Vcan_Buff.DataBuf[1]=Roll;
Vcan_Buff.DataBuf[2]=ACCE_X;
Vcan_Buff.DataBuf[3]=ACCE_Y;
Vcan_Buff.DataBuf[4]=Origion_NamelessQuad.Acceleration[_YAW];
Vcan_Buff.DataBuf[5]=Filter_Feedback_NamelessQuad.Acceleration[_YAW];
//Vcan_Buff.DataBuf[6]=Total_Controler.High_Position_Control.Expect;
//Vcan_Buff.DataBuf[7]=FilterBefore_NamelessQuad.Acceleration[_YAW];
Vcan_Buff.DataBuf[7]=Gyro_Delta_Length;
Vcan_Buff.DataBuf[6]=Acceleration_Length;
*/
Vcan_Buff.DataBuf[0]=NamelessQuad.Position[_YAW];
Vcan_Buff.DataBuf[1]=NamelessQuad.Speed[_YAW];
Vcan_Buff.DataBuf[2]=NamelessQuad.Acceleration[_YAW];
Vcan_Buff.DataBuf[3]=Altitude_Estimate;
Vcan_Buff.DataBuf[4]=Origion_NamelessQuad.Acceleration[_YAW];
Vcan_Buff.DataBuf[5]=acc_correction[_YAW];
Vcan_Buff.DataBuf[7]=vel_correction[_YAW];
Vcan_Buff.DataBuf[6]=pos_correction[_YAW];
/*
Vcan_Buff.DataBuf[0]=NamelessQuad.Position[_PITCH];
Vcan_Buff.DataBuf[1]=NamelessQuad.Speed[_PITCH];
Vcan_Buff.DataBuf[2]=GPS_Vel.E;
Vcan_Buff.DataBuf[3]=Earth_Frame_To_XYZ.E;
Vcan_Buff.DataBuf[4]=NamelessQuad.Position[_ROLL];
Vcan_Buff.DataBuf[5]=NamelessQuad.Speed[_ROLL];
Vcan_Buff.DataBuf[6]=GPS_Vel.N;
Vcan_Buff.DataBuf[7]=Earth_Frame_To_XYZ.N;
*/
//Vcan_Buff.DataBuf[0]=Acce_Correct[0];
//Vcan_Buff.DataBuf[1]=Acce_Correct[1];
//Vcan_Buff.DataBuf[2]=Acce_Correct[2];
//Vcan_Buff.DataBuf[3]=imu.accelRaw[0];
//Vcan_Buff.DataBuf[4]=imu.accelRaw[1];
// Vcan_Buff.DataBuf[6]=imu.accelRaw[2];
/*
Vcan_Buff.DataBuf[0]=ADRC_Roll_Controller.x1;
Vcan_Buff.DataBuf[1]=ADRC_Roll_Controller.x2;
Vcan_Buff.DataBuf[2]=Total_Controler.Roll_Angle_Control.Control_OutPut;
Vcan_Buff.DataBuf[3]=Roll_Gyro;
Vcan_Buff.DataBuf[4]=ADRC_Roll_Controller.z1;
Vcan_Buff.DataBuf[5]=ADRC_Roll_Controller.z2;
Vcan_Buff.DataBuf[6]=Total_Controler.Roll_Gyro_Control.Control_OutPut;
Vcan_Buff.DataBuf[7]=ADRC_Roll_Controller.u0;
//Vcan_Buff.DataBuf[7]=FilterBefore_NamelessQuad.Acceleration[_YAW];
//Vcan_Buff.DataBuf[7]=Gyro_Delta_Length;
//Vcan_Buff.DataBuf[6]=Acceleration_Length;
*/
Vcan_Buff.End=0x000003fc;
Quad_DMA1_USART1_SEND((u32)(&Vcan_Buff),sizeof(Vcan_Buff));
DMA_Send_Cnt=0;
}
}
首先定义一个DMA_Vcan_Buff型的结构体Vcan_Buff:
DMA_Vcan_Buff的定义:
typedef struct
{
uint32_t Head;
float DataBuf[8];
uint32_t End;
}DMA_Vcan_Buff;
函数具体语句:
static uint16_t DMA_Send_Cnt=0;
DMA_Send_Cnt++;
定义一个静态变量,自加;判断
if(DMA_Send_Cnt>=DMA_SEND_PERIOD)
主要语句就几句其他都是注释
Vcan_Buff.Head=0xfc030000;
Vcan_Buff.DataBuf[0]=NamelessQuad.Position[_YAW];
Vcan_Buff.DataBuf[1]=NamelessQuad.Speed[_YAW];
Vcan_Buff.DataBuf[2]=NamelessQuad.Acceleration[_YAW];
Vcan_Buff.DataBuf[3]=Altitude_Estimate;
Vcan_Buff.DataBuf[4]=Origion_NamelessQuad.Acceleration[_YAW];
Vcan_Buff.DataBuf[5]=acc_correction[_YAW];
Vcan_Buff.DataBuf[7]=vel_correction[_YAW];
Vcan_Buff.DataBuf[6]=pos_correction[_YAW];
Vcan_Buff.End=0x000003fc;
这几句是对 Vcan_Buff的定义,可以说是待发送的数据
Quad_DMA1_USART1_SEND((u32)(&Vcan_Buff),sizeof(Vcan_Buff));
DMA_Send_Cnt=0;
Quad_DMA1_USART1_SEND发送数据
DMA_Send_Cnt=0;又赋零,这个数没什么存在感
Quad_DMA1_USART1_SEND的定义:
void Quad_DMA1_USART1_SEND(u32 SendBuff,u16 len)//DMA---USART1传输
{
Quad_DMA_Config(DMA1_Channel4,(u32)&USART1->DR,(u32)SendBuff,len);//DMA1通道4,外设为串口1,存储器为SendBuff,长度len.
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
Quad_DMA_Enable(DMA1_Channel4);
//while(DMA_GetFlagStatus(DMA1_FLAG_TC4) != SET);
//DMA_ClearFlag(DMA1_FLAG_TC4);//清除发送完成标志
}
先看看Quad_DMA_Config,初始化DMA,DMA-USART1
void Quad_DMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输,挂载DMA1时钟
DMA_DeInit(DMA_CHx); //将DMA的通道1寄存器重设为缺省值,这里是DMA1_Channel4
DMA1_MEM_LEN=cndtr;
DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr =cmar;//DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //外设作为数据传输的目的地
DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA缓存的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA_CHx, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
}
其中u16 DMA1_MEM_LEN;//保存DMA每次数据传送的长度
接着 USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);//使能指定USART的DMA请求
Quad_DMA_Enable(DMA1_Channel4);
第一句好理解
第二句
void Quad_DMA_Enable(DMA_Channel_TypeDef*DMA_CHx)//开启一次DMA传输
{
DMA_Cmd(DMA_CHx, DISABLE );
//关闭USART1 TX DMA1 所指示的通道
DMA_InitStructure.DMA_BufferSize =DMA1_MEM_LEN;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
DMA_Cmd(DMA_CHx, ENABLE); //使能USART1 TX DMA1 所指示的通道
}
先关闭DMA1 所指示的通道,在复制后DMA_InitStructure.DMA_BufferSize =DMA1_MEM_LEN;初始化DMA ,又打开DMA1 所指示的通道
下面应该回到ANO_SEND_StateMachine
这个函数复杂一点就有:
int16_t ANO_Cnt=0;
void ANO_SEND_StateMachine()
{
ANO_Cnt++;
if(ANO_Cnt==1)
{
ANO_Data_Send_Status();
}
else if(ANO_Cnt==2)
{
ANO_DT_Send_Senser((int16_t)X_g_av,(int16_t)Y_g_av,(int16_t)Z_g_av,
(int16_t)X_w_av,(int16_t)Y_w_av,(int16_t)Z_w_av,
(int16_t)DataMag.x,(int16_t)DataMag.y,(int16_t)DataMag.z);
}
else if(ANO_Cnt==3)
{
ANO_DT_Send_RCData(PPM_Databuf[2],PPM_Databuf[3],
PPM_Databuf[0],PPM_Databuf[1],
PPM_Databuf[4],PPM_Databuf[5],
PPM_Databuf[6],PPM_Databuf[7],0,0);
}
else if(ANO_Cnt==4)
{
ANO_DT_Send_GPSData(1,GPS_Sate_Num,Longitude_Origion,Latitude_Origion,10);
ANO_Cnt=0;
}
else if(ANO_Cnt==5)
{
ANO_Cnt=0;
}
}
这个发送的数据比较多,根据ANO_Cnt的值来发送那个数据
首先当ANO_Cnt等于1时
运行
ANO_Data_Send_Status();
uint8_t data_to_send[50];
/************************************************************/
//1:发送基本信息(姿态、锁定状态)
void ANO_Data_Send_Status(void)
{
u8 _cnt=0;
vs16 _temp;
vs32 _temp2;
u8 sum = 0;
u8 i;
data_to_send[_cnt++]=0xAA;
data_to_send[_cnt++]=0xAA;
data_to_send[_cnt++]=0x01;
data_to_send[_cnt++]=0;
_temp = (int)(Roll*100);
data_to_send[_cnt++]=BYTE1(_temp);
data_to_send[_cnt++]=BYTE0(_temp);
_temp = (int)(Pitch*100);
data_to_send[_cnt++]=BYTE1(_temp);
data_to_send[_cnt++]=BYTE0(_temp);
_temp = (int)(Yaw*100);
data_to_send[_cnt++]=BYTE1(_temp);
data_to_send[_cnt++]=BYTE0(_temp);
_temp2 = (vs32)(100*NamelessQuad.Position[_YAW]);//单位cm
data_to_send[_cnt++]=BYTE3(_temp2);
data_to_send[_cnt++]=BYTE2(_temp2);
data_to_send[_cnt++]=BYTE1(_temp2);
data_to_send[_cnt++]=BYTE0(_temp2);
data_to_send[_cnt++]=0x01;//飞行模式
data_to_send[_cnt++]=Controler_State;//上锁0、解锁1
data_to_send[3] = _cnt-4;
sum = 0;
for(i=0;i<_cnt;i++)
sum += data_to_send[i];
data_to_send[_cnt++]=sum;
Quad_DMA1_USART3_SEND((u32)(data_to_send),_cnt);
//UART3_Send(data_to_send, _cnt);
}
这里面有几个不一样的定义
//数据拆分宏定义,在发送大于1字节的数据类型时,比如int16、float等,需要把数据拆分成单独字节进行发送
#define BYTE0(dwTemp) ( *( (char *)(&dwTemp) ) )
#define BYTE1(dwTemp) ( *( (char *)(&dwTemp) + 1) )
#define BYTE2(dwTemp) ( *( (char *)(&dwTemp) + 2) )
#define BYTE3(dwTemp) ( *( (char *)(&dwTemp) + 3) )
不是很理解,先放着吧!
看看data_to_send都是有啥
前四个,0xAA;0xAA;0x01;_cnt-4;(这个应该是11)横滚俯仰偏航高度模式上锁状态这些数据的和
后面一句
Quad_DMA1_USART3_SEND((u32)(data_to_send),_cnt);
定义
void Quad_DMA1_USART3_SEND(u32 SendBuff,u16 len)//DMA---USART1传输
{
Quad_DMA1_Config(DMA1_Channel2,(u32)&USART3->DR,(u32)SendBuff,len);//DMA1通道4,外设为串口1,存储器为SendBuff,长度len.
USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);
Quad_DMA_Enable(DMA1_Channel2);
//while(DMA_GetFlagStatus(DMA1_FLAG_TC4) != SET);
//DMA_ClearFlag(DMA1_FLAG_TC4);//清除发送完成标志
}
和Quad_DMA1_USART1_SEND类似,这个只不过初始化的时候初始化了DMA1_Channel2通道和USART3
void Quad_DMA1_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输
DMA_DeInit(DMA_CHx); //将DMA的通道1寄存器重设为缺省值
DMA1_MEM_LEN=cndtr;
DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr =cmar;//DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //外设作为数据传输的目的地
DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA缓存的大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //DMA通道 x拥有中优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA_CHx, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
}
可以类比
ANO_Cnt==2时
ANO_DT_Send_Senser((int16_t)X_g_av,(int16_t)Y_g_av,(int16_t)Z_g_av,
(int16_t)X_w_av,(int16_t)Y_w_av,(int16_t)Z_w_av,
(int16_t)DataMag.x,(int16_t)DataMag.y,(int16_t)DataMag.z);
打开定义
void ANO_DT_Send_Senser(s16 a_x,s16 a_y,s16 a_z,s16 g_x,s16 g_y,s16 g_z,s16 m_x,s16 m_y,s16 m_z)
{
u8 _cnt=0;
vs16 _temp;
u8 sum = 0;
u8 i=0;
data_to_send[_cnt++]=0xAA;
data_to_send[_cnt++]=0xAA;
data_to_send[_cnt++]=0x02;
data_to_send[_cnt++]=0;
_temp = a_x;
data_to_send[_cnt++]=BYTE1(_temp);
data_to_send[_cnt++]=BYTE0(_temp);
_temp = a_y;
data_to_send[_cnt++]=BYTE1(_temp);
data_to_send[_cnt++]=BYTE0(_temp);
_temp = a_z;
data_to_send[_cnt++]=BYTE1(_temp);
data_to_send[_cnt++]=BYTE0(_temp);
_temp = g_x;
data_to_send[_cnt++]=BYTE1(_temp);
data_to_send[_cnt++]=BYTE0(_temp);
_temp = g_y;
data_to_send[_cnt++]=BYTE1(_temp);
data_to_send[_cnt++]=BYTE0(_temp);
_temp = g_z;
data_to_send[_cnt++]=BYTE1(_temp);
data_to_send[_cnt++]=BYTE0(_temp);
_temp = m_x;
data_to_send[_cnt++]=BYTE1(_temp);
data_to_send[_cnt++]=BYTE0(_temp);
_temp = m_y;
data_to_send[_cnt++]=BYTE1(_temp);
data_to_send[_cnt++]=BYTE0(_temp);
_temp = m_z;
data_to_send[_cnt++]=BYTE1(_temp);
data_to_send[_cnt++]=BYTE0(_temp);
data_to_send[3] = _cnt-4;
sum = 0;
for(i=0;i<_cnt;i++)
sum += data_to_send[i];
data_to_send[_cnt++] = sum;
Quad_DMA1_USART3_SEND((u32)(data_to_send),_cnt);
//UART3_Send(data_to_send, _cnt);
}
这个发送和ANO_Data_Send_Status类似发送三个轴的加速度,角速度,磁力计数据
ANO_Cnt==3时发送接收机接收到的数据
ANO_DT_Send_RCData(PPM_Databuf[2],PPM_Databuf[3],
PPM_Databuf[0],PPM_Databuf[1],
PPM_Databuf[4],PPM_Databuf[5],
PPM_Databuf[6],PPM_Databuf[7],0,0);
}
void ANO_DT_Send_RCData(u16 thr,u16 yaw,u16 rol,u16 pit,u16 aux1,u16 aux2,u16 aux3,u16 aux4,u16 aux5,u16 aux6)
{
u8 _cnt=0;
u8 i=0;
u8 sum = 0;
data_to_send[_cnt++]=0xAA;
data_to_send[_cnt++]=0xAA;
data_to_send[_cnt++]=0x03;
data_to_send[_cnt++]=0;
data_to_send[_cnt++]=BYTE1(thr);
data_to_send[_cnt++]=BYTE0(thr);
data_to_send[_cnt++]=BYTE1(yaw);
data_to_send[_cnt++]=BYTE0(yaw);
data_to_send[_cnt++]=BYTE1(rol);
data_to_send[_cnt++]=BYTE0(rol);
data_to_send[_cnt++]=BYTE1(pit);
data_to_send[_cnt++]=BYTE0(pit);
data_to_send[_cnt++]=BYTE1(aux1);
data_to_send[_cnt++]=BYTE0(aux1);
data_to_send[_cnt++]=BYTE1(aux2);
data_to_send[_cnt++]=BYTE0(aux2);
data_to_send[_cnt++]=BYTE1(aux3);
data_to_send[_cnt++]=BYTE0(aux3);
data_to_send[_cnt++]=BYTE1(aux4);
data_to_send[_cnt++]=BYTE0(aux4);
data_to_send[_cnt++]=BYTE1(aux5);
data_to_send[_cnt++]=BYTE0(aux5);
data_to_send[_cnt++]=BYTE1(aux6);
data_to_send[_cnt++]=BYTE0(aux6);
data_to_send[3] = _cnt-4;
sum = 0;
for(i=0;i<_cnt;i++)
sum += data_to_send[i];
data_to_send[_cnt++]=sum;
Quad_DMA1_USART3_SEND((u32)(data_to_send),_cnt);
//UART3_Send(data_to_send, _cnt);
}
ANO_Cnt==4时发送GPS的数据,后 ANO_Cnt=0
ANO_DT_Send_GPSData(1,GPS_Sate_Num,Longitude_Origion,Latitude_Origion,10);
void ANO_DT_Send_GPSData(u8 Fixstate,
u8 GPS_Num,
u32 log,
u32 lat,
int16 gps_head)
{
u8 sum = 0;
u8 _cnt=0;
u8 i=0;
data_to_send[_cnt++]=0xAA;
data_to_send[_cnt++]=0xAA;
data_to_send[_cnt++]=0x04;
data_to_send[_cnt++]=0;
data_to_send[_cnt++]=Fixstate;
data_to_send[_cnt++]=GPS_Num;
data_to_send[_cnt++]=BYTE3(log);
data_to_send[_cnt++]=BYTE2(log);
data_to_send[_cnt++]=BYTE1(log);
data_to_send[_cnt++]=BYTE0(log);
data_to_send[_cnt++]=BYTE3(lat);
data_to_send[_cnt++]=BYTE2(lat);
data_to_send[_cnt++]=BYTE1(lat);
data_to_send[_cnt++]=BYTE0(lat);
data_to_send[_cnt++]=BYTE1(gps_head);
data_to_send[_cnt++]=BYTE0(gps_head);
data_to_send[3] = _cnt-4;
sum = 0;
for(i=0;i<_cnt;i++)
sum += data_to_send[i];
data_to_send[_cnt++]=sum;
Quad_DMA1_USART3_SEND((u32)(data_to_send),_cnt);
//UART3_Send(data_to_send, _cnt);
}
就先写到这