STM32F407ZGT6控制舵机(采用高级定时器8)

2023-11-12

前言

32单片机给舵机供电不足,会出现不稳定的情况(舵机鬼畜);所以要外加电源给舵机供电,利用12v锂电池,通过稳压模块降压到5.5v,提供给舵机。稳压电路的gnd一定要接上32单片机的gnd,不共地虽然能供电但数据线无法传输数据。

stm32的高级定时器8的通道一连接PC6,通道二连接PC7.

ServorCtrlAngle(2,45);	

此主函数的语句,2选择通道2,所以数据线接PC7。

main.c 代码

注意,有相当部分代码是实现其他功能的,无关驱动舵机的。

#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "oled.h"
#include "extizd.h"
#include "BaseTimX.h"
#include "htimx.h"


int int1=10;
int int2=12;

float float1=1.5;
float float2=10.25;

void oledPage0()
{
	 OLED_ShowChar(0,0,'Z');
	 OLED_ShowChar(1*8,0,'P');
	OLED_ShowChar(2*8,0,'0');

	 OLED_ShowChar(4*8,0,'F');
	 OLED_ShowChar(5*8,0,'P');
	 OLED_ShowChar(6*8,0,'0');

	
		OLED_ShowChar(0*8,1,'Z');
		OLED_ShowChar(1*8,1,'S');
		OLED_ShowChar(2*8,1,'1');
		OLED_ShowChar(3*8,1,'0');
		OLED_ShowChar(4*8,1,'0');
		OLED_ShowChar(5*8,1,'0');
	
	  OLED_ShowChar(6*8,1,'F');
		OLED_ShowChar(7*8,1,'S');
	 OLED_ShowChar(8*8,1,'0');
		OLED_ShowChar(9*8,1,'.');
	 OLED_ShowChar(10*8,1,'0');
		OLED_ShowChar(11*8,1,'1');
		
	 OLED_ShowChar(0,2,'k');
	 OLED_ShowChar(1*8,2,'m');
	 OLED_ShowChar(2*8,2,'0');

	 OLED_ShowChar(4*8,2,'a');
	 OLED_ShowChar(5*8,2,'s');
	 OLED_ShowChar(6*8,2,'0');
	 
	 	 OLED_ShowChar(0*8,3,'z');
	 OLED_ShowChar(1*8,3,'s');
	 OLED_ShowChar(2*8,3,'0');
		OLED_ShowChar(3*8,3,'=');
		 
		 
	 OLED_ShowChar(0*8,4,'x');
	 OLED_ShowChar(1*8,4,'s');
	 OLED_ShowChar(2*8,4,'0');
	 OLED_ShowChar(3*8,4,'=');
}



int main(void)
{
	u8 KeyVal=0;
	
	u32 intnum=0;
	float a=123.456;
	int i=0;

	delay_init(168); 
	LED_Init();
	BEEP_Init();//初始化 	
	
	KEY_Init();
	OLED_Init();
	delay_ms(5);
	OLED_Clear();
	
	KeyModeFlag=0;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
	oledPage0();
	BaseTimx_Init();
	TIM_Cmd(BASIC_TIM6, ENABLE);


	HTim8_Init();//初始化函数中,加一时间是1us,1000---1us===1ms
	
	TIM_Cmd(TIM8, ENABLE);

	HTim8_SetPwmFreq(50);//用定时器8控制舵机,需要频率是50HZ(周期是20ms)

	while(1)
	{
		ServorCtrlAngle(2,0);
		delay_ms(3000);
		ServorCtrlAngle(2,45);		
		delay_ms(1000);
		
		ServorCtrlAngle(2,90);		
		delay_ms(3000);
		ServorCtrlAngle(2,180);		
		delay_ms(3000);
		ServorCtrlAngle(2,270);		
		delay_ms(3000);
//		
//		ServorCtrlAngle(2,0);		
//		LED0=!LED0;
//		delay_ms(300);
//		LED0=!LED0;
//		delay_ms(300);
//		LED0=!LED0;
//		delay_ms(300);
//		LED0=!LED0;
//		delay_ms(300);
//		delay_ms(1000);


//		ServorCtrlAngleNP(1,0);
//		delay_ms(1000);
//		
//		ServorCtrlAngleNP(1,-90);
//		delay_ms(1000);
//		
//		ServorCtrlAngleNP(1,-45);
//		delay_ms(1000);
//		
//		
//		ServorCtrlAngleNP(1,-20);
//		delay_ms(1000);
//		
//		ServorCtrlAngleNP(1,0);
//		delay_ms(1000);
//		
//		ServorCtrlAngleNP(1,20);
//		delay_ms(1000);
//		
//		ServorCtrlAngleNP(1,50);
//		delay_ms(1000);
//		
//		
//		ServorCtrlAngleNP(1,90);
//		delay_ms(2000);
		
//		TIM_SetCompare1(TIM8,100);	//=======修改比较值,修改占空比
//		TIM_SetCompare2(TIM8,0);	//=======修改比较值,修改占空比
//		
//		
//		
//		
//		TIM_SetCompare1(TIM8,0);	//=======修改比较值,修改占空比
//		TIM_SetCompare2(TIM8,1000);	//=======修改比较值,修改占空比
//		
//		delay_ms(10);
		

		
		
		
		
		KeyVal=KeyScan1(KeyModeFlag);
		switch(KeyVal)
		{
			case Key4ShortClickVal: //整数加或者减
				if(FlagKeyAddSub==0)
				{
					switch(FlagIntParIndex)
					{
						case ParInt1:
							int1=int1+StepIntArray[StepIntIndex];
							if(int1>10000)int1=10;
						
							OLED_ShowNum(4*8,3,int1,5,12);

							break;
						
						case ParInt2:
							int2=int2+StepIntArray[StepIntIndex];
							if(int2>10000)int2=10;
							OLED_ShowNum(4*8,3,int2,5,12);

							break;
						
						
					}
				}
				else if(FlagKeyAddSub==1)
				{
					switch(FlagIntParIndex)
					{
						case ParInt1:
						
							if(int1<2)int1=10000;
							int1=int1-StepIntArray[StepIntIndex];
							OLED_ShowNum(4*8,3,int1,5,12);
					
							break;
						
						case ParInt2:
							if(int2<2)int2=10000;
							int2=int2-StepIntArray[StepIntIndex];
							OLED_ShowNum(4*8,3,int2,5,12);

							break;
						
						
					}
				}
				
				break;
			
			case Key4LongClickVal://长按调节整数的步长
				while(KEY4==0){};
				StepIntIndex++;
				if(StepIntIndex>=5)StepIntIndex=0;
				 OLED_ShowChar(2*8,1,' ');
				OLED_ShowChar(3*8,1,' ');
				OLED_ShowChar(4*8,1,' ');
				OLED_ShowChar(5*8,1,' ');	
				OLED_ShowNum(2*8,1,StepIntArray[StepIntIndex],4,12);

				break;
			//---------------------
			case Key5ShortClickVal://浮点数加或者减
					if(FlagKeyAddSub==0)
						{
								switch(FlagFloatParIndex)
								{
									case ParFloat1:
											float1=float1+StepFloatArray[StepFloatIndex];
											if(float1>1000.0f)float1=10.0f;
										
											OLED_ShowFloat(4*8,4,float1,2);
										break;
									
									case ParFloat2:
										float2=float2+StepFloatArray[StepFloatIndex];
										if(float2>1000.0f)float2=10.0f;
										OLED_ShowFloat(4*8,4,float2,2);
										break;
									
									
								}
						}
						else if(FlagKeyAddSub==1)
						{
							switch(FlagFloatParIndex)
								{
									case ParFloat1:
										if(float1<10.0f)float1=1000.0f;
										float1=float1-StepFloatArray[StepFloatIndex];
										OLED_ShowFloat(4*8,4,float1,2);
										break;
									
									case ParFloat2:
										if(float2<10.0f)float2=1000.0f;
										float2=float2-StepFloatArray[StepFloatIndex];
										OLED_ShowFloat(4*8,4,float2,2);
										break;
									
									
								}
						}
			
			
				break;
			
			case Key5LongClickVal://长按调节小数的步长
				while(KEY5==0){};
				StepFloatIndex++;
				if(StepFloatIndex>=5)StepFloatIndex=0;
				OLED_ShowChar(8*8,1,' ');
				OLED_ShowChar(9*8,1,' ');
				OLED_ShowChar(10*8,1,' ');
				OLED_ShowChar(11*8,1,' ');	
				OLED_ShowFloat(8*8,1, StepFloatArray[StepFloatIndex],2);	
					
				break;
			//---------------------
			case Key6ShortClickVal:
				
				break;
			
			case Key6LongClickVal://调节int参数号
				while(KEY6==0){};
				FlagIntParIndex++;
				if(FlagIntParIndex>=2)FlagIntParIndex=0;
				OLED_ShowNum(2*8,0,FlagIntParIndex,1,12);
				OLED_ShowNum(2*8,3,FlagIntParIndex,1,12);
				break;
			
			//--------------------
			case Key7ShortClickVal://启动
				
				break;
			
			case Key7LongClickVal://float 参数号
				while(KEY7==0){};
				FlagFloatParIndex++;
				if(FlagFloatParIndex>=2)FlagFloatParIndex=0;
				OLED_ShowNum(6*8,0,FlagFloatParIndex,1,12);
				OLED_ShowNum(2*8,4,FlagFloatParIndex,1,12);

				break;
			
			//---------------------
			case Key8ShortClickVal://切换连续模式或者是单按长按模式
				while(KEY8==0){};
				if(KeyModeFlag==0)KeyModeFlag=1;
				else if(KeyModeFlag==1)KeyModeFlag=0;
					
				OLED_ShowNum(2*8,2,KeyModeFlag,1,12);
				
				break;
			
			case Key8LongClickVal://保留
				while(KEY8==0){};	
				if(FlagKeyAddSub==0)FlagKeyAddSub=1;
				else if(FlagKeyAddSub==1)FlagKeyAddSub=0;
					
				if(FlagKeyAddSub==0)
					OLED_ShowChar(6*8,2,'A');
				else if(FlagKeyAddSub==1)
					OLED_ShowChar(6*8,2,'S');
				
		//		OLED_ShowNum(6*8,2,FlagKeyAddSub,1,12);
	
				break;
		
		}
		
		
		
	
	}
}

htim.c code

#include "htimx.h"

u32 Global_Timer8_Arr=100;

void HTIM8_GPIO_Config(void)
{
	/* 定义一个 GPIO_InitTypeDef 类型的结构体 */
 GPIO_InitTypeDef GPIO_InitStructure;
/* 开启定时器相关的 GPIO 外设时钟 */
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);//?? GPIOC ??	/* 指定引脚复用功能 */
	
 GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8);
 GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8);
	
	
	/* 定时器功能引脚初始化 */
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	
 GPIO_Init(GPIOC, &GPIO_InitStructure);
	
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
 
 GPIO_Init(GPIOC, &GPIO_InitStructure);

}

void HTim8Mode_Init(void)//初始化
{
	TIM_TimeBaseInitTypeDef 	TIM_TimeBaseStructure;
	TIM_OCInitTypeDef 				TIM_OCInitStructure;
	// 开启 TIMx_CLK
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
	
	/* 累计 TIM_Period 个后产生一个更新或者中断 */
	//当定时器从 0 计数到 4999,即为 5000 次,为一个定时周期
	Global_Timer8_Arr=1000;
	TIM_TimeBaseStructure.TIM_Period = Global_Timer8_Arr-1;
//定时器时钟源 TIMxCLK =168MHz
 // 设定定时器频率为 =TIMxCLK/(TIM_Prescaler+1)=168/(168-1+1)=1MHz
	TIM_TimeBaseStructure.TIM_Prescaler = 168-1;//1us加一次
	
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
	// 初始化定时器 TIMx
	TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
	
	
	
	/* ================== 输出结构体初始化 =================== */
 // 配置为 PWM 模式 1,先输出高电平,达到比较值的时候再改变电平
 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
 // 主输出使能
 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
 // 互补输出使能
 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
 // 配置比较值
 TIM_OCInitStructure.TIM_Pulse = 500;
 // 主输出高电平有效
 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
 // 互补输出高电平有效
 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
 // 主输出在被禁止时为高电平
 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
 // 互补输出在被禁止时为低电平
 TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
 // 通道初始化
 
	TIM_OC1Init(TIM8, &TIM_OCInitStructure);
	// 使能通道重装载
   TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);
	 
	//定时8第二通道的设置和第一通道CH1一样;
	TIM_OC2Init(TIM8, &TIM_OCInitStructure);
	// 使能通道重装载
   TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);
	 

//	/* ================ 断路和死区结构体初始化 ================ */
// // 自动输出使能,断路、死区时间和锁定配置
// TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
// TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
// TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
// // 配置死区时间
// TIM_BDTRInitStructure.TIM_DeadTime = 11;
// TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
// // 配置刹车引脚电平,当引脚为配置的电平时,主和互补输出都被禁止
// TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;
// TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
// TIM_BDTRConfig(ADVANCE_TIM, &TIM_BDTRInitStructure);

	
	// 使能定时器
	TIM_Cmd(TIM8, ENABLE);
	
	// 主动输出使能
	TIM_CtrlPWMOutputs(TIM8, ENABLE);
 
}

void HTim8_Init(void)
{
	HTIM8_GPIO_Config();
	HTim8Mode_Init();
	TIM_Cmd(TIM8, ENABLE);
}

//
//
void HTim8_SetPwmFreq(u32 FreqTemp)
{
	TIM_TimeBaseInitTypeDef 	TIM_TimeBaseStructure;
	Global_Timer8_Arr=1000000/FreqTemp;
	TIM_TimeBaseStructure.TIM_Period = Global_Timer8_Arr-1;
//定时器时钟源 TIMxCLK =168MHz
 // 设定定时器频率为 =TIMxCLK/(TIM_Prescaler+1)=168/(168-1+1)=1MHz
	TIM_TimeBaseStructure.TIM_Prescaler = 168-1;//1us加一次
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
	// 初始化定时器 TIMx
	TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);

	
}


void HTim8_SetPwmDuty(u8 PwmChannelTemp,float DutyTemp)
{
	if(PwmChannelTemp==1)
	{
		TIM_SetCompare1(TIM8,DutyTemp*Global_Timer8_Arr);
	}
	else 	if(PwmChannelTemp==2)
	{
		TIM_SetCompare2(TIM8,DutyTemp*Global_Timer8_Arr);
	}
}


void ServorCtrlAngle(u8 ServoNumTemp, float AngleTemp)
{
	float dutytemp=0;
  float timecal=0;
	u32 cntX=0;
	
	timecal=AngleTemp*Servo1_Delta_TimeMax/Servo1_Delta_AngleMax+0.5;
	cntX=timecal*1000/HTim8AddTimeTick;//乘以1000是因为ms和微秒
	if(ServoNumTemp==1)//连C6
	{
		TIM_SetCompare1(TIM8,cntX);
	}
	else 	if(ServoNumTemp==2)//连C7
	{
		TIM_SetCompare2(TIM8,cntX);
	}
}





void ServorCtrlAngleNP(u8 ServoNumTemp, float AngleTemp)
{
	float dutytemp=0;
  float timecal=0;
	u32 cntX=0;
	AngleTemp=AngleTemp+90;//取中间为0度
	timecal=AngleTemp*Servo1_Delta_TimeMax/Servo1_Delta_AngleMax+0.5;
	cntX=timecal*1000/HTim8AddTimeTick;//乘以1000是因为ms和微秒
	if(ServoNumTemp==1)
	{
		TIM_SetCompare1(TIM8,cntX);
	}
	else 	if(ServoNumTemp==2)
	{
		TIM_SetCompare2(TIM8,cntX);
	}
}

htim.h code

#ifndef __HTIMX_H 
#define __HIMX_H 

#include "sys.h" 

#define H_TIM8							  				TIM8
#define H_TIM8_CLK 					  				RCC_APB2Periph_TIM8 //RCC_APB2Periph_TIM8
#define H_TIM8_UP_TIM13_IRQn					TIM8_UP_TIM13_IRQn
#define H_TIM8_UP_TIM13_IRQHandler 		TIM8_UP_TIM13_IRQHandler

extern u32 Global_Timer8_Arr;


#define Servo1_Delta_AngleMax 270  //0-270度
#define Servo1_Delta_TimeMax 	2

#define HTim8AddTimeTick 	1  //这里是微s单位,1us,因为高级定时器8是168Mhz总线,采用168分频,就是1Mhz,1微妙频率,


void HTim8Mode_Init(void);//初始化 	
void HTIM8_GPIO_Config(void);
void HTim8_Init(void);//初始化 	

void HTim8_SetPwmFreq(u32 FreqTemp);//
//PwmChannelTemp=1是通道1,=2是通道2
//DutyTemp===0-1,,0.1;
void HTim8_SetPwmDuty(u8 PwmChannelTemp,float DutyTemp);//

//说明设置中,高级定时器8是168Mhz总线,采用168分频,就是1Mhz,1微妙频率,
//舵机计算次数是加一时间是1us一次,加到20ms周期,就是20000次。

//注意:如果设置是20us计算一次,那么分频系数是3360----168Mhz/3360=0.05Mhz=20us
void ServorCtrlAngle(u8 ServoNumTemp, float AngleTemp);//0-180度
//这个函数是以ServorCtrlAngle为基础的,主要是以中间为0度,左边为负90度,右边为正90的,就是-90到+90之间,范围
void ServorCtrlAngleNP(u8 ServoNumTemp, float AngleTemp);//取中间为0度,一遍-90,另外一边+90


//*****************一下是定时器器1的设置,用定时器1产生PWM,控制直流电机
//设置的说明:设置定时器的计时滴答是1us,由于是控制直流电机,所以可以设置PWM频率是10K左右;
//PWM2模式
#endif  
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32F407ZGT6控制舵机(采用高级定时器8) 的相关文章

随机推荐

  • 服务器系统多大内存条,服务器系统多大内存

    服务器系统多大内存 内容精选 换一换 创建IP地址组 添加需要统一管理的IP地址 IP地址组功能目前仅在 华北 北京一 华北 北京四 华南 广州 西南 贵阳一 开放 IP地址组无法针对某些类型的云服务器生效 即引用了IP地址组的安全组规则
  • 强化学习-任务与奖赏(周志华)

    文章目录 什么是强化学习 马尔科夫决策过程 四元组 机器 与 环境 界限 策略两种表示方法及奖赏 2K 摇臂赌博机 探索与利用 贪心法 softmax 什么是强化学习 强化学习 一种学习过程 包含很多学习步骤 经过一段时间才能收获结果 通常
  • 404 not found nginx(dist打包后,刷新和跳转都是404 not found nginx的问题) 解决方案(打包发布在服务器)

    当我们执行了yarn run build之后 生成dist文件 我们将代码放入nginx 1 24 0下面的html中 然后我们就配置conf文件下的nginx conf 配置方面不介绍了 主要问题是因为没有加这句话 问题分析 index
  • MySQL连接查询之内连接、左连接、右连接、自连接

    目录 一 内连接 1 连接查询的介绍 2 内连接查询 二 左连接 1 左连接查询 三 右连接 1 右连接查询 四 自连接 1 自连接查询 一 内连接 1 连接查询的介绍 连接查询可以实现多个表的查询 当查询的字段数据来自不同的表就可以使用连
  • java 电商锁库存实现_电商项目扣减库存方案

    阿里巴巴b2b电商算法实战电子商务 85 3元 包邮 需用券 去购买 gt 各位小宝贝们 大家是不是在面试过程中经常被问到 你电商项目扣减库存时 到底是下单减库存呢 还是付款减库存 那今天给大家出几种解决方案 有不对的地方欢迎批评指正 一
  • 人机交互与智能的思考

    1 智能与交互的起源 霍金曾说过 在过去的20年里 人工智能一直专注于围绕建设智能体所产生的问题 即在特定的情境下 可以感知并行动的各种系统 在这种情况下 智能是一个与统计学 和经济学相关的理性概念 通俗地讲 这是一种做出好的决定计划和推论
  • 【Logstash】【ElasticSearch】【Kibana】安装测试【日志存储】

    Linux日志 var存放日志 log auth 认证 boot 登录 dpkg 深度 Debian软件安装 fontconfig 字体 Logstash功能 Logstash是一个开源的数据收集引擎 具有实时管道功能 接收 处理 转发日志
  • 华为培训04 路由协议

    学习目标 路由分类 路由配置 VLAN路由 1 路由基础 2 VLAN间路由 2 1 三层交换 解决VLAN间通信的一种解决办法就是三层交换 在三层交换机上配置vlanif接口 实现VLAN间路由 如果网络上有多个VLAN 则需要给每一个V
  • 基于springboot开发项目架构之CMS

    1 CMS是什么 CMS Content Management System 即内容管理系统 不同的项目对CMS的定位不同 比如 一个在线教育网站 有些公司认为CMS系统是对所有的课程资源进行管理 而在早期网站刚开始盛行时很多公司的业务是网
  • Spring Cloud Alibaba + mybatis + Element UI 前后端分离 分布式微服务高并发数据平台化(中台)思想+多租户saas企业开发架构技术选型和设计方案

    基于Spring Cloud Alibaba 分布式微服务高并发数据平台化 中台 思想 多租户saas设计的企业开发架构 支持源码二次开发 支持其他业务系统集成 集中式应用权限管理 支持拓展其他任意子项目 一 架构技术选型 核心框架 Spr
  • [云原生专题-41]:K8S - 核心概念 - Service业务的统一网关接口Ingress详解、安装、常见操作命令

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 122804728 目录 前言 第1章
  • 面向切面编程SpringAop入门案例和实现机制

    代理与SpringAop springAop概述 SpringAop术语 SpringAop的实现机制 JDK实现动态代理 CGlib实现动态代理 springAop代理的实现 xml springAop代理的实现 注解 切点修饰语法 sp
  • ROS中订阅(Subscribe)最新消息以及对消息队列的浅谈

    ROS中订阅 Subscribe 最新消息以及对消息队列的浅谈 机器人应用中难免会遇到运算起来很费时间的操作 比如图像的特征提取 点云的匹配等等 有时候 不可避免地 我们需要在ROS的Subscriber的Callback回调函数中进行这些
  • 作用域和堆内存的区别

    作用域是函数执行的时候产生fn 函数执行的时候首先会开辟一个新的内存空间叫栈内存 环境或作用域 数据类型在赋值的时候会开辟一个新的内存空间叫堆内存 存放代码块的 二者都会形成一个内存地址 生成对象的单例模式 优势 每个对象都是独立的 即便属
  • @SuppressWarnings("resource")作用

    1 实例 SuppressWarnings resource public static void main String args Scanner input new Scanner System in 写代码时 input 警告加上这个
  • 若隐若现的芯片

    先看效果 再看代码
  • 【java语法基础】常量与变量、数据类型,以及数据类型的转换

    常量 就是值永远不被改变的量 声明一个常量 需要用final关键字修饰 具体格式 final 常量类型 常量标识符 常量值 例如 final int PIE 18 注 在定义一个常量标识符时 所有的字符都要大写 如果常量标识符由多个单词组成
  • 用python实现数字图片识别神经网络--实现网络训练功能

    上节我们完成了神经网络基本框架的搭建 当时剩下了最重要的一个接口train 也就是通过读取数据自我学习 进而改进网络识别效率的功能尚未实现 从本节开始 我们着手实现该功能 自我训练过程分两步走 第一步是计算输入训练数据 给出网络的计算结果
  • git查看日志

    目录 引言 git查看该项目提交记录 查看指定条数的记录 显示提交的差异 提交的简略信息 按行显示提交信息 按照指定格式显示记录 指定文件的提交记录 指定字符串或函数的提交记录 示例 引言 有时需要对之前所做的一些修改查看记录 这里是查看g
  • STM32F407ZGT6控制舵机(采用高级定时器8)

    前言 32单片机给舵机供电不足 会出现不稳定的情况 舵机鬼畜 所以要外加电源给舵机供电 利用12v锂电池 通过稳压模块降压到5 5v 提供给舵机 稳压电路的gnd一定要接上32单片机的gnd 不共地虽然能供电但数据线无法传输数据 stm32