艾思控AQMD6008BLS-TE无刷电机驱动使用笔记(配合STM32)

news2025/6/7 3:26:59

一、介绍

本驱动器使用的电机电流精确检测技术、有感无刷电机自测速、有感无刷电机转动位置检测、再生电流恒电流制动(或称刹车)技术和强大的PID调节技术可地控制电机平稳正反转、换向及制动,输出电流实时调控防止过流,精准控制电机转速和转动位置,电机响应时间短且反冲力小。

二、使用方法

该款无刷电机驱动有多种使用方法,就stm32而言,可以通过输出PWM信号对电机进行调速,也可通过485通讯或CAN通讯与电机驱动进行通讯(电机驱动内部应该也是另外一块32)。项目使用过程中,经导师建议,优先采用485通讯方式。在使用此种通讯方式时,注意设备地址和通讯参数(波特率、奇偶校验等)的设置。

在通过速度控制寄存器进行速度控制时,可以通过0x0042寄存器设定占空比,也可通过0x0043寄存器设定换向频率。另外,在正确配置电机极个数和减速比之后,可以通过0x0034寄存器读取电机的转速。

三、代码

在编写代码的过程中,有参考硬件家园刘工的工程代码,在此表示感谢。

Motor.h

#ifndef __MOTOR_H__
#define __MOTOR_H__

#include "MyApplication.h"

//定义枚举类型
typedef enum
{
	M1 = (uint8_t)0x01,
	M2 = (uint8_t)0x02,
}Motor_Num_t;

//定义结构体类型
typedef struct
{
	uint8_t M1_Addr;
	uint8_t M2_Addr;
	FlagStatus_t Motor_Move_State;
	uint16_t M1_Read_Value;
	uint16_t M2_Read_Value;
	void (*Motor_Set_PWM)(uint8_t, float, UART_t*); 
	void (*Motor_Read_Value)(uint8_t, UART_t*);
	void (*Protocol_Read_Speed)(uint8_t, UART_t*);
	void (*Motor_PWM_Acc_Buffer)(uint8_t, float, UART_t*);
	void (*Motor_PWM_Rv_Buffer)(uint8_t, float, UART_t*);
	void (*Motor_Brake)(uint8_t, UART_t*);
} Motor_t;



/* extern variables-----------------------------------------------------------*/
extern Motor_t  Motor;
/* extern function prototypes-------------------------------------------------*/

#endif
/********************************************************
  End Of File
********************************************************/

Motor.c

/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/
#define FunctionCode_Read_Motor 		(uint8_t)0x03
#define FunctionCode_Write_Motor 	(uint8_t)0x06
#define UART3_Read_Speed_LENGTH		(uint8_t)7

/* Private variables----------------------------------------------------------*/
static void Motor_Set_PWM(uint8_t, float, UART_t*); 
static void Motor_Read_Value(uint8_t, UART_t*);
static void Protocol_Read_Speed(uint8_t, UART_t*);
static void Motor_PWM_Acc_Buffer(uint8_t, float, UART_t*);
static void Motor_PWM_Rv_Buffer(uint8_t, float, UART_t*);
static void Motor_Brake(uint8_t, UART_t*); 

/* Public variables-----------------------------------------------------------*/
Motor_t Motor = 
{
	0x01, 
	0x02,
	FALSE,
	0,
	0,
	Motor_Set_PWM,
	Motor_Read_Value,
	Protocol_Read_Speed,
	Motor_PWM_Acc_Buffer,
	Motor_PWM_Rv_Buffer,
	Motor_Brake
};

/* Private function prototypes------------------------------------------------*/      

/*
	* @name   Motor_Set_PWM
	* @brief  设置驱动PWM占空比
	* @param  Motor_Num -> 编号, pwm -> 占空比, UART -> 串口
	* @retval None      
*/
static void Motor_Set_PWM(uint8_t Motor_Num, float pwm, UART_t* UART)
{
	UART_t* const COM = UART;
	uint16_t SpeedTemp = (uint16_t)(pwm * 10);
	
	//条件选择语句
	switch(Motor_Num)
	{	
		case M1: 
		{
			*(COM->pucSend_Buffer + 0) = Motor.M1_Addr;
			*(COM->pucSend_Buffer + 1) = FunctionCode_Write_Motor;
			
			*(COM->pucSend_Buffer + 2) = 0x00;
			*(COM->pucSend_Buffer + 3) = 0x42;

			*(COM->pucSend_Buffer + 4) = (uint8_t)(SpeedTemp >> 8);
			*(COM->pucSend_Buffer + 5) = (uint8_t)SpeedTemp;

			CRC_16.CRC_Value = CRC_16.CRC_Check(COM->pucSend_Buffer, 6);
			CRC_16.CRC_H     = (uint8_t)(CRC_16.CRC_Value >> 8);
			CRC_16.CRC_L     = (uint8_t)CRC_16.CRC_Value;

			*(COM->pucSend_Buffer + 6) = CRC_16.CRC_H;
			*(COM->pucSend_Buffer + 7) = CRC_16.CRC_L;

			UART3.SendArray(COM->pucSend_Buffer, 8);
			
			break;
		}
		case M2:
		{
			*(COM->pucSend_Buffer + 0) = Motor.M2_Addr;
			*(COM->pucSend_Buffer + 1) = FunctionCode_Write_Motor;
			
			*(COM->pucSend_Buffer + 2) = 0x00;
			*(COM->pucSend_Buffer + 3) = 0x42;

			*(COM->pucSend_Buffer + 4) = (uint8_t)(SpeedTemp >> 8);
			*(COM->pucSend_Buffer + 5) = (uint8_t)SpeedTemp;

			CRC_16.CRC_Value = CRC_16.CRC_Check(COM->pucSend_Buffer, 6);
			CRC_16.CRC_H     = (uint8_t)(CRC_16.CRC_Value >> 8);
			CRC_16.CRC_L     = (uint8_t)CRC_16.CRC_Value;

			*(COM->pucSend_Buffer + 6) = CRC_16.CRC_H;
			*(COM->pucSend_Buffer + 7) = CRC_16.CRC_L;

			UART3.SendArray(COM->pucSend_Buffer, 8);
			
			break;
		}
		default: System.Assert_Failed();
	}
	HAL_Delay(30);
}

/*
	* @name   Motor_Read_Speed
	* @brief  通过驱动读取转速
	* @param  UART -> 串口
	* @retval None      
*/
static void Motor_Read_Value(uint8_t Motor_Num, UART_t* UART)
{
	UART_t* const  COM = UART;
	
	//条件选择语句
	switch(Motor_Num)
	{
		case M1: 
		{
			*(COM->pucSend_Buffer + 0) = Motor.M1_Addr;
			*(COM->pucSend_Buffer + 1) = FunctionCode_Read_Motor;
			
			*(COM->pucSend_Buffer + 2) = 0x00;
			*(COM->pucSend_Buffer + 3) = 0x34;
			
			*(COM->pucSend_Buffer + 4) = 0x00;
			*(COM->pucSend_Buffer + 5) = 0x01;
			
			CRC_16.CRC_Value = CRC_16.CRC_Check(COM->pucSend_Buffer, 6);
			CRC_16.CRC_H     = (uint8_t)(CRC_16.CRC_Value >> 8);
			CRC_16.CRC_L     = (uint8_t)CRC_16.CRC_Value;

			*(COM->pucSend_Buffer + 6) = CRC_16.CRC_H;
			*(COM->pucSend_Buffer + 7) = CRC_16.CRC_L;

			Modbus.Sensor_To_Read_Flag = 1;
			UART3.SendArray(COM->pucSend_Buffer, 8);
			break;			
		}
		
		case M2: 
		{
			*(COM->pucSend_Buffer + 0) = Motor.M2_Addr;
			*(COM->pucSend_Buffer + 1) = FunctionCode_Read_Motor;
			
			*(COM->pucSend_Buffer + 2) = 0x00;
			*(COM->pucSend_Buffer + 3) = 0x34;
			
			*(COM->pucSend_Buffer + 4) = 0x00;
			*(COM->pucSend_Buffer + 5) = 0x01;
			
			CRC_16.CRC_Value = CRC_16.CRC_Check(COM->pucSend_Buffer, 6);
			CRC_16.CRC_H     = (uint8_t)(CRC_16.CRC_Value >> 8);
			CRC_16.CRC_L     = (uint8_t)CRC_16.CRC_Value;

			*(COM->pucSend_Buffer + 6) = CRC_16.CRC_H;
			*(COM->pucSend_Buffer + 7) = CRC_16.CRC_L;

			Modbus.Sensor_To_Read_Flag = 2;
			UART3.SendArray(COM->pucSend_Buffer, 8);
			break;			
		}	
		default: System.Assert_Failed();
	}
	
	HAL_Delay(30);
}

/*
	* @name   Protocol_Read_Speed
	* @brief  分析串口值
	* @param  UART_t* -> 串口
	* @retval None      
*/
static void Protocol_Read_Speed(uint8_t Motor_Num, UART_t* UART)
{
	UART_t* const  COM = UART;
	uint8_t i = 0, Index = 0;

	//串口3停止DMA接收
	HAL_UART_DMAStop(&huart3);

	switch(Motor_Num)
	{
		case M1:
		{
			//过滤干扰数据,首字节为modbus地址,共8字节
			for(i = 0; i < UART3_Rec_LENGTH; i++)
			{
				//检测键值起始数据Modbus.Addr
				if(Index == 0)
				{
					if(*(COM->pucRec_Buffer+i) != Motor.M1_Addr)
						continue;
				}
				
				*(COM->pucRec_Buffer + Index) = *(COM->pucRec_Buffer + i);

				//已读取7个字节
				if(Index == UART3_Read_Speed_LENGTH - 1)
					break;
				
				Index++;
			}
			
			//计算CRC-16
			CRC_16.CRC_Value   = CRC_16.CRC_Check(COM->pucRec_Buffer, 5); //计算CRC值
			CRC_16.CRC_H       = (uint8_t)(CRC_16.CRC_Value >> 8);
			CRC_16.CRC_L       = (uint8_t)CRC_16.CRC_Value;	

			//校验CRC-16
			if(((*(COM->pucRec_Buffer + 5) == CRC_16.CRC_L) && (*(COM->pucRec_Buffer + 6) == CRC_16.CRC_H))
																										||
				 ((*(COM->pucRec_Buffer + 5) == CRC_16.CRC_H) && (*(COM->pucRec_Buffer + 6) == CRC_16.CRC_L)))
			{
				//校验地址
				
				if(((*(COM->pucRec_Buffer + 0)) == Motor.M1_Addr) && ((*(COM->pucRec_Buffer + 1)) == FunctionCode_Read_Motor) && ((*(COM->pucRec_Buffer + 2)) == 0x02))
				{
					
					Motor.M1_Read_Value = ((*(COM->pucRec_Buffer + 3)) << 8) | ((*(COM->pucRec_Buffer + 4)));
				}
			}	
			break;
		}
		case M2:
		{
			//过滤干扰数据,首字节为modbus地址,共8字节
			for(i = 0; i < UART3_Rec_LENGTH; i++)
			{
				//检测键值起始数据Modbus.Addr
				if(Index == 0)
				{
					if(*(COM->pucRec_Buffer+i) != Motor.M2_Addr)
						continue;
				}
				
				*(COM->pucRec_Buffer + Index) = *(COM->pucRec_Buffer + i);

				//已读取7个字节
				if(Index == UART3_Read_Speed_LENGTH - 1)
					break;
				
				Index++;
			}
			
			//计算CRC-16
			CRC_16.CRC_Value   = CRC_16.CRC_Check(COM->pucRec_Buffer, 5); //计算CRC值
			CRC_16.CRC_H       = (uint8_t)(CRC_16.CRC_Value >> 8);
			CRC_16.CRC_L       = (uint8_t)CRC_16.CRC_Value;	

			//校验CRC-16
			if(((*(COM->pucRec_Buffer + 5) == CRC_16.CRC_L) && (*(COM->pucRec_Buffer + 6) == CRC_16.CRC_H))
																										||
				 ((*(COM->pucRec_Buffer + 5) == CRC_16.CRC_H) && (*(COM->pucRec_Buffer + 6) == CRC_16.CRC_L)))
			{
				//校验地址
				if(((*(COM->pucRec_Buffer + 0)) == Motor.M2_Addr) && ((*(COM->pucRec_Buffer + 1)) == FunctionCode_Read_Motor) && ((*(COM->pucRec_Buffer + 2)) == 0x02))
				{
					Motor.M2_Read_Value = ((*(COM->pucRec_Buffer + 3)) << 8) | ((*(COM->pucRec_Buffer + 4)));
				}
			}				
			break;
		}
		default: break;
	}
	
	//清缓存
	for(i = 0; i < UART3_Rec_LENGTH; i++)
	{
		*(COM->pucRec_Buffer + i) = 0x00;
	}

}

/*
	* @name   Motor_PWM_Acc_Buffer
	* @brief  电机PWM加速缓冲
	* @param  Motor_Num -> 编号, time -> 时间, UART -> 串口
	* @retval None      
*/
static void Motor_PWM_Acc_Buffer(uint8_t Motor_Num, float time, UART_t* UART)
{
	UART_t* const  COM = UART;
	uint8_t SpeedTemp = (uint8_t)(time * 10);
	

	//条件选择语句
	switch(Motor_Num)
	{	
		case M1: 
		{
			*(COM->pucSend_Buffer + 0) = Motor.M1_Addr;
			*(COM->pucSend_Buffer + 1) = FunctionCode_Write_Motor;
			
			*(COM->pucSend_Buffer + 2) = 0x00;
			*(COM->pucSend_Buffer + 3) = 0x60;

			*(COM->pucSend_Buffer + 4) = 0x00;
			*(COM->pucSend_Buffer + 5) = SpeedTemp;

			CRC_16.CRC_Value = CRC_16.CRC_Check(COM->pucSend_Buffer, 6);
			CRC_16.CRC_H     = (uint8_t)(CRC_16.CRC_Value >> 8);
			CRC_16.CRC_L     = (uint8_t)CRC_16.CRC_Value;

			*(COM->pucSend_Buffer + 6) = CRC_16.CRC_H;
			*(COM->pucSend_Buffer + 7) = CRC_16.CRC_L;

			UART3.SendArray(COM->pucSend_Buffer, 8);
			
			break;
		}
		case M2:
		{
			*(COM->pucSend_Buffer + 0) = Motor.M2_Addr;
			*(COM->pucSend_Buffer + 1) = FunctionCode_Write_Motor;
			
			*(COM->pucSend_Buffer + 2) = 0x00;
			*(COM->pucSend_Buffer + 3) = 0x60;

			*(COM->pucSend_Buffer + 4) = 0x00;
			*(COM->pucSend_Buffer + 5) = SpeedTemp;

			CRC_16.CRC_Value = CRC_16.CRC_Check(COM->pucSend_Buffer, 6);
			CRC_16.CRC_H     = (uint8_t)(CRC_16.CRC_Value >> 8);
			CRC_16.CRC_L     = (uint8_t)CRC_16.CRC_Value;

			*(COM->pucSend_Buffer + 6) = CRC_16.CRC_H;
			*(COM->pucSend_Buffer + 7) = CRC_16.CRC_L;

			UART3.SendArray(COM->pucSend_Buffer, 8);
			
			break;
		}
		default: System.Assert_Failed();
	}
	HAL_Delay(30);	
}

/*
	* @name   Motor_PWM_Rv_Buffer
	* @brief  电机PWM减速缓冲
	* @param  Motor_Num -> 编号, time -> 时间, UART -> 串口
	* @retval None      
*/
static void Motor_PWM_Rv_Buffer(uint8_t Motor_Num, float time, UART_t* UART)
{
	UART_t* const  COM = UART;
	uint8_t SpeedTemp = (uint8_t)(time * 10);
	

	//条件选择语句
	switch(Motor_Num)
	{	
		case M1: 
		{
			*(COM->pucSend_Buffer + 0) = Motor.M1_Addr;
			*(COM->pucSend_Buffer + 1) = FunctionCode_Write_Motor;
			
			*(COM->pucSend_Buffer + 2) = 0x00;
			*(COM->pucSend_Buffer + 3) = 0x51;

			*(COM->pucSend_Buffer + 4) = 0x00;
			*(COM->pucSend_Buffer + 5) = SpeedTemp;

			CRC_16.CRC_Value = CRC_16.CRC_Check(COM->pucSend_Buffer, 6);
			CRC_16.CRC_H     = (uint8_t)(CRC_16.CRC_Value >> 8);
			CRC_16.CRC_L     = (uint8_t)CRC_16.CRC_Value;

			*(COM->pucSend_Buffer + 6) = CRC_16.CRC_H;
			*(COM->pucSend_Buffer + 7) = CRC_16.CRC_L;

			UART3.SendArray(COM->pucSend_Buffer, 8);
			
			break;
		}
		case M2:
		{
			*(COM->pucSend_Buffer + 0) = Motor.M2_Addr;
			*(COM->pucSend_Buffer + 1) = FunctionCode_Write_Motor;
			
			*(COM->pucSend_Buffer + 2) = 0x00;
			*(COM->pucSend_Buffer + 3) = 0x51;

			*(COM->pucSend_Buffer + 4) = 0x00;
			*(COM->pucSend_Buffer + 5) = SpeedTemp;

			CRC_16.CRC_Value = CRC_16.CRC_Check(COM->pucSend_Buffer, 6);
			CRC_16.CRC_H     = (uint8_t)(CRC_16.CRC_Value >> 8);
			CRC_16.CRC_L     = (uint8_t)CRC_16.CRC_Value;

			*(COM->pucSend_Buffer + 6) = CRC_16.CRC_H;
			*(COM->pucSend_Buffer + 7) = CRC_16.CRC_L;

			UART3.SendArray(COM->pucSend_Buffer, 8);
			
			break;
		}
		default: System.Assert_Failed();
	}
	HAL_Delay(30);	
}

/*
	* @name   Motor_Brake
	* @brief  电机刹车
	* @param  Motor_Num -> 编号, UART -> 串口
	* @retval None      
*/
static void Motor_Brake(uint8_t Motor_Num, UART_t* UART)
{
	UART_t* const  COM = UART;

	//条件选择语句
	switch(Motor_Num)
	{	
		case M1: 
		{
			*(COM->pucSend_Buffer + 0) = Motor.M1_Addr;
			*(COM->pucSend_Buffer + 1) = FunctionCode_Write_Motor;
			
			*(COM->pucSend_Buffer + 2) = 0x00;
			*(COM->pucSend_Buffer + 3) = 0x40;

			*(COM->pucSend_Buffer + 4) = 0x00;
			*(COM->pucSend_Buffer + 5) = 0x01;

			CRC_16.CRC_Value = CRC_16.CRC_Check(COM->pucSend_Buffer, 6);
			CRC_16.CRC_H     = (uint8_t)(CRC_16.CRC_Value >> 8);
			CRC_16.CRC_L     = (uint8_t)CRC_16.CRC_Value;

			*(COM->pucSend_Buffer + 6) = CRC_16.CRC_H;
			*(COM->pucSend_Buffer + 7) = CRC_16.CRC_L;

			UART3.SendArray(COM->pucSend_Buffer, 8);
			
			break;
		}
		case M2:
		{
			*(COM->pucSend_Buffer + 0) = Motor.M2_Addr;
			*(COM->pucSend_Buffer + 1) = FunctionCode_Write_Motor;
			
			*(COM->pucSend_Buffer + 2) = 0x00;
			*(COM->pucSend_Buffer + 3) = 0x40;

			*(COM->pucSend_Buffer + 4) = 0x00;
			*(COM->pucSend_Buffer + 5) = 0x01;

			CRC_16.CRC_Value = CRC_16.CRC_Check(COM->pucSend_Buffer, 6);
			CRC_16.CRC_H     = (uint8_t)(CRC_16.CRC_Value >> 8);
			CRC_16.CRC_L     = (uint8_t)CRC_16.CRC_Value;

			*(COM->pucSend_Buffer + 6) = CRC_16.CRC_H;
			*(COM->pucSend_Buffer + 7) = CRC_16.CRC_L;

			UART3.SendArray(COM->pucSend_Buffer, 8);
			
			break;
		}
		default: System.Assert_Failed();
	}
	HAL_Delay(30);	
}



/********************************************************
  End Of File
********************************************************/

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

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

相关文章

「许战海战略文库」佳隆股份:2亿级别的调味品公司如何应对增长难题

自2002年以来&#xff0c;佳隆食品逐步向集团化方向发展&#xff0c;2010年11月2日在深圳证券交易所成功挂牌上市。 2009年-2022年&#xff0c;公司营收增长并不明显&#xff0c;基本维持在2-3亿之间。尤其是2022年&#xff0c;营收出现亏损的情况&#xff0c;在运营和增长战略…

ruoyi-ai 基于ruoyi-plus实现AI聊天和绘画功能-后端

基于ruoyi-plus实现AI聊天和绘画功能-后端 本项目完全开源免费&#xff01; 后台管理界面使用elementUI服务端使用Java17SpringBoot3.X ruoyi-ai: 基于ruoyi-plus实现AI聊天和绘画功能-后端 实现功能 集成OpenAi API (gpt-4-vision-preview dall-e-3)接入文生图模型&#xf…

satellite-image-deep-learning,一个遥感深度学习方向的宝藏网站

今天我们分享一个深度学习遥感相关的网站&#xff1a;「satellite-image-deep-learning」。这是一个github库&#xff0c;里面含有大量应用于卫星和航空图像的深度学习资源。 主要包括以下几个方面&#xff1a; annotation&#xff1a;提供数据集注释信息&#xff0c;里面包含…

基于ssm的视康眼镜网店销售系统的设计与实现+vue论文

引 言 随着互联网应用的不断发展&#xff0c;以及受新冠病毒疫情影响&#xff0c;越来越多的零售行业将其销售方式从实体门店销售转向虚拟网店销售方向发展。中国互联网络信息中心(CNNIC)发布第48次《中国互联网络发展状况统计报告》显示&#xff0c;截至2021年6月&#xff0c…

年度总结丨酷雷曼2023年度记忆

2023年 我们关心粮食和蔬菜 也关心“视界”和未来 我们执着于向新兴科技深处钻研 也探寻着让VR全景广泛落地 我们目睹着智慧生活的日新月异 也记录着平凡奋斗者们创造的非凡事业 2024年 属于VR的盛行之年 你又会将目光投向哪里&#xff1f; 这里有一份来自 酷雷曼的…

前端angular 实现验证码 输入+展示(大框+加粗内容 )

参考用原生方在手机上此效果 如何实现一个4位验证码输入框效果 输入使用的任旧是html的input元素&#xff0c;只是让它看不到了只是把输入到input元素里的内容取到的内容放在改过样式的div里不需要dom操作&#xff0c;直接用双向绑定就拿到数据&#xff1b;使用动态样式 设置了…

SQL Yog 连接MySQL的时候出现 错误码 2058的问题

查看报错信息&#xff1a; 这个问题是出现在&#xff0c;我使用sql Yog连接MySQL数据库的时候出现的错误。 问题分析&#xff1a; 原因可能是MySQL加密方式&#xff0c;不允许本地访问&#xff0c; 解决办法&#xff1a; 1&#xff0c;window r 输入cmd进入黑窗口 2&#xff…

flink on yarn任务启停脚本(实现一键读取ck启动,保存ck停止)

1.问题描述 flink同步任务&#xff0c;长期任务过多&#xff0c;某个任务停止保存checkpoint或者savepoint后&#xff0c;修改代码&#xff0c;使用命令行读取检查点重新启动需要人工去hdfs上找寻检查点保存位置。任务过多管理起来很不方便。 鉴于此&#xff0c;使用脚本编写了…

springcloud之集成nacos config

写在前面 源码 。 本文看下如下集成nacos config组件。 1&#xff1a;常见配置方式分析 我们先来看下常见的配置方式都有哪些&#xff0c;以及其有什么优点和缺点。 硬编码 优点&#xff1a;hardcode&#xff0c;除了开发的时候快些&#xff0c;爽一下&#xff0c;有个屁优…

京东年度数据报告-2023全年度吸尘器十大热门品牌销量榜单

2023年&#xff0c;在家电行业增长乏力的环境下&#xff0c;作为环境电器的热门品类之一&#xff0c;吸尘器市场整体的销售也呈现下滑态势。 根据鲸参谋平台的数据显示&#xff0c;2023年度&#xff0c;京东平台上吸尘器市场的年度销量累计超过300万&#xff0c;同比下滑约20%…

多线程基础入门【Linux之旅】——上篇【线程控制,线程互斥,线程安全】

目录 前文 回望页表 一&#xff0c;什么是线程 二&#xff0c;使用 pthread_create &#xff08;线程创建&#xff09; 三&#xff0c;线程控制 1 &#xff0c;线程共享进程数据&#xff0c;但也拥有自己的一部分数据: 2&#xff0c; 线程 VS 进程优点 3&#xff0c;…

【数据结构】数组实现队列(详细版)

目录 队列的定义 普通顺序队列的劣势——与链队列相比 顺序队列实现方法&#xff1a; 一、动态增长队列 1、初始化队列 2、元素入队 3、判断队列是否为空 4、元素出队 5、获取队首元素 6、获取队尾元素 7、获取队列元素个数 8、销毁队列 总结&#xff1a; 动态增长队列…

企业数据存储监控

随着组织及其网络基础架构的不断扩展&#xff0c;存储将不可避免地成为一项挑战&#xff0c;随着存储需求的增长&#xff0c;调配更多存储资源的需求也会随之增长。为基础架构配置了更多存储资源后&#xff0c;它们需要不间断地运行&#xff0c;并且应该免受威胁。从本质上讲&a…

Linux之Ubuntu环境安装配置Jenkins

Ubuntu环境安装配置Jenkins&#xff0c;启动服务 一、安装过程 1、查看服务器的操作系统 lsb_release -a 2、查看JDK是否安装 java -version 如果还没有安装&#xff0c;则需要安装&#xff0c;命令如下&#xff1a; sudo apt install openjdk-11-jre-headless 3、下载2.…

pandas.DataFrame() 数据自动写入Excel

DataFrame 表格数据格式 &#xff1b; to_excel 写入Excel数据&#xff1b; read_excel 阅读 Excel数据函数 import pandas as pd#df2 pd.DataFrame({neme: [zhangsan, lisi, 3]}) df1 pd.DataFrame({One: [1, 2, 3],name: [zhangsan, lisi, 3]})#One是列明&#xff0c;123是…

前端三剑客——HTML5+CSS3+JavaScript

核心技术●实战训练营●项目实战&#xff08;微视频版&#xff09;   《前端三剑客——HTML5CSS3JavaScript》采用“核心技术→实战训练营→企业级项目实践”的结构和“由浅入深&#xff0c;由深到精”的模式进行讲解。 全书科学设置七大阶段由浅入深循序渐进&#xff0c;为解…

消防船,2027年将达到约26亿美元左右

近年来&#xff0c;消防船市场不断扩大&#xff0c;主要受到城市化进程和海上经济的快速发展的推动。消防船能够有效地灭火、增强海上边防力量&#xff0c;受到国内外政府和企业的广泛关注全球市场 近年来&#xff0c;消防船市场不断扩大&#xff0c;主要受到城市化进程和海上经…

C++ 多态向上转型详解

文章目录 1 . 前言2 . 多态3 . 向上转型4 . 总结 【极客技术传送门】 : https://blog.csdn.net/Engineer_LU/article/details/135149485 1 . 前言 此篇博文详解C的多态向上转型平台 : Qt 2 . 多态 【Q】什么是多态&#xff1f; 【A】解释如下 : 通俗来说,就是多种形态,具体…

Nginx学习之Nginx高性能的实现原理

Nginx学习之Nginx高性能的实现原理   Nginx 采用的是多进程&#xff08;单线程&#xff09; & 多路IO复用模型&#xff0c;使用了 I/O 多路复用技术的 Nginx&#xff0c;就成了”并发事件驱动“的服务器&#xff0c;同时使用sendfile等技术&#xff0c;最终实现了高性能。…