毕业设计 基于stm32的智能平衡小车 - 单片机 物联网嵌入式

news2024/11/24 0:54:46

文章目录

  • 0 前言
  • 1 项目背景
  • 2 设计思路
  • 3 硬件设计
  • 4 软件设计
    • 4.1 核心PID控制
    • 4.2 直立控制程序设计
    • 4.3 速度控制程序设计
    • 4.4 方向控制程序设计
    • 4.5 关键代码
  • 5 最后


0 前言

🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩 基于stm32的智能平衡小车

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:4分
  • 创新点:4分

在这里插入图片描述

🧿 项目分享:

https://gitee.com/sinonfin/sharing


1 项目背景

随着机器人研究的进一步深入,在工业生产、安防系统、智能家居、物流网等领域的应用更加广泛,在实际应用中,可能遇到复杂的任务环境。相比多轮的轮式机器人,两轮自平衡机器人体积小,运动灵活,能够在比较狭窄、需要大转角的场合中运动[1]。这种机器人两轮共轴,可以通过运动保持自身平衡,能实现前进、后退、转向、原地静止等基本运动功能,由于其结构特殊,能适应不同的地形环境,研究两轮自平衡机器人,具有重要的意义。

其次,两轮自平衡车还可以作为代步交通工具。相比传统的代步工具如自行车、电动车等,两轮自平衡车体积大幅减小,重力大幅减。运动灵活,绿色环保。

2 设计思路

从控制的角度来看,电机是系统唯一的控制对象。车模运动控制任务可以分解成以下三个基本控制任务:

(1) 直立控制任务:车模的倾角作为控制的输入量,使用PD算法,控制车模稳定在平衡位置。

(2) 速度控制任务:直立车模的速度控制与普通的车模速度控制不同,在直立系统中,速度控制是通过改变车模倾角来完成的。具体实施思路是,对电机转速加入干扰,使车身偏离平衡位置,以此刺激直立控制任务,从而达到控制速度的目的,速度控制使用PI算法。

(3) 方向控制任务:通过控制两个电机的差速来达到转向的目的,方向控制使用PD算法,使用X轴的角速度作为微分项的因子,可以极大改善转向的动态性能,避免振荡。

在这里插入图片描述

3 硬件设计

该小车学长采用一个主控电路板+一个电机驱动电路板的结构,将两者分开设计,一是可以避免电机驱动对主控的影响及电磁干扰,二是出于经济的考虑。

主控电路板主要包括以下部分:微控制器电路、电源管理电路、微控制器接口、按键电路、蜂鸣器电路。其中,电源管理电路分为3.3V电源管理电路和5V电源管理电路,5V管理电路使用LM2940三端线性稳压器,输入7.2V电池电压,输出5V电压。3.3V管理电路使用LM1117三端线性稳压器,输入接LM2940的5V电压,输出3.3V电压。考虑到本系统中器件、传感器较多,因此5V管理电路和3.3V管理电路均使用两个。微控制器接口主要包括:OLED接口、蓝牙接口、MMA7361传感器接口、L3G4200D传感器接口、编码器正交解码接口2个、四通道PWM接口、遥控器解码接口,以及预留IO,方便调试使用。

在这里插入图片描述
原理图

在这里插入图片描述

4 软件设计

在这里插入图片描述

4.1 核心PID控制

在自动控制中,按照偏差(目标值与反馈值之差)的比例§、积分(I)、微分(D)的组合进行控制的方法称为PID控制算法,由于其原理简单、稳定性好、可靠性高、易于调整等优点,在自动控制领域应用最为广泛,已有近70年历史,现有的很多控制方法都是基于PID控制算法发展演变而来。当我们对目标系统和控制对象的模型不够了解,或者不能得到控制系统的参数时,PID控制算法尤为适用。

在这里插入图片描述

1)比例控制部分:成比例地反应控制系统的偏差信号e(t),偏差一旦产生,调节器立即产生控制作用以减小偏差,其控制作用最为明显。

2)积分控制部分:积分控制作用的强弱取决于积分时间常数Ti,Ti越大,积分作用越弱,反之则越强。积分控制主要用于消除静差,提高系统的无差度。

3)微分控制部分:微分控制的计算因子是偏差的变化率,能够抑制偏差的变化,并偏差的值变得太大之前,引入一个早期修正量,达到加快系统响应调节速度的目的。积分控制可以提高系统的动态性能,提高反应速度,克服振荡。

PID控制算法的计算结果是偏差信号的比例、积分、微分三部分的线性叠加,偏差值e(t)即目标值r(t)与反馈值c(t)的差,属于闭环控制系统,因此需要使用传感器构成反馈回路。

4.2 直立控制程序设计

车模平衡控制需要负反馈,就需要能够测量车体的倾角,构成反馈回路。在能够测量倾角的情况下,设定目标平衡角度,使用PID算法进行闭环控制。因为车体只会在一个的方向上运动,只存在一个维度的倾斜,因此只需要测量一个维度的倾角,然后控制轮子转动,抵消车体在该维度上的倾斜,就可以完成平衡控制

在这里插入图片描述

算法流程

在这里插入图片描述

关键代码

void Angle_Calculate()
{
int16_t AngleControlOut_P,AngleControlOut_D;
	angle_Accel = (A_Z-AZ_ZERO);  
	angle_Accel*=0.0039f;
	angle_Accel = asin(angle_Accel);
	angle_Accel*=500;
	Gyro_Now = (T_Y-TY_OFFSET) * TY_Ratio;
	Erjie_Lvbo(angle_Accel,Gyro_Now);
	if(FilterSwitch==0)	myfilter=QingHua_AngleCalaulate;
	else if(FilterSwitch==1)	myfilter=Yijie_Lvbo;
	else if(FilterSwitch==2)	myfilter=Erjie_Lvbo;
	else if(FilterSwitch==3)	myfilter=Kalman_Filter;
	if(FilterSwitch==3)
	{
		myfilter(angle_Accel,Gyro_Now);
		ZL.error=angle_now_kal-(Balance_Point);
	}	
	else
	{
		myfilter(angle_Accel,Gyro_Now);
		ZL.error=angle_now-(Balance_Point);
	}
    AngleControlOut_P=-(int16_t)(ZL.P*ZL.error);
    AngleControlOut_D=-(int16_t)(ZL.D*Gyro_Now);
    if(AngleControlOut_D>500) AngleControlOut_D=500;//对微分项限幅
    else if(AngleControlOut_D<-500) AngleControlOut_D=-500;
    AngleControlOut=AngleControlOut_P+AngleControlOut_D;
    if(AngleControlOut>800) AngleControlOut=800;
    else if(AngleControlOut<-800) AngleControlOut=-800;
}

4.3 速度控制程序设计

直立车模的速度控制方法与普通车模的速度控制方法不同,因为普通车模的电机只需要控制转动,而直立车模的电机输出是平衡控制、速度控制、方向控制三部分之间的叠加。

因为直立系统的首要任务是保持直立,当车模倾角发生改变,车模就会在直立控制的作用下向倾斜方向运动。速度控制就是利用了直立系统的这种特性

在这里插入图片描述

void Speed_Calculate()
{ 
	
		SP.goal=(t1-t1_mid)/10;
		if(SP.goal>50) SP.goal=50;
	  else if(SP.goal<-30) SP.goal=-30;
	
    SpeedControlOut_Old=SpeedControlOut;
    SP.error=(SP.goal)-(Speed_L+Speed_R)/2;
    SP.error_sum+=SP.error;
   if(SP.error_sum>200) SP.error_sum=200;//积分限幅
   else if(SP.error_sum<-200) SP.error_sum=-200;
		SpeedControlOut=-(int16_t)((SP.P)*SP.error+SP.I*SP.error_sum);
    if(SpeedControlOut>300) SpeedControlOut=300;//速度环输出限幅
    else if(SpeedControlOut<-300) SpeedControlOut=-300;
}

4.4 方向控制程序设计

直立车模的转向是通过两轮的差速来完成的,转向控制使用PD算法,本系统不具备自主识别路径的功能,因此PD算法的输入参数使用遥控器完成。为了改善转向的动态特性,避免振荡,对PD算法做了修改,微分项的因子不再使用传统的e(t)-e(t-1),而是使用陀螺仪的X轴,因为陀螺仪输出灵敏度更高

在这里插入图片描述

void Direction_Calculate(int16_t bias)
{
		DIR.last_error=DIR.error;
		DIR.error=bias/6-dmp_yaw;
		DIR.error_sum+=DIR.error;
		if(DIR.error_sum>2000) DIR.error_sum=2000;
	  else if(DIR.error_sum<-2000) DIR.error_sum=-2000;
		DirectionControlOut_Old=DirectionControlOut;
	  DirectionControlOut = DIR.P*DIR.error
							 + DIR.I*DIR.error_sum
							 + DIR.D*(T_X-TX_OFFSET);
		
	
		DirectionControlOut_Old=DirectionControlOut;
		DirectionControlOut=bias*0.15f;
		if(DirectionControlOut>300) DirectionControlOut=300;
		else if(DirectionControlOut<-300)	DirectionControlOut=-300;
}

互补滤波法调试结果

在这里插入图片描述

4.5 关键代码

int main()
{
	uint8_t	dirswitchtemp,spswitchtemp;
  SmartCar_Init();
  while(1)
  {
	  VisualScope_Out();
	   while(DMA_IsMajorLoopComplete(HW_DMA_CH2));

			if(StandUp_Flag==1&&IS_RUNNING==0)
			{
				dirswitchtemp=DirectionControlSwitch;//保存之前的开关
				spswitchtemp =SpeedControlSwitch;
				DirectionControlSwitch=0;
				  SpeedControlSwitch=0;
					ZL.P*=1.5f;
					ZL.D*=1.5f;
					DelayMs(500);
					Motor_Enable();
					IS_RUNNING=1;//将小车运行标志置位
					DelayMs(500);
					StandUp_Flag=0;
					DelayMs(1000);
					ZL.P/=1.5f;
					ZL.D/=1.5f;
					SpeedControlSwitch=dirswitchtemp;
					DirectionControlSwitch=dirswitchtemp;
			}
  }
}

void PIT0_ISR()
{
    static uint16_t FindZeroIndex=0;
		systime_speed++;//速度控制节拍+1
		systime_direction++;//方向控制节拍+1
		ADC_GetDataAndFilter();
		Angle_Calculate();
		//Yaw_Calculate();
		if(systime_direction==5)
		{
				//HMC_angle=Get_Angle();
				systime_direction=0;
				Dr_Smooth=0.2;
				Direction_Calculate(t2-t2_mid);
		}
     if(systime_speed==20)
    {
		systime_speed=0 ;
		GPIO_ToggleBit(HW_GPIOE,26);//闪烁
		  Sp_Smooth=0.05;//重置平滑系数
		 Get_Speed();
        Speed_Calculate();
    }
    if(FindZeroFlag)
    {
        FindZeroIndex++;
          if(FindZeroIndex>=400)//说白了按下键之后两秒才开始记录数据
          {
              GYROY_SUM+=T_Y;
			  GYROX_SUM+=T_X;
                  if(FindZeroIndex>=499)
                  {
                      FindZeroFlag=0;//次数够了,清标志位
                      FindZeroIndex=0;
                      TY_OFFSET=GYROY_SUM*0.01f;
					  TX_OFFSET=GYROX_SUM*0.01f;
					  GYROX_SUM=0;
                      GYROY_SUM=0;
                  }
          }
    }
    Motor_Output();
}


void SmartCar_Init()
{
  DelayInit();
	/******Debug_初始化******/
	/*******主要是DMP用到了printf*********/
	UART_QuickInit(UART3_RX_PE05_TX_PE04,115200);
	UART_SelectDebugInstance(HW_UART3);				
    //**********LED初始化,用作系统运行指示***********//
  GPIO_QuickInit(HW_GPIOE,26,kGPIO_Mode_OPP);
  GPIO_SetBit(HW_GPIOE,26);
    /********OLED初始化**************/
    OLED_Init();
	//**************模拟加速度计陀螺仪初始化*****************/
	
	GPIO_QuickInit(MMA7361_EN,kGPIO_Mode_OPP);
	GPIO_SetBit(MMA7361_EN);												//使能MMA7361
	ADC_QuickInit(ADC_ACCEL_Z,kADC_SingleDiff10or11);//单端12位输入
	//**************IIC及L3G4200D\HMC5883初始化******************//
	I2C_QuickInit(I2C0_SCL_PD08_SDA_PD09,I2C_SPEED);
   L3G4200D_Init();
		
	
	CT_IIC_Init();
		while(mpu_dmp_init())
		{
			OLED_P8x16Str(0,0,"DMP Error");
			OLED_P8x16Num(0,0,mpu_dmp_init());
			DelayMs(200);
		}
	OLED_P8x16Str(0,0,"DMP    OK!");
		/****DMP数据输出中断*/
		GPIO_QuickInit(HW_GPIOE,4,kGPIO_Mode_IFT);	//DMP输出输出中断
		 GPIO_CallbackInstall(HW_GPIOE,GPIOE_ISR);
		 GPIO_ITDMAConfig(HW_GPIOE,4,kGPIO_IT_FallingEdge,true);
  /****************PWM初始化*****************/
    FTM_PWM_QuickInit(FTM0_CH0_PC01,kPWM_EdgeAligned,10000);
    FTM_PWM_QuickInit(FTM0_CH1_PC02,kPWM_EdgeAligned,10000);
    FTM_PWM_QuickInit(FTM0_CH2_PC03,kPWM_EdgeAligned,10000);
    FTM_PWM_QuickInit(FTM0_CH3_PC04,kPWM_EdgeAligned,10000);
	
    FTM_PWM_ChangeDuty(FTM_PWM_LEFT,0);
    FTM_PWM_ChangeDuty(FTM_PWM_LEFT_,0);
    FTM_PWM_ChangeDuty(FTM_PWM_RIGHT,0);
    FTM_PWM_ChangeDuty(FTM_PWM_RIGHT_,0);
  /**************FTM正交解码初始化**************/
  /***********初始化位 脉冲-方向型编码器**********/
    FTM_QD_QuickInit(FTM1_QD_PHA_PB00_PHB_PB01,kFTM_QD_NormalPolarity,kQD_CountDirectionEncoding);
    FTM_QD_QuickInit(FTM2_QD_PHA_PB18_PHB_PB19,kFTM_QD_NormalPolarity,kQD_CountDirectionEncoding);
    
    GPIO_QuickInit(DIR_LEFT,kGPIO_Mode_IFT);//左边编码器方向角设置为悬空输入
    GPIO_QuickInit(DIR_RIGHT,kGPIO_Mode_IFT);//右边编码器方向角设置为悬空输入
  //**********************串口初始化********/
     UART_QuickInit(UART4_RX_PE25_TX_PE24,115200);
    UART_ITDMAConfig(HW_UART4,kUART_DMA_Tx,true);
    UART_DMASendConfig(HW_UART4,HW_DMA_CH2);
  //**********************按键中端配置************/
    GPIO_QuickInit(KEY_GPIO,KEY_OK,kGPIO_Mode_IPU);
    GPIO_QuickInit(KEY_GPIO,KEY_UP,kGPIO_Mode_IPU);
    GPIO_QuickInit(KEY_GPIO,KEY_DOWN,kGPIO_Mode_IPU);
    GPIO_QuickInit(KEY_GPIO,KEY_LEFT,kGPIO_Mode_IPU);
    GPIO_QuickInit(KEY_GPIO,KEY_RIGHT,kGPIO_Mode_IPU);
		
    GPIO_CallbackInstall(KEY_GPIO,GPIOA_ISR);//按键中断回调函数
    GPIO_ITDMAConfig(KEY_GPIO,KEY_OK,kGPIO_IT_FallingEdge,true);
    GPIO_ITDMAConfig(KEY_GPIO,KEY_UP,kGPIO_IT_FallingEdge,true);
    GPIO_ITDMAConfig(KEY_GPIO,KEY_DOWN,kGPIO_IT_FallingEdge,true);
    GPIO_ITDMAConfig(KEY_GPIO,KEY_LEFT,kGPIO_IT_RisingEdge,true);
    GPIO_ITDMAConfig(KEY_GPIO,KEY_RIGHT,kGPIO_IT_FallingEdge,true);
		    //*************解码通道配置****************/  
		GPIO_QuickInit(HW_GPIOD,12,kGPIO_Mode_IFT);				
 		GPIO_QuickInit(HW_GPIOD,13,kGPIO_Mode_IFT);
		GPIO_QuickInit(HW_GPIOD,14,kGPIO_Mode_IFT);
    
    GPIO_CallbackInstall(HW_GPIOD,GPIOD_ISR);
    GPIO_ITDMAConfig(HW_GPIOD,12,kGPIO_IT_RisingFallingEdge,true);
	  GPIO_ITDMAConfig(HW_GPIOD,13,kGPIO_IT_RisingFallingEdge,true);
		GPIO_ITDMAConfig(HW_GPIOD,14,kGPIO_IT_RisingFallingEdge,true);
    //*****************PIT定时中断初始化*****************/
    PIT_QuickInit(HW_PIT_CH0,3000);
    PIT_ITDMAConfig(HW_PIT_CH0,kPIT_IT_TOF,true);
    PIT_CallbackInstall(HW_PIT_CH0,PIT0_ISR);
    /*******************NVIC配置****************/
    NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2);  //中断优先级分成2组
		NVIC_SetPriority(PORTD_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, 0, 0));//遥控器
    NVIC_SetPriority(PIT0_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, 1, 0));//周期性中断优先级
		NVIC_SetPriority(PORTE_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, 2, 0));//DMP
    NVIC_SetPriority(PORTA_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, 3, 0));//按键中断
		OLED_P8x16Str(0,2,"Hello World!");
}

5 最后

🧿 项目分享:

https://gitee.com/sinonfin/sharing

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/66616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

32、Java高级特性——日期操作类、Date类、SimpleDateFormat类、Calendar类

目录 一、日期操作类 二、Date类 1、Date类中的构造方法 2、获取系统当前时间 三、SimpleDateFormat类 1、SimpleDateFormat类中的构造方法 2、format(Date date,StringBuffer toAppendTo,FieldPosition pos)方法 四、Calendar类 1、Calendar类中的构造方法 2、Cal…

[附源码]Python计算机毕业设计SSM家政信息管理平台(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Removing the Bias of Integral Pose Regression 阅读笔记

消除积分姿态回归的偏差 ICCV2021 论文链接 补充材料链接 参考链接 摘要&#xff1a; 尽管姿态估计的回归法更直观&#xff0c;但由于热图法的优越性能&#xff0c;使其在2D人体姿态估计中占主导地位。积分回归法在架构上使用隐式热图&#xff0c;拉近了热图法与回归法。这就…

GraalVM + Springboot3 + IDEA 在widow10 上完成构建本地化服务

GraalVM是开发人员编写和执行Java代码的工具。具体来说&#xff0c;GraalVM是由Oracle创建的Java虚拟机&#xff08;JVM&#xff09;和Java开发工具包&#xff08;JDK&#xff09;。它是一个高性能的运行时&#xff0c;可以提高应用程序的性能和效率。 GraalVM的目标包括&…

【数据结构】哈希表

目录 一、哈希函数的引入 二、解决哈希冲突的思路 2.1基于闭散列的思路 2.2基于开散列的思路 2.3负载因子 三、关于哈希函数的设计 四、基于拉链法实现哈希表 4.1哈希表的内部构造 4.2插入操作 4.3扩容操作 4.4搜索操作 4.5删除操作 哈希表其实就是基于数组衍生而来…

深度解读面试题:链表中环的入口结点(附代码,可过在线OJ)

在解读“链表中环的入口结点”前&#xff0c;我认为有必要明白关于它的一些用于打基础的问题&#xff08;相交链表、判断链表中是否存在环&#xff09; 相交链表 题目&#xff1a; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点…

快收藏!!整理了100个Python小技巧!!

下面&#xff0c;我就给大家分享100个Python小技巧&#xff0c;帮助大家更好的了解和学习Python&#xff0c;欢迎收藏、关注&#xff0c;点赞支持&#xff01; ▍1、for循环中的else条件 这是一个for-else方法&#xff0c;循环遍历列表时使用else语句。下面举个例子&#xff…

根据平均值列出记录

AANSI SQL包括几个聚合函数&#xff0c;使您可以对一组值进行计算以将其结果作为单个值返回。他们包括Count(), Min(), Max(), Sum() and AVG(),以及其他。默认情况下&#xff0c;聚合函数适用于所有行&#xff0c;但是您可以通过将WHERE子句应用于SELECT语句来缩小字段的范围。…

直冲云霄,阿里大牛耗时49天整理12W字面试手册,押题准确率直冲95%

很多人都想进字节做开发&#xff0c;不论是技术还是薪资、福利都算得上TOP级~ 7月底官方再次启动扩招&#xff0c;发布了1200&#xff0b;后端工程师岗位&#xff01; 那么本批有哪些优质岗位可选择&#xff1f;薪资待遇如何&#xff1f; 下面给大家列出几类具体的岗位要求&a…

软件项目管理指南:定义、5大过程、估算及进度管理方法等

本文将分享&#xff1a;1、软件项目管理的定义&#xff1b;2、软件项目管理的过程步骤&#xff1b;3、软件项目管理的内容&#xff1b;4、软件项目估算与进度管理方法&#xff1b;5、软件开发各生命周期阶段与文档、角色间的关系&#xff1b;6、软件开发项目中的各大角色职能&a…

深度学习-第P1周——实现mnist手写数字识别

深度学习-第P1周——实现mnist手写数字识别深度学习-第P1周——实现mnist手写数字识别一、前言二、我的环境三、前期工作1、导入依赖项并设置GPU2、导入数据集3、数据可视化四、构建简单的CNN网络五、训练模型1、设置超参数2、编写训练函数3、编写测试函数4、正式训练六、结果可…

ADSP-21489的图形化编程详解(7:延时、增益、分频、反馈、响度)

延时 21489 可以做延时&#xff0c;音频高手会运用此项算法来增强音效&#xff0c;我们做个最简单的&#xff0c;让大家知道怎么用它&#xff0c;至于怎么样嵌入到自己的系统里实现更好的效果&#xff0c;则需要各位调音师专业的耳朵来判断&#xff0c;调音无上限&#xff01;…

MySQL之索引及其背后的数据结构

✨博客主页: 荣 ✨系列专栏: MySQL ✨一句短话: 难在坚持,贵在坚持,成在坚持! 文章目录一. 索引的介绍1. 什么是索引2. 索引的使用二. 索引背后的数据结构1. 考虑使用哈希表2. 二叉搜索树3. N叉搜索树(B树, B树)4. 注意事项一. 索引的介绍 1. 什么是索引 索引 (Index) 是帮助…

[激光原理与应用-39]:《光电检测技术-6》- 光干涉的原理与基础

目录 第1章 概述 1.1 什么是光干涉 1.2 产生干涉的必要条件 1.3 非相干光 - 自发辐射无法产生干涉 1.4 相干光 - 受激辐射 1.5 时间相干性 1.6 空间相干性 它山之石 第1章 概述 1.1 什么是光干涉 它是指因两束光波相遇而引起光的强度重新分布的现象。 指两列或两列以上…

Verilog入门学习笔记:Verilog基础语法梳理

无论是学IC设计还是FPGA开发&#xff0c;Verilog都是最基本、最重要的必备技能。但任何一门编程语言的掌握都需要长期学习。并不是简简单单的随便读几本书&#xff0c;随便动动脑筋那么简单。Verilog是一门基于硬件的独特语言&#xff0c;由于它最终所实现的数字电路&#xff0…

基于AVDTP信令分析蓝牙音频启动流程

前言 公司项目edifier那边需要在原来音频SBC,AAC基础上增加LHDC5.0编码&#xff0c;在打通lhdc协议栈之前&#xff0c;学习记录一番AVDTP音频服务流程。 一、AVDTP音频流基础知识 分析音频流程首先应具备的最简单基础概念知识&#xff1a;AVDTP信令signal&#xff0c;流端点se…

【JVM】垃圾回收机制详解(GC)

目录一.GC的作用区域二.关于对象是否可回收1.可达性分析算法和引用计数算法2.四种引用类型三.垃圾收集算法1.标记-清除算法2.复制算法3.标记-整理算法4.分代收集算法四.轻GC(Minor GC)和重GC(Full GC)一.GC的作用区域 可以看jvm详解之后&#xff0c;再来理解这篇文章更好 堆和…

[附源码]计算机毕业设计农村人居环境治理监管系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

ASP.NET Core 3.1系列(18)——EFCore中执行原生SQL语句

1、前言 前一篇博客介绍了EFCore中常见的一些查询操作&#xff0c;使用Linq或Lambda结合实体类的操作相当方便。但在某些特殊情况下&#xff0c;我们仍旧需要使用原生SQL来获取数据。好在EFCore中提供了完整的方法支持原生SQL&#xff0c;下面开始介绍。 2、构建测试数据库 …

Radare2 框架介绍及使用

Radare2 框架介绍及使用 欢迎入群交流 radare2 这是整个框架的核心工具&#xff0c;它具有debugger和Hexeditor的核心功能&#xff0c;使您能够像打开普通的文件一样&#xff0c;打开许多输入/输出源&#xff0c;包括磁盘、网络连接、内核驱动和处于调试中的进程等。 它实现了…