CRAZEPONY飞控学习(一)

本文详细介绍了四旋翼飞控系统的初始化过程,包括系统时钟配置、定时器初始化、串口设置及中断配置等内容,并对关键函数进行了深入剖析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

	

  在不久前曾研究过最近最为流行的开源飞控Pixhawk的源代码,但是由于在这之前没有接触过操作系统这个概念,在不知道代码执行流程的情况下看了几个星期的时间,脑子里还是一团乱,所以决定还是从裸机开始研究,因此再往上买了一个小的开源四旋翼作为入门。废话不多说,开始进入正题!

   按照之前看裸机程序的思路肯定先找到main文件来一个一个往下看,在这里把main函数先贴出来:

int main(void)
{

	SystemClock_HSE(9);           //系统时钟初始化,时钟源外部晶振HSEs  8*9=72MHz;
	cycleCounterInit();				// Init cycle counter
	SysTick_Config(SystemCoreClock / 1000);	//SysTick开启系统tick定时器并初始化其中断,1ms

	UART1_init(SysClock,BT_BAUD_Set); //串口1初始化
	
  NVIC_INIT();	                //中断初始化

  STMFLASH_Unlock();            //内部flash解锁

  LoadParamsFromEEPROM();

  LedInit();	                //IO初始化

  BT_PowerInit();               //蓝牙电源初始化完成,默认关闭
  MotorInit();	                //马达初始化
  BatteryCheckInit();           //电池电压监测初始化
  IIC_Init();                   //IIC初始化
	
	#ifdef IMU_SW										//使用软件解算
	MPU6050_initialize();
	#else
  MPU6050_DMP_Initialize();     //初始化DMP引擎
	#endif
	
  //HMC5883L_SetUp();           //初始化磁力计HMC5883L

  NRF24L01_INIT();              //NRF24L01初始化
	
  PowerOn();                    //开机等待
  BT_ATcmdWrite();              //蓝牙写配置
 
	BatteryCheck();

	MS5611_Init();

	IMU_Init();			// sample rate and cutoff freq.  sample rate is too low now due to using dmp.

#ifdef UART_DEBUG
	//定时器3初始化,串口调试信息输出
	TIM3_Init(SysClock,2000);
#endif

	//定时器4初始化,用于飞控主循环基准定时
	TIM4_Init(SysClock,1000);	    
	
	MotorPwmFlash(10,10,10,10);
		
	altCtrlMode=MANUAL;
	WaitBaroInitOffset();		//等待气压初始化高度完成
	
	//飞控控制主循环
  while (1)
  {
		
  }//end of while(1)
}
  这里先贴出的是while(1)函数之前的初始化代码,按理来说光是研究飞控算法的话不用太去深究这些初始化配置函数,但为了也学习下stm32单片机我准备还是多花点功夫去研究下!我们就一个一个函数来说
1)首先是SystemClock_HSE(9)这个函数。HSE是高速外部时钟,可接石英/陶瓷谐振器或接外部时钟源,范围是4MHZ-16MHZ。但这了的9并不代表选择了9MHZ。我们再来看这个函数定义
可以看到这个有参函数定义的参数名是PLL,在这里指的就是锁相环频倍数,也就是就9倍,以8MHZ的外部时钟作为时钟输入源,在这里就是初始化系统时钟8*9=72MHZ;
2)cycleCounterInit()如果到这个追终到这个函数的定义里面去看很容易就发现这就是个得出当前系统时钟频率的函数

3)SysTick_Config(SystemCoreClock / 1000):这是个SysTick定时器的初始化函数,一开始我不明白为什么还要初始化这个SysTick定时器,不是只用到了TIM3和TIM4两个定时器来进行程序的定时中断处理吗。通过查询才明白这个定时器多是为了精准的延时而使用的。首先它是已计数的方式定时,72M的主频就是每隔1/72M秒计数加一,要实现1MS的中断就是0.001/1/72M=72000次。达到计数后会进入定时中断处理函数中

void SysTickHandler(void)

{

    TimingDelay_Decrement();

}

  
void TimingDelay_Decrement(void)    
  
{    
  
    
  
  if (TimingDelay != 0x00)    
  
  {     
  
    TimingDelay--;    
  
  }  
  
} 
这个TimingDelay又在哪里被赋值的呢?我们再看看Delay()函数

void Delay(__IO uint32_t nTime) 
  
{   
  
  TimingDelay = nTime;  
  
   
  
  while(TimingDelay != 0);  
  
}
4)UART1_init(SysClock,BT_BAUD_Set);就是一个简单的串口初始化,设置串口和波特率

5)NVIC_INIT();我们直接看函数的定义

void NVIC_INIT(void)
{
    TimerNVIC_Configuration();//定时器中断配置
    UART1NVIC_Configuration();//串口1中断配置
}
void TimerNVIC_Configuration()
{
    NVIC_InitTypeDef NVIC_InitStructure;
    
    /* NVIC_PriorityGroup 2 */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    //TIM3
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//串口打印定时器,优先级低于姿态解算
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    //TIM4
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//飞控主循环基准定时器,优先级高于串口打印
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

} 


void UART1NVIC_Configuration(void)
{
        NVIC_InitTypeDef NVIC_InitStructure; 
        /* Enable the USART1 Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}
可以看到在里面设置了串口和定时器中断的先占优先级和从优先级并使能中断。

5)LoadParamsFromEEPROM();字面意思就很好理解,从外部储存器EEPROM中读取参数或给EEPROM中写入值;



### 关于电赛凌霄飞控学习路线 #### 、基础知识准备 在深入研究凌霄飞控之前,建议掌握些基础理论知识。这些知识对于理解飞控系统的原理至关重要。 1. **PID控制器** PID控制器是飞控系统的核心之,了解比例(P)、积分(I)和微分(D)的作用及其参数调节方法是非常重要的[^1]。可以通过模拟环境测试不同的PID参数设置对飞行稳定性的影响。 2. **传感器融合** 掌握IMU(惯性测量单元)的工作原理以及如何利用加速度计、陀螺仪的数据进行姿态估计。卡尔曼滤波器或互补滤波器的应用也是不可忽视的部分[^1]。 3. **嵌入式编程** 学习C/C++语言并熟悉ARM Cortex-M系列处理器架构及相关外设接口(SPI, I2C, UART等)[^2]。这是因为在实际项目中往往需要用到裸机程序设计能力来优化性能。 #### 二、实践操作指南 1. **硬件搭建** - 获取套完整的凌霄飞控套件,包括主板、ESC(电子调速器)、电机及其他必要组件。 - 参考官方文档完成基本连接配置,并确保所有设备正常通信。 2. **软件调试工具安装与使用** - 下载对应版本的地面站软件(GCS),如QGroundControl或其他支持该型号的产品。 - 利用地面站界面调整初始参数,观察实时反馈数据变化情况。 3. **代码阅读与修改尝试** - 如果计划参与更深层次定制,则需下载开源固件源码至本地IDE环境中编译运行。 - 对现有功能模块逐剖析,找出感兴趣部分加以改进扩展;例如增加额外输入信号处理逻辑或是改变默认行为模式等等。 4. **实验验证环节** 开展系列循序渐进的小型试验以检验所学成果的有效性。比如手动操控下的悬停表现评估、预定义轨迹跟踪准确性衡量等方面均应有所涉猎。 #### 三、推荐资源列表 - 官方网站及论坛:这里通常包含了详尽的技术资料说明文件还有活跃社区成员分享的经验心得等内容可供查阅借鉴; - YouTube视频教程集合:许多开发者录制了直观易懂的教学短片演示具体步骤流程便于模仿学习; - GitHub仓库链接地址:可找到最新版库代码提交记录历史以便追踪更新动态及时跟进前沿进展趋势。 ```python # 示例代码片段展示如何初始化UART串口通讯 import serial def init_uart(port='/dev/ttyUSB0', baudrate=9600): try: ser = serial.Serial(port, baudrate) print(f"Serial port {port} opened successfully.") return ser except Exception as e: print(e) if __name__ == "__main__": uart_instance = init_uart() ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值