打开飞控的main.c文件
首先是HardWave_Init();//飞控板内部资源、相关外设初始化
打开
#include "Headfile.h"
Sensor_Okay_Flag Sensor_Init_Flag;
void HardWave_Init(void)
{
SystemInit();//时钟初始化
cycleCounterInit();//系统滴答时钟初始化,程序精准延时
SysTick_Config(SystemCoreClock / 1000);//SysTick开启系统tick定时器并初始化其中断,1ms
USART1_Init(115200);//主串口初始化
OLED_Init(); //显示屏初始化
Bling_Init(); //指示灯、测试IO初始化
Key_Init(); //按键初始化
PPM_Init(); //PPM遥控器接收初始化
HC_SR04_Init(); //超声波初始化
PWM_Init(); //PWM初始化—TIM4
/*
SPI2_Configuration();
NRF24L01_Init();//
while(NRF24L01_Check())
{
printf("24L01 Check Failed!\r\n");
printf("Please Check!\r\n");
delay_ms(100);
}
NRF24L01_RX_Mode();
*/
Sensor_Init_Flag.NRF24L01_Okay=1;
QuadInit();
/*******************IMU初始化开始*************************/
delay_ms(2000);
/***********MPU6050初始化***************/
IIC_GPIO_Config();
InitMPU6050_GY86();
delay_ms(500);
IMU_Calibration();
Sensor_Init_Flag.MPU6050_Okay=1;
/***********HMC5883初始化***************/
delay_ms(100);
QuadInit();
/***********磁力计+气压计初始化***************/
delay_ms(500);
#ifdef IMU_BOARD_GY86
HMC5883L_Initial();
Sensor_Init_Flag.Mag_Okay=1;
QuadInit();
Baro_init();
Read_MS5611_Offset();
Sensor_Init_Flag.Baro_Okay=1;
#elsedef IMU_BOARD_NC686
IST8310_Init();
Sensor_Init_Flag.Mag_Okay=1;
QuadInit();
spl0601_init();
Sensor_Init_Flag.Baro_Okay=1;
QuadInit();
#elsedef IMU_BOARD_NC683
IST8310_Init();
Sensor_Init_Flag.Mag_Okay=1;
QuadInit();
FBM320_Init();
Sensor_Init_Flag.Baro_Okay=1;
QuadInit();
#endif
/*******************IMU初始化结束*************************/
Quad_Start_Bling();//LED开机预显示
delay_ms(500);
Parameter_Init();//传感器参数初始化
LCD_CLS();//清屏
USART2_Init(19200);//串口2、备用
USART3_Init(115200);//串口3、解析GPS
Total_PID_Init();//PID控制器初始化
TIM2_Configuration_Cnt();//TIM2
Timer4_Configuration();//TIM3
NVIC_Configuration();//中断优先级设置
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure; //定义NVIC初始化结构体
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //优先级组别2,具体参见misc.h line80
/*
//-----NRF24L01数据中断-----//
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //IRQ中断通道-->NRF24L01,PB12
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢先式优先级别
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //副优先级别
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能通道
NVIC_Init(&NVIC_InitStructure); //初始化NVIC
*/
//飞控系统定时器
NVIC_InitStructure.NVIC_IRQChannel =TIM2_IRQn ;//计数定时器
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//超声波
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//PPM接收机
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//GPS数据接收中断
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;//串口中断3
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//串口2、光流模块
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口中断1
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//USART_Cmd(USART3, ENABLE);
//飞控控制定时器
NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn;//主控制定时器
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
首先定义一个名为Sensor_Init_Flag的结构体:
Sensor_Okay_Flag Sensor_Init_Flag;
typedef struct
{
uint16 NRF24L01_Okay:1;
uint16 MPU6050_Okay:1;
uint16 Mag_Okay:1;
uint16 Baro_Okay:1;
}Sensor_Okay_Flag;
进入到void HardWave_Init(void)函数
首先是SystemInit();//时钟初始化,这个是库函数在 系统初始化函数SystemInit讲解里有解释
cycleCounterInit();//系统滴答时钟初始化,程序精准延时
如果到这个追终到这个函数的定义里面去看很容易就发现这就是个得出当前系统时钟频率的函数
void cycleCounterInit(void)
{
RCC_ClocksTypeDef clocks;
RCC_GetClocksFreq(&clocks);
usTicks = clocks.SYSCLK_Frequency / 1000000;
}
// Return system uptime in microseconds (rollover in 70minutes)
//返回 us
固件库里的解释显示该函数返回不同片上时钟的频率
![]()
SysTick_Config(SystemCoreClock / 1000)//SysTick开启系统tick定时器并初始化其中断,1ms
这个函数的解释可以在
回顾※STM32入门学习之_SysTick_Config()函数的SysTick时钟配置和
CRAZEPONY飞控学习(一)参考一下
USART1_Init(115200);//主串口初始化
就是一个简单的串口初始化,设置串口和波特率
定义:
void USART1_Init(unsigned long bound)//根据USART_InitStruct中指定的参数初始化外设USART1寄存器,并设置波特率
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = bound;//设置波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8bits,在一个帧中传输或者接收到的数据位数8位或者9位,这里选8位
USART_InitStructure.USART_StopBits = USART_StopBits_1;//stop bit is 1,定义了发送的停止位数目,在帧结尾传输1个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//no parity,定义了奇偶模式,奇偶失能
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//no Hardware Flow Control//指定了硬件流控制模式使能还是失能
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//enable tx and rx//指定了使能或者失能发送和接收模式
USART_Init(USART1, &USART_InitStructure);//初始化外设USART1寄存器
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//rx interrupt is enable,使能或者失能指定的USART中断,接收中断
USART_Cmd(USART1, ENABLE);//使能或者失能USART外设
}
接下来:
OLED_Init(); //显示屏初始化
void OLED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOC, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);JTAG-DP失能 + SW-DP使能,改变指定管脚的映射
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 |GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化gpio
OLEDInit();
}
对于OLEDInit:
Bling_Init(); //指示灯、测试IO初始化,指示灯初始化
Bling_Init(); //指示灯、测试IO初始化
void Bling_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;//定义一个GPIO_InitTypeDef的结构体,具体定义于文件“stm32f10x_gpio.h”或者参考固件库使用手册
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|
RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|
RCC_APB2Periph_AFIO,ENABLE);//打开GPIOA(B,C,D)的时钟H和功能复用IO时钟
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;//选择待设置的GPIO管脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//最高输出速率50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_15;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd![]()
Key_Init(); //按键初始化
按键初始化就是GPIO_Pin_8 | GPIO_Pin_9初始化,
void Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
PPM_Init(); //PPM遥控器接收初始化
void PPM_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;//GPIO_Pin_0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//输入下拉
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource8);//选择GPIO管脚用作外部中断线路,
//选择PIOB用作外部中断线源的GPIO端口,GPIO_PinSource8待设置的外部中断线路
EXTI_InitStructure.EXTI_Line = EXTI_Line8;//外部中断线8
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//设置EXTI线路为中断请求
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//设置输入线路上升沿为中断请求
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//用来定义选中线路的新状态。它可以被设为ENABLE或者DISABLE
EXTI_Init(&EXTI_InitStructure);//数初始化外设EXTI寄存器
//EXTI->IMR &=~EXTI_Line2;//关闭外部中断
}
HC_SR04_Init(); //超声波初始化
void HC_SR04_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//下拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
EXTI_InitStructure.EXTI_Line = EXTI_Line1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
EXTI->IMR &=~EXTI_Line1;//关闭外部中断???????
}
PWM_Init(); //PWM初始化—TIM4
void PWM_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint16_t prescalerValue = 0, ccr1_PWMVal = 0;
PWM_GPIO_Init();
prescalerValue = (u16) (SystemCoreClock / 1000000)-1;//10us
//-----TIM3定时配置-----//
TIM_TimeBaseStructure.TIM_Period = MAX_PWM; //40000/2M=20ms-->50Hz,
//从0开始计数,这个值被写入到Auto-Reload Register中,设置了在下一个更新事件装入活动的自动重装载寄存器周期的值。它的取值必须在0x0000和0xFFFF之间。
TIM_TimeBaseStructure.TIM_Prescaler = 0; //暂时不分频,设置了用来作为TIMx时钟频率除数的预分频值。它的取值必须在0x0000和0xFFFF之间。
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //时钟分割,设置了时钟分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //重复比较次数更新事件
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_PrescalerConfig(TIM3, prescalerValue, TIM_PSCReloadMode_Immediate);//预分频,现在计时器频率为20MHz
//-----PWM配置-----//
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1-->向上计数为有效电平
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = ccr1_PWMVal; //duty cycle
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC1Init(TIM3, &TIM_OCInitStructure); //初始化外设TIM3 OC1-->Motor1
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //初始化外设TIM3 OC2-->Motor2
TIM_OC3Init(TIM3, &TIM_OCInitStructure); //初始化外设TIM3 OC3-->Motor3
TIM_OC4Init(TIM3, &TIM_OCInitStructure); //初始化外设TIM3 OC4-->Motor4
TIM_ARRPreloadConfig(TIM3, ENABLE);//自动重载寄存器使能,下一个更新事件自动更新影子寄存器
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIM3在CCR2上的预装载寄存器,在更新事件时,值才被写入到CCR
TIM_Cmd(TIM3, ENABLE);
PWM_Set(1000,1000,1000,1000);
}
其中:
void PWM_GPIO_Init(void )
{
GPIO_InitTypeDef GPIO_InitStructure;
//开始TIM4 的时钟 及GPIOB时钟 和AFIO时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//定时器3作为PWM输出
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO ,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
//设置PA5、PA66、PB0、PB1 为推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;//
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//输出速率
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;//
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
而对于PWM_Set具体定义
函数名:void PWM_Set(const u16 pwm1, const u16 pwm2, const u16 pwm3, const u16 pwm4)
说明:PWM设置
入口:无
出口:无
备注:根据PWM的数值给与相应PWM信号灯的状态:
当PWM为0时,灯灭
不为0时,灯亮
************************************************************************************/
void PWM_Set(const uint16_t pwm1, const uint16_t pwm2, const uint16_t pwm3, const uint16_t pwm4)
{
TIM_SetCompare1(TIM3, pwm1);
TIM_SetCompare2(TIM3, pwm2);
TIM_SetCompare3(TIM3, pwm3);
TIM_SetCompare4(TIM3, pwm4);
}
Sensor_Init_Flag.NRF24L01_Okay=1;变量赋值
QuadInit();//初始化并显示
uint8 QuadShow_Cnt=0;
void QuadInit(void)
{
QuadShow_Cnt++;
delay_ms(100);
if(QuadShow_Cnt==4) {LCD_CLS();delay_ms(500);}
if(QuadShow_Cnt<=3)
{
LCD_P8x16Str(0,0,"NamelessCotrun");
if(Sensor_Init_Flag.NRF24L01_Okay==1) LCD_P8x16Str(10,2,"NRF Is Okay");
if(Sensor_Init_Flag.MPU6050_Okay==1) LCD_P8x16Str(10,4,"MPU Is Okay");
if(Sensor_Init_Flag.Mag_Okay==1) LCD_P8x16Str(10,6,"Mag Is Okay");
}
else
{
LCD_P8x16Str(0,0,"NamelessCotrun");
if(Sensor_Init_Flag.Baro_Okay==1) LCD_P8x16Str(10,2,"MS Is Okay");
}
这个初始化里面用了好多LCD里面的函数查查!
delay_ms(2000);//延时
/***********MPU6050初始化***************/
IIC_GPIO_Config();
InitMPU6050_GY86();
delay_ms(500);
IMU_Calibration();
其中第一个函数看定义应该是GPIO的IIC设置,但是具体定义是初始化GPIO,点亮GPIOB6和7管脚
void IIC_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
delay_ms(10);
GPIO_SetBits(GPIOB,GPIO_Pin_6 | GPIO_Pin_7);
}
Sensor_Init_Flag.MPU6050_Okay=1;
按键扫描:
void Key_Scan()
{
if(QuadKey1==0)
{
delay_ms(10);///消抖
if(QuadKey1==0)
{
while(QuadKey1==0);//向下翻页
Page_Number++;
if(Page_Number>=10) Page_Number=10;
LCD_CLS();//LCD复位
}
}
if(QuadKey2==0)
{
delay_ms(10);
if(QuadKey2==0)
{
while(QuadKey2==0);
Page_Number--;//向前翻页
if(Page_Number<=0) Page_Number=0;
LCD_CLS();
}
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)