教你做一个属于自己的平衡小车,用STM32F103单片机实现(代码篇)

2023-05-16

平衡小车软件篇

平衡小车硬件篇

目录

一、定时器相关代码

1、TIM2

2、TIM3和TIM4

二、中断相关代码

三、电机相关代码

四、OLED屏幕和MUP6050相关代码

五、PID函数

1、直立环

2、速度环

3、转向环

六、控制函数

七、扩展篇

八、效果展示


 说明:本篇文章适用于有点STM32单片机基础,和有相关的硬件基础,并且想做一个小项目的人,可以作为一个参考,当然了没有基础的也可以

如果需要代码的话可以私聊我,供参考

下面就进行我们的代码部分

一、定时器相关代码

我这里使用了三个定时器,分别是TIM2,TIM3,TIM4,定时器2用于产生两路PWM波,用来控制小车的速度,TIM3和TIM4用来对编码器的脉冲进行计数,实现电机的闭环控制。

1、TIM2

#include "pwm.h"

void PWM_Init_TIM2(u16 psc,u16 arr)
{
	GPIO_InitTypeDef GPIO_InitPwm;        //GPIO初始化
	TIM_TimeBaseInitTypeDef TIM_PwmInit;  //定时器初始化
	TIM_OCInitTypeDef TIM_OcPwminit;      //指定定时器输出通道初始化
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //配置GPIO时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

	GPIO_InitPwm.GPIO_Mode  = GPIO_Mode_AF_PP; //推完复用输出
	GPIO_InitPwm.GPIO_Pin   = GPIO_Pin_2 | GPIO_Pin_3;
	GPIO_InitPwm.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitPwm);

	TIM_PwmInit.TIM_CounterMode = TIM_CounterMode_Up; 
	TIM_PwmInit.TIM_Period = arr;
	TIM_PwmInit.TIM_Prescaler = psc;
	TIM_PwmInit.TIM_ClockDivision = TIM_CKD_DIV1; //1分频
	TIM_TimeBaseInit(TIM2, &TIM_PwmInit);

	TIM_OcPwminit.TIM_OCMode      = TIM_OCMode_PWM1 ;       //比较输出模式pwm1
	TIM_OcPwminit.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 
	TIM_OcPwminit.TIM_OCNPolarity = TIM_OCNPolarity_Low;    //互补输出极性、低电平有效

	TIM_OC3Init(TIM2, &TIM_OcPwminit);            //初始化通道
	TIM_OC4Init(TIM2, &TIM_OcPwminit);            //初始化通道

	TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); 
	TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); //控制波形是立即生效还是定时器发生下一次更新事件时被更新的
														//Enable:下一次更新事件时被更新
														//Disable:立即生效
	TIM_Cmd(TIM2, ENABLE);                      //使能TIM3的外设

}

由代码可知PWM由定时器2的通道3和通道4输出,对应到单片机引脚图就是PA2和PA3,这里要注意。

2、TIM3和TIM4

TIM3和TIM4配置都差不多,就介绍一个就可以了,定时器配置代码如下

#include "encoder.h"

void Encoder_TIM3_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_ICInitTypeDef TIM_ICInitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//初始化
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6 |GPIO_Pin_7;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);//初始化定时器。
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period=65535;
	TIM_TimeBaseInitStruct.TIM_Prescaler=0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
	
TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);//配置编码器模式
	
	TIM_ICStructInit(&TIM_ICInitStruct);//初始化输入捕获
	TIM_ICInitStruct.TIM_ICFilter=10;
	TIM_ICInit(TIM3,&TIM_ICInitStruct);
	
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//配置溢出更新中断标志位
	TIM_SetCounter(TIM3,0);//清零定时器计数值
	TIM_Cmd(TIM3,ENABLE);//开启定时器
}

这里要注意有一个配置为编码器模式的函数,函数的具体用法和函数参数什么意思就不在这里解释了,可以去查询相关资料或者后面出文章解释

TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);
	

下面就是定时器中断函数和读取编码器数据的函数了

/*********************
编码器
速度读取函数
入口参数:定时器几
**********************/
int Read_Speed(int TIMx)
{
	int value_1;
	switch(TIMx)
	{                            //单位时间内,位移就是速度
		case 3:value_1=(short)TIM_GetCounter(TIM3);TIM_SetCounter(TIM3,0);break;
                                //1.采集编码器的计数值并保存。2.将定时器的计数值清零。
		default:value_1=0;
	}
	return value_1;
}

void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=0){

		TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
	}
}

速度读取函数中,第一步采集定时器的计数值,也就是编码器的数据,并保存,第二步将定时器清零。

二、中断相关代码

针对中断这部分代码有两种解决方法,也可以用定时器实现,现在就介绍用中断实现方法,其实原理都是一样的。

#include "exti.h"

void MPU6050_EXTI_Init(void)    //中断后有一个下降沿
{
	EXTI_InitTypeDef EXTI_InitStruct;
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);//开启时钟
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//PB5配置为上拉输入
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);	
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource5);//映射
	
	EXTI_InitStruct.EXTI_Line=EXTI_Line5;
	EXTI_InitStruct.EXTI_LineCmd=ENABLE;
	EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
	EXTI_Init(&EXTI_InitStruct);
}

这里配置了一个单片机引脚为外部中断,(PB5)为什么要配置这个引脚呢?这个引脚和MPU6050的中断引脚INT相连,INT是陀螺仪的中断引脚,当采集一次数据时,就会发生一次中断,对于中断后干嘛,在后面说明。

三、电机相关代码

#include "motor.h"
/*电机初始化函数*/
void Motor_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//开启时钟
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_12 |GPIO_Pin_13 |GPIO_Pin_14 |GPIO_Pin_15;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);	
}

这个函数也就是配置4个引脚为输出引脚,和电机相连

#include "motor.h"
/*赋值函数*/
void Load(int moto1,int moto2)
{
	                          //数据正负号,对应正反转
	if(moto1>0)	Ain1=1,Ain2=0;//正转
	else 		Ain1=0,Ain2=1;//反转
	                          //加载PWM值
	TIM_SetCompare3(TIM2,GFP_abs(moto1)); //输出

	if(moto2>0)	Bin1=1,Bin2=0;
	else 		Bin1=0,Bin2=1;	
	TIM_SetCompare4(TIM2,GFP_abs(moto2));
}

这个函数是用于将PID计算输出的最终值加载到电机上,完成电机的控制。

四、OLED屏幕和MUP6050相关代码

针对这两部分的代码我都是用的官方的示例代码,这个网上都有很多的,陀螺仪只要能读到数据就可以了。

五、PID函数

平衡小车的PID函数由三部分构成,分别为直立环,速度环,转向环三部分构成,直立环就是让小车角度趋近0,速度环就是让电机速度趋近0,转向环就是让电机保持角速度为零

1、直立环

/*********************
直立环PD控制器:Kp*Ek+Kd*Ek_D
入口:期望角度、真实角度、真实角速度
出口:直立环输出
*********************/
int Vertical(float Med,float Angle,float gyro_Y)
{
	int PWM_out;
	
	PWM_out=Vertical_Kp*(Angle-Med)+Vertical_Kd*(gyro_Y-0); //gyro_Y-0 :角速度偏差
	return PWM_out;
}

直立环采用的是PD控制器,即out = Kp*Ek+Kd*Ek_D,Ek_D表示偏差的微分

2、速度环

/*********************
速度环PI:Kp*Ek+Ki*Ek_S
*********************/
int Velocity(int Target,int encoder_left,int encoder_right)
{
	static int Encoder_S,EnC_Err_Lowout_last,PWM_out,Encoder_Err,EnC_Err_Lowout;
	float a=0.7;  //低通滤波系数
	Encoder_Err = ((encoder_left+encoder_right)-Target);	//计算速度偏差
	//low_out = (1-a)*Ek+a*low_out_last;   	//对速度偏差进行低通滤波
	EnC_Err_Lowout = (1-a)*Encoder_Err+a*EnC_Err_Lowout_last;//使得波形更加平滑,滤除高频干扰,防止速度突变。
	EnC_Err_Lowout_last = EnC_Err_Lowout;//防止速度过大的影响直立环的正常工作。
	Encoder_S += EnC_Err_Lowout;//对速度偏差积分,积分出位移
	Encoder_S = Encoder_S > 10000 ? 10000 : (Encoder_S < (-10000) ? (-10000) :Encoder_S);//积分限幅
	PWM_out=Velocity_Kp*EnC_Err_Lowout+Velocity_Ki*Encoder_S;//速度环控制输出计算
	return PWM_out;    //输出
}

速度环采用的是PI控制器,即out = Kp*Ek+Ki*Ek_S,Ek_S表示偏差的积分

3、转向环

/*********************
转向环:系数*Z轴角速度
*********************/
int Turn(int gyro_Z)
{
	int PWM_out;
	PWM_out=(-0.6)*gyro_Z;    
	//	PWM_out=Turn_Kp*gyro_Z;
	return PWM_out;
}

转向环比较简单,输出就是一个系数乘以Z轴角速度就可以了

六、控制函数

代码如下

void EXTI9_5_IRQHandler(void)         //表示10ms中断时间到
{
	int PWM_out;
	if(EXTI_GetITStatus(EXTI_Line5)!=0){//一级判定,看陀螺仪有没有中断
		
		if(PBin(5)==0){//二级判定   看看有没有数据  低电平

			EXTI_ClearITPendingBit(EXTI_Line5);//清除中断标志位
			//采集编码器数据
			Encoder_Left=-Read_Speed(3);
			Encoder_Right=Read_Speed(4);
			//采集陀螺仪角度信息
			mpu_dmp_get_data(&Pitch,&Roll,&Yaw);		//角度
			MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);	//陀螺仪
			MPU_Get_Accelerometer(&aacx,&aacy,&aacz);	//加速度
			//将数据压入闭环控制中,计算出控制输出量。
			Velocity_out=Velocity(Target_Speed,Encoder_Left,Encoder_Right);	//速度环			
			Vertical_out=Vertical(Velocity_out+Med_Angle,Pitch,gyroy);		//直立环    
			Turn_out=Turn(gyroz);											//转向环							
			
			PWM_out=Vertical_out;//最终输出
			//把控制输出量加载到电机上,完成最终的的控制。
			MOTO1=PWM_out-Turn_out;
			MOTO2=PWM_out+Turn_out;
			Limit(&MOTO1,&MOTO2);	 //限幅			
			Load(MOTO1,MOTO2);		 //加载到电机上
		}
	}
}

这里就应该和前面PB5中断函数联系起来了,这里我利用的是陀螺仪采集完数据会产生中断,(这里设置陀螺仪采集数据的周期为10ms),然后就触发单片机中断,进入中断完成相应的控制。

(当然了,这里也可以不用陀螺仪中断,直接采用定时器定时10ms,然后进入定时器中断函数完成相应的控制,所以这里是非常灵活的。)

其实这个控制函数也是比较简单的,进入中断后先清除中断标志位,再读取陀螺仪和编码器的数据,将数据再压入PID控制器进行计算,计算完成后将相应的值加载到电机上就可以了,进入中断调整一次小车的姿态,一直不断的调整,这样就大概完成了平衡小车的制作。

七、扩展篇

如果有人想在小车上添加一些功能该怎么办呢?比如实现超声波避障,跟随,或者是实现蓝牙控制小车

当然了这也是可以实现的了,在速度环函数的入口参数中有一个Target_Speed变量就是期望速度,可以将这个变量单独拿出来作为二次开发接口,然后改变这个变量的值来进行小车的移动。

比如下面就是实现蓝牙控制的一部分代码

MPU_Get_Accelerometer(&aacx,&aacy,&aacz);	//加速度
/*前后*/
if((Fore==0)&&(Back==0))Target_Speed=0;//速度清零,稳在原地
if(Fore==1)Target_Speed-=2;//需要前进
if(Back==1)Target_Speed+=2;//
Target_Speed=Target_Speed>SPEED_Y?SPEED_Y:(Target_Speed<-SPEED_Y?(-SPEED_Y):Target_Speed);//限幅
/*左右*/
if((Left==0)&&(Right==0))Turn_Speed=0;
if(Left==1)Turn_Speed+=30;	//左转
if(Right==1)Turn_Speed-=30;	//右转
Turn_Speed=Turn_Speed>SPEED_Z?SPEED_Z:(Turn_Speed<-SPEED_Z?(-SPEED_Z):Turn_Speed);//限幅( (20*100) * 100   )
/*转向约束*/
if((Left==0)&&(Right==0))Turn_Kd=-0.6;//没有左右转向指令,则转向约束
else if((Left==1)||(Right==1))Turn_Kd=0;//收到左右转向指令,去掉转向约束
Velocity_out=Velocity(Target_Speed,Encoder_Left,Encoder_Right);	//速度环
            

如果想要添加超声波也是类似的方法,都是改变期望速度Target_Speed

八、效果展示

平衡小车

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

教你做一个属于自己的平衡小车,用STM32F103单片机实现(代码篇) 的相关文章

  • 深度学习知识点整理

    文章目录 数据集基础术语epochbatchNormalization 网络架构参数神经元卷积层例子 池化 pooling overlap预处理数据增强模型并行max pooling全连接层sequential模型SoftMaxSVM有监督
  • ubuntu20.04 LNMP环境搭建

    LNMP环境搭建 文章目录 LNMP环境搭建1 nginx 源码安装1 1 资源下载1 2 编译安装1 3 配置1 3 1 nginx conf配置1 3 2 将nginx添加为系统服务 1 4 验证 2 mariadb 源码安装2 1 资
  • c#连接sqlserver数据库

    之前做过java连接数据库 就以为还蛮简单的 但是中间还是踩了点坑 就连接数据库是的连接字符串的问题 我查了半天没有找到比较完整的参数设置 官网的也比较模糊不清 最后和vs的服务器与资源管理器配合 拿到了想要的参数 打开数据库 复制服务器名
  • 公文题分析

    想要抽空学点法律知识 xff0c 随时进行法律咨询 xff0c 网上办理法律事务 xff0c 怎么做 如今 xff0c 在县级市Q市 xff0c 群众只要通过手机进入 34 云司法 34 微信小程序 xff0c 就能足不出户获得优质法律服务
  • 今日申论做题感受分析

    总的来说太过于沉溺于题目所给的材料 xff0c 而忽略了自身感受和理解所带来的 xff0c 而这正也是申论希望让我们养成的能力 xff0c 我们要从宏观上形成感受 xff0c 然后再结合具体材料展开相关内容 xff0c 但是目前来说我很容易
  • 今日做题以及以后的做题思路整理

    1 言语理解不能图快只抓后面的语句 xff0c 还是要花点时间大致理解一下 2 翻译推理还是有不熟悉的地方 xff0c 后期需要弥补一下 3 逻辑填空还是需要不断积累
  • 隔年增长率变形

    普通的隔年增长率 xff1a Aa 43 Bb 61 Cc 一般会叫你通过a 和b 求出c 但是该公式的本质还是Aa 43 Bb 61 Cc xff0c 其实a和b的数值可以为任意形式 xff0c 不仅仅局限于百分数 xff0c 它仅仅只是
  • 2022.9.17

    夜抚红烛垂泪 xff0c 才觉银月满身 若人若物若非故 xff0c 心无可期念无数 流水长东恨满怀 xff0c 人生常憾憾无穷 忽下眉梢 xff0c 又上心头 xff0c 如影相随 xff0c 何羡相思
  • 2022.10.30

    新愁复旧愁 xff0c 苦痛哀伤恨
  • mininet基本操作

    mininet是由斯坦福大学基于Linux Container架构开发的一个进程虚拟化网络仿真工具 xff0c 可以创建一个包含主机 xff0c 交换机 xff0c 控制器和链路的虚拟网络 xff0c 其交换机支持OpenFlow xff0
  • 平均数的增长百分比

    设一个数A和一个数B xff0c 若A B要增长百分之30 xff0c 那么A和B的数值变化将呈现这样的规律 xff1a 1 若B不变 xff0c A增长百分之30 xff0c 则可达到整体增长百分之30 2 若A不变 xff0c B减少百
  • 2022.11.2

    字字句句切切思 心心念念欲语迟
  • 夜思 思芳愿静

    夜抚红烛垂泪 xff0c 才觉银月满身 若人若物若非故 心无可期念无数 声声难抑切切思 xff0c 心心相念欲语迟 流水长东恨满怀 xff0c 人生长憾憾无穷 才下眉梢 xff0c 又上心头 xff0c 如影相随 xff0c 何羡相思
  • 2011/11/26

    听雨听风听愁绵 xff0c 疏雨薄衣心无涟
  • 2022 12 3

    将遭遇的苦难试做上天所给予的理所当然 xff0c 当撑不下去后 xff0c 就用肉泥与血液筑就保护幸福和快乐的围墙 xff0c 人的一生便如此草草地收尾了
  • 国考申论近日书写注意点总结

    一定要审题审清楚 xff0c 它叫你概括问题就主要重心放在问题上 提前做好要点的主题词书写 xff0c 确保后续主题词的书写不会太过垃圾 一定要根据提前安排的行数进行书写 xff0c 不能因为字数的充裕就进行肆意的书写
  • 公共服务设施

    学校 xff1a 小学 xff0c 中学 xff0c 大学 xff0c 中等专业技术学校 xff0c 职业培训机构 xff0c 寄宿制高中和特殊学校 xff0c 幼 xff08 托 xff09 儿园等 医院 xff1a 综合医院 xff0c
  • 倡议书书写细节

    一般来说倡议书所给的材料是一些榜样事迹 xff0c 然后叫你去写相关的倡议书 xff0c 可能是学习榜样精神 或者是榜样行为 xff0c 但是一般来说就是从精神层面或者行为层面进行相关的倡议 当日也可以精神 行为同步倡议 这个时候倡议书的开
  • 倡议书题目所遇困难记录

    充实学习生活明确人生方向 该篇倡议书的主要书写困难在 xff1a 长期以来我训练的相关材料都是与乡村振兴 基层治理以及产业发展相关 xff0c 与榜样事迹精神提炼是相去甚远 xff0c 所以在这方面的训练就比较少 xff0c 所以相关的提炼
  • 文化共享惠民生短评

    文化共享惠民生 今日故宫博物院养心殿多件文物移驾至首都博物馆 xff0c 以亲民 开放姿态融入大众生活 但是 xff0c 各地文物资源闲置情况普遍存在 对此 xff0c 让文物走出封闭确有必要 而梁祝遗存与各地美术馆在该方面工作开展十分值得

随机推荐

  • 自然场景文本检测识别 - 综述

    自然场景文本检测识别 综述 Part II 坚果粥 xff1a 自然场景文本检测识别 综述 Part I26 赞同 1 评论文章 拥有这些背景知识后 xff0c 我们可以开始学习自然场景文本检测识别 xff08 STR xff09 的算法模
  • 议论文写作结构

  • 议论文书写总结

    观点如何引入以及背后原理 议论文的书写有一个常用的书写模板 xff0c 也就是五分三式 有人说这种模板的得分不高 xff0c 也有人只要核心内容切实 不空范 xff0c 论证严谨就也是可以的 那么议论文该如何才能写好 以下仅为随笔 xff0
  • 议论文开头的引出原理

    相信大家都写过议论文 xff0c 议论文开头如果用大家普遍的描述去形容 xff0c 便是用温和的方式将观点进行引出 xff0c 但是此句话太过浅薄 xff0c 难以深入实质 原理 议论文的开头从本质上来说 xff0c 是大脑在看到题干所给的
  • 面试总结1

    总结 xff1a 面试不是以模板为驱动 xff0c 是以题目为驱动 与申论书写类似 xff0c 以模板为驱动 xff0c 只会削足适履 xff0c 让自己没有办法较好地发挥出来 xff0c 流畅性以及自身的创新性都没有办法较好地得到体现 以
  • 模式识别 一

    模式识别 教材选择模式识别基本概念模式识别的主要方法应用领域模式识别与机器学习的区别模式识别典型过程前修基础课程课后问题解答1 简述特征空间优化的方法2 简述分类器的设计准则3 简述分类器设计的基本方法4 简述在什么情况下分类器不可分5 分
  • Docker 持久化存储 Bind mounts

    Docker 持久化存储 Bind mounts Bind mounts 的 v 与 mount 区别启动容器基于bind mount挂载到容器中的非空目录只读 bind mountcompose 中使用 bind mount 官方文档 x
  • BGP路由技术详解(一)

    BGP路由技术详解 xff08 一 xff09 前言一 BGP路由协议概述1 BGP定义2 BGP的特点3 BGP分类4 BGP的路径矢量特征5 BGP的路由器6 BGP Peer 二 自治系统AS的概念1 定义2 AS号3 传输AS中的路
  • 计算机网络知识点(三) 数据链路层

    目录 第三章 数据链路层 3 1 数据链路层的设计问题 3 1 1 提供给网络层的服务 3 1 2 成帧 3 1 3 差错控制 3 1 4 流量控制 3 2 差错检测和纠正 3 2 1 纠错码 3 2 2 检错码 3 3 基本数据链路层协议
  • IP地址划分子网

    前言 记录的内容仅是本人在学习IP的路上的一些心得体会 IP组成 网络号 43 主机号 其实说到底就是一连串的二进制 地址分类 A类 xff1a 10 0 0 0 xff5e 10 255 255 255 B类 xff1a 172 16 0
  • 电脑网络(校园网/热点)持续连不上,连上后自动断联

    ipconfig flushdns xff1a 无效重启解决 xff1a
  • 工厂模式

    1 工厂方法 针对一个产品一个工厂 span class token keyword interface span span class token class name Moveable span span class token pun
  • 使用VSCode快速提交Gitee

    使用VSCode提交Gitee 前言下载GitGitee创建仓库使用VSCode克隆仓库到本地源代码管理界面说明保存账号密码 xff0c 不用每次提交输入 前言 每次用GitHub都要FQ xff0c 所以改用Gitee 下载Git Git
  • 配置webpack-dev-server自动化

    1 注意版本 xff0c 可能会有冲突 个人建议使用以下版本 xff0c 本人没有出现冲突 34 webpack 34 34 5 42 1 34 34 webpack cli 34 34 4 9 2 34 34 webpack dev se
  • Docker容器时间和服务器时间相差8小时

    项目场景 xff1a 在微服务部署时使用docker作为容器 xff0c 部署在服务器上时间不一致 问题描述 在服务器上使用docker进行项目部署时 xff0c docker容器时间和服务器时间相差8小时 xff0c 导致插入数据库时间不
  • anaconda中使用pip无法安装库到指定环境下的问题(已解决)

    参考文章 xff1a https blog 51cto com u 15060549 4662570 login 61 from csdn 大致意思就是通过修改site py文件中的 这段代码 xff0c 将这两个变量修改为环境自身的路径即
  • 使用Java实现HDFS文件读写

    1 HDFS读文件 2 HDFS写文件 3 实例操作 3 1新建Mawen工程 3 2在pom xml中将标签中内容替换为以下代码 xff0c 静待依赖包下载完毕 lt dependencies gt lt dependency gt lt
  • GD32F303移植FreeRTOS多任务调度只能执行一个任务解决办法

    1 问题描述 GD32F303移植完FreeRTOS后创建多个任务 xff0c 运行的时候只有一个任务在运行 xff0c 其余任务处于卡死不运行状态 xff0c void start task void pvParameters taskE
  • npm显示升级到最新版本仍然显示npm为原版本的问题解决

    文章目录 前言一 问题描述二 问题原因三 解决方法1 查看npm安装路径2 修改npm全局安装路径命令3 npm更新命令 总结 前言 在升级npm版本时遇到了显示版本升级成功 xff0c 但是在继续执行npm v命令查看npm版本时仍然显示
  • 教你做一个属于自己的平衡小车,用STM32F103单片机实现(代码篇)

    平衡小车软件篇 平衡小车硬件篇 目录 一 定时器相关代码 1 TIM2 2 TIM3和TIM4 二 中断相关代码 三 电机相关代码 四 OLED屏幕和MUP6050相关代码 五 PID函数 1 直立环 2 速度环 3 转向环 六 控制函数