【STM32】步进电机及其驱动(ULN2003驱动28BYJ-48丨按键控制电机旋转)

news2024/12/23 19:16:25

本篇文章包含的内容

  • 一、步进电机的结构和工作原理
    • 1.1 步进控制系统的组成
    • 1.2 步进电机简介
    • 1.3 步进电机的分类
    • 1.4 步进电机的工作原理
      • 1.4.1 单极性步进电机(5线4相)
      • 1.4.2 双极性步进电机(4线2相)
      • 1.4.3 细分器驱动原理
    • 1.5 步进电机工作参数
      • 1.5.1 静态参数
      • 1.5.2 动态参数
    • 1.6 步进电机的特点
  • 二、步进电机驱动
    • 2.1 ULN2003驱动芯片
    • 2.2 驱动模块电路图
  • 三、代码实现


参考文章与课程:
  【视频课程】步进电机基础原理和应用——程子华主讲
  【视频课程】电机系列教学视频(基于STM32硬件)——野火
  【霄耀在努力】STM32驱动步进电机(原理、程序、解决电机只震动不转动问题)


一、步进电机的结构和工作原理

1.1 步进控制系统的组成

  步进控制系统由以下三个部分组成:

  • 控制器:可以是PLC、定位控制模块或单片机,主要作用是产生控制脉冲信号博主采用STM32作为控制器)。
  • 驱动器:对控制器发出的控制信号进行分配和功率放大,控制步进电机每一相的线圈是否通电。
  • 电机:电机本身,或用步进电机驱动其他设备。

1.2 步进电机简介

  步进电机是一种特种电机,又称为脉冲电动机,是一种将电脉冲信号转化为角位移线位移的开环(无反馈)控制元件。在非超载的条件下,电机的转速、角位移只取决于控制脉冲信号的频率脉冲数
  “步进”的意义是电机转动遵从固定的步幅,即每一个控制脉冲来临,电机就转动一个步进角 θ \theta θ。步进角 θ \theta θ与电机本身的结构(和其拓展结构,例如减速齿轮可以减小步进角)有关。脉冲数越多,电机转动的角度就越大。同时,脉冲的频率越高,电机转速就越快,但不能超过最高频率,否则电机的力矩将迅速减小,电机停转。
  下图所示的是较为常见的42步进电机。“42”的意思是该电机的外壳尺寸是42mm×42mm。可以在其转轴上加装减速齿轮实现减速功能,来增大输出力矩和减小步进角 θ \theta θ;也可以在将转轴替换为丝杠,常见于需要驱动设备直线运动的场合。
在这里插入图片描述
  博主在这里使用的步进电机型号是28BYJ-48,是套件中常见的步进电机。它也是一种减速步进电机,内部的减速齿轮由塑料制成,具有重量轻,体积小,结构简单等特点。它常被用在监控探头的云台上。这种电机及其驱动模块如下图所示:
在这里插入图片描述

1.3 步进电机的分类

  步进电机的分类方法非常多,按照不同的分类方法,步进电机可以被分为以下几种:

  1. 按力矩产生的原理分类
  • 磁阻式:又称为反应式步进电机。转子采用软磁材料,一般式硅钢片,本身没有磁性,但极易被磁化。其特点是结构简单,步进角小(可达1.2°),但效率低,发热量大,可靠性难以保障,很早之前就被市场淘汰了。
    在这里插入图片描述

  • 永磁式:又称为PM步进电机,转子使用永磁性材料,通过改变定子线圈的磁极来驱动转子。内部的圆柱形转子外表均匀分布着N极和S极。一般都为两相,扭矩和体积都比较小。步进角 θ \theta θ一般为3.75°、7.5°、15°、18°,特点是步进角一般较大,力矩较小,精度比较低,发热小,结构简单,价格低廉,一般用在一些较为低端的产品中。今年来设备小型化,微型永磁式步进电机的应用范围也有了进一步的扩展,例如带可升降型的摄像头的手机。
    在这里插入图片描述

  • 混合式:定子由两个转子铁芯(一般是硅钢片)和一个磁钢(永磁体)组成,两个转子铁芯极性相反。它的特点是产生的力矩相较于永磁式步进电机更大,发热较小,效率高,转速相对较大,噪音低,步进角小等。两相混合式步进电机的步进角一般为1.8°,三相混合式步进电机的步进角一般为1.2°,五相混合式步进电机的步进角可以达到0.72°。它的相应速度快,适用于频繁启停的场合。
    请添加图片描述

  1. 按相数分类:可以分为单相、双相、三相、四相、五相步进电机。相数,指电机内部的闭合线圈组数。
  2. 按输出力矩的大小分类
  • 伺服式:输出力矩在小于1N·m的范围内,只能驱动较小的负载,要与液压扭矩放大器配合使用才能驱动机床、工作台等较大的负载
  • 功率式:输出力矩在5~50N·m之间,甚至更高,可以直接驱动机床工作台等较大的负载
  1. 按定子数分类
  • 单定子式
  • 双定子式
  • 三定子式
  • 多定子式
  1. 按各相绕组分布分类
  • 径向分布式:电机各相按圆周依次排列
  • 轴向分布式:电机各相按轴向依次排列

  按照以上的一些分类方法,可以举出一些例子:
在这里插入图片描述
  28BYJ-48就是一种常见的单极性五线四相步进电机,“单极性”指线圈中电流的方向是确定的,不可翻转;对应的,“双极性”指线圈冲存在两种不同地电流方向。

1.4 步进电机的工作原理

  对于双极性步进电机和单极性步进电机,它们二者绕组极性的不同,它们的工作方式也略有差异。

1.4.1 单极性步进电机(5线4相)

  单极性步进电机有共阴极接法共阳极接法,两种接法对于控制信号而言只是控制信号的极性的不同。要控制电机的旋转方向,只需要将拍之间的导电顺序颠倒即可。接下来的几种驱动方式都采用共阴极接法为例说明,且电机为顺时针转动。

  1. 单相整步驱动:“单相”指每一拍只有一相导电,“整步”指每一拍走过的角度是相邻两相之间的一整步。如下图所示,四个相的导电顺序为: A → B → C → D → A → . . . A\rightarrow B \rightarrow C \rightarrow D \rightarrow A \rightarrow... ABCDA...,依次循环,步距角 θ = 90 ° \theta=90° θ=90°
    在这里插入图片描述

  2. 双相整步驱动:“双相”指每一拍有两相同时导通,且在数字信号驱动下,两相线圈通电产生的磁场大小相等。四拍的导电顺序为 A B → B C → C D → D A → A B → . . . AB\rightarrow BC \rightarrow CD \rightarrow DA \rightarrow AB \rightarrow... ABBCCDDAAB...,与单相整步驱动相比,双相整步驱动拥有更大的转动力矩(是单相整步驱动力矩的 2 \sqrt{2} 2 倍)。
    在这里插入图片描述

  3. 半步驱动:半步驱动方式实际上是单相整步驱动和双相整步驱动的结合。相较于前两者,半步驱动有更小的步距角(45°),八拍的导电顺序为: A → A B → B → B C → C → C D → D → D A → A → . . . A\rightarrow AB \rightarrow B \rightarrow BC \rightarrow C \rightarrow CD \rightarrow D \rightarrow DA \rightarrow A \rightarrow... AABBBCCCDDDAA...,其缺点为转动力矩不稳定,有可能会导致电机本身的震动或者驱动设备的动力不稳定等问题。
    在这里插入图片描述

1.4.2 双极性步进电机(4线2相)

  双极性步进电机中的线圈中的电流方向是双相的,通过配置 A + A^+ A+ A − A^- A B + B^+ B+ B − B^- B的高低电平来控制电机的旋转。其原理与单极性步进电机类似,优点是相较于前者可以具有更大的转动力矩(可以通过配置一个线圈上的两端电压分别为+5V和-5V来使线圈上的电流增大),缺点是驱动电路和程序较为复杂。由于原理与单极性步进电机类似,以下不做过多赘述。

  1. 单相整步驱动
    在这里插入图片描述

  2. 双相整步驱动
    在这里插入图片描述

  3. 半步驱动
    在这里插入图片描述

1.4.3 细分器驱动原理

  如果驱动电路可以改变每一相通电时的电流大小,就可以控制每一相产生的磁场大小。这样不仅能解决半步驱动时力矩忽大忽小的问题,还能使步距角进一步减小以达到更高的精度控制
在这里插入图片描述

1.5 步进电机工作参数

1.5.1 静态参数

  • 相数:产生不同对极 N、S 磁场的激磁线圈对数(双极性),也可以理解为步进电机中线圈的组数。一般而言,两相步进电机步距角为 1.8°,三相的步进电机步距角为 1.5°,相数越多的步进电机,其步距角就越小
  • 拍数:完成一个磁场周期性变化所需脉冲数或导电状态,用 n n n 表示;或指电机转过一个齿距角所需脉冲数。以四相电机为例,四相四拍运行方式即 A B → B C → C D → D A → A B → . . . AB\rightarrow BC \rightarrow CD \rightarrow DA \rightarrow AB \rightarrow... ABBCCDDAAB...,四相八拍运行方式即 A → A B → B → B C → C → C D → D → D A → A → . . . A\rightarrow AB \rightarrow B \rightarrow BC \rightarrow C \rightarrow CD \rightarrow D \rightarrow DA \rightarrow A \rightarrow... AABBBCCCDDDAA...
  • 步距角:一个脉冲信号所对应的电机转动的角度,可以简单理解为一个脉冲信号驱动的角度,电机上都有标注,一般 42 步进电机的步距角为 1.8°
  • 定位转矩:电机在不通电状态下,电机转子自身的锁定力矩(由磁场齿形的谐波以及机械误差造成)。
  • 静转矩:电机在额定静态电压作用下,电机不作旋转运动时,电机转轴的锁定力矩。此力矩是衡量电机体积的标准,与驱动电压及驱动电源等无关。

1.5.2 动态参数

  • 步距角精度:步进电机转动一个步距角度的理论值与实际值的误差。用百分比表示:误差/步距角*100%。
  • 失步:电机运转时运转的步数,不等于理论上的步数。也可以叫做丢步,一般都是因负载太大或者是频率过快。
  • 失调角:转子齿轴线偏移定子齿轴线的角度,电机运转必存在失调角,由失调角产生的误差,采用细分驱动是不能解决的。
  • 最大空载起动频率:在不加负载的情况下,能够直接起动的最大频率。
  • 最大空载的运行频率:电机不带负载的最高转速频率。
  • 运行转矩特性:电机的动态力矩取决于电机运行时的平均电流(而非静态电流),平均电流越大,电机输出力矩越大,即电机的频率特性越硬。
  • 电机正反转控制:通过改变通电顺序而改变电机的正反转。

1.6 步进电机的特点

  1. 步进电机的精度大概为步距角的 3~5%,且不会积累。
  2. 步进电机的外表允许的最高温度较高。步进电机发热的主要原因是铜损和铁损,铜损指铜导线的导电发热效应,铁损指作为铁芯的硅钢片在磁场中产生涡流效应而被加热。一般步进电机会因外表温度过高而产生磁性减小,从而导致力矩减小。一般来说磁性材料的退磁点都在摄氏 130 度以上,有的甚至高达摄氏 200度以上,所以步进电机外表温度在摄氏 80-90 度是完全正常的(28BYJ-48不会达到很高的工作温度)。
  3. 步进电机的转矩与速度成反比,速度越快力矩越小。
  4. 低速时步进电机可以正常启动,高速时不会启动,并伴有啸叫声。步进电机的空载启动频率是固定的,如果高于这个频率电机不能被启动,并且会丢步或堵转。

二、步进电机驱动

2.1 ULN2003驱动芯片

  ULN2003是一个单片高电压(最高可达50V)、高电流(单个额定输出500mA)的达林顿晶体管阵列集成电路。 它是由7对NPN达林顿晶体管组成的,它的高电压输出特性和阴极钳位二极管可以转换感应负载。单个达林顿晶体管对的集电极电流为500mA,达林顿管并联可以承受更大的电流。
  ULN2003可以作为继电器驱动器,字锤驱动器、灯驱动器、显示驱动器(LED气体放电),线路驱动器和逻辑缓冲器。ULN2003的每一对达林顿晶体管的基极都有一个2.7k的串联电阻,可以直接和TTL或者5V的CMOS装置连接。它实际上就是一个功率放大器,输出端具有较大的驱动能力(电流较大)。
  ULN2003的芯片内部原理图和引脚定义图如下所示:
在这里插入图片描述
在这里插入图片描述

2.2 驱动模块电路图

  与28BYJ-48配套的ULN2003驱动模块原理图如下图所示:
ULN2003电机驱动模块
  该模块的电路原理比较简单,具体使用时IN1、IN2、IN3、IN4分别对应A、B、C、D四相,且都为高电平有效。输入某一相为高电平时对应相的LED指示灯亮起,标识该相目前输入为有效电平。

三、代码实现

  博主在写代码的时候饶了很多弯路……,最后也参考了一些网上的代码。参考的文章和课程在文章开头有所标识。IN1~IN4分别接STM32的PA0,PA1,PA2,PA3,驱动模块的电源(5V)直接连接到ST-Link的电源输入口上,驱动模块与STM32共地。接线图略。

  • Stepper.h
#ifndef __STEPPER_H_
#define __STEPPER_H_

// 电机的旋转方向
typedef enum 
{
	Forward = 0,
	Reversal = 1
} RotDirection;

// 需要使用其他端口时,只需要更改以下的宏定义即可
// 这里需要保证四个输出端口同属一个GPIO
// 如果不能满足这一点,需要更改Stepper.c中初始化函数Stepper_Init和Stepper_RotateByStep中的一些变量名称
// 这里的宏定义是为了提高程序的可读性和可移植性,但使用stm32f10x.h中定义的原始名称也未尝不可
#define		Stepper_CLK				RCC_APB2Periph_GPIOA
#define		Stepper_Output_GPIO		GPIOA
#define 	Stepper_LA				GPIO_Pin_0
#define 	Stepper_LB				GPIO_Pin_1
#define 	Stepper_LC				GPIO_Pin_2
#define 	Stepper_LD				GPIO_Pin_3

void Stepper_GPIOInit(void);
void Stepper_Stop(void);
void Stepper_SingleStep(uint8_t StepNum, uint16_t Delay_Time_xms);
void Stepper_RotateByStep(RotDirection direction, uint32_t step, uint16_t Delay_Time_xms);
void Stepper_RotateByLoop(RotDirection direction, uint32_t Loop, uint16_t Delay_Time_xms);

#endif

  • Stepper.c
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Key.h"
#include "Stepper.h"

uint8_t STEP;	// 用于存储电机正在走过的整步编号

/**
  * @brief  步进电机输出端GPIO初始化函数
  * @param  无
  * @retval 无
  */
void Stepper_GPIOInit(void)
{
	RCC_APB2PeriphClockCmd(Stepper_CLK, ENABLE);
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;	// 推挽输出
	GPIO_InitStruct.GPIO_Pin = Stepper_LA | Stepper_LB | Stepper_LC | Stepper_LD;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(Stepper_Output_GPIO, &GPIO_InitStruct);
	
	GPIO_ResetBits(Stepper_Output_GPIO, Stepper_LA | Stepper_LB | Stepper_LC | Stepper_LD);
}

/**
  * @brief  电机停转函数
  * @param  无
  * @retval 无
  */
void Stepper_Stop(void)
{
	GPIO_ResetBits(Stepper_Output_GPIO, Stepper_LA | Stepper_LB | Stepper_LC | Stepper_LD);
}

/**
  * @brief  4拍单相整步驱动函数
  * @param  StepNum 	整步编号,0~3对应A~D
  * @param	Delay_Time_xms 		每步旋转后延时时间x ms,用于控制步进电机速度(一般需大于等于2)
  * @retval 无
  */
void Stepper_SingleStep(uint8_t StepNum, uint16_t Delay_Time_xms)
{
	switch(StepNum)
	{
		case 0:		// A
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LA, Bit_SET);
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LB | Stepper_LC | Stepper_LD, Bit_RESET);
		break;
		case 1:		// B
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LB, Bit_SET);	
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LA | Stepper_LC | Stepper_LD, Bit_RESET);
		break;			
		case 2:		// C
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LC, Bit_SET);	
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LA | Stepper_LB | Stepper_LD, Bit_RESET);
		break;
		case 3:		// D
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LD, Bit_SET);
			GPIO_WriteBit(Stepper_Output_GPIO, Stepper_LA | Stepper_LB | Stepper_LC, Bit_RESET);
		break;
		default: break;
	}
	Delay_ms(Delay_Time_xms);	// 延时,控制电机速度
	Stepper_Stop();				// 断电,防止电机过热
}

/**
  * @brief  步进电机按步旋转
  * @param  direction		电机旋转方向,可以是Forward(正传)或者Reversal(反转)
  * @param	step			电机转过的步数
  * @param	Delay_Time_xms	每步旋转后延时时间x ms,用于控制步进电机速度(一般需大于等于2)
  * @retval 无
  */
void Stepper_RotateByStep(RotDirection direction, uint32_t step, uint16_t Delay_Time_xms)
{
	for (uint32_t i = 0; i < step; i ++)
	{
		if (direction == Forward)	// 电机正传
		{
			STEP ++;
			if (STEP > 3)
			{
				STEP = 0;
			}
		}
		else if (direction == Reversal)	// 电机反转
		{
			if (STEP < 1)
			{
				STEP = 4;
			}
			STEP --;
		}
		Stepper_SingleStep(STEP, Delay_Time_xms);
	}
}

/**
  * @brief  步进电机按整数圈旋转
  * @param  direction		电机旋转方向,可以是Forward(正传)或者Reversal(反转)
  * @param  Loop			电机旋转的圈数
  * @param  Delay_Time_xms	每步旋转后延时时间x ms,用于控制步进电机速度(一般需大于等于2)
  * @retval 
  */
void Stepper_RotateByLoop(RotDirection direction, uint32_t Loop, uint16_t Delay_Time_xms)
{
	Stepper_RotateByStep(direction, Loop * 2048, Delay_Time_xms);
}

  Stepper_RotateByLoop函数中Loop * 2048是博主根据28BYJ-48步进电机的性能参数列表计算和实践调试所得。这里博主使用四拍驱动方式,如果要使用8拍的半步驱动方式,2048应该改为4096。读者手中的28BYJ-48的齿轮减速比可能与博主的有所不同(1:16 or 1:64),根据测试,博主手头的28BYJ-48的参数如下表所示:

型号电压相数步距角减速齿轮减速比最大空载启动频率最大空载运行频率
28BYJ-485V45.625° / 321:32600Hz1000Hz
  • Key.cKey.h在这里省略,在头文件中将函数进行声明即可)
#include "stm32f10x.h"                  // Device header
#include "Delay.h"

/**
  * @brief  按键初始化函数
  * @param  无
  * @retval 无
  */
void Key_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	// 这里的速度是GPIO的输出速度,在输入模式下这个参数选择没有用处
	
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

/**
  * @brief  返回按下按键的值,若不按下按键默认返回0
  * @param  无
  * @retval KeyNum 按键对应的值,按下PB1按键返回1,按下PB11按键返回2
  */
uint8_t Key_GetNum(void)
{
	uint8_t KeyNum = 0;
	
	if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)	// 读取1端口的值
	{
		Delay_ms(20);
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);	// 如果不松手,程序将在此等待
		Delay_ms(20);
		KeyNum = 1;
	}
	if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)	// 读取11端口的值
	{
		Delay_ms(20);
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);	// 如果不松手,程序将在此等待
		Delay_ms(20);
		KeyNum = 2;
	}
	
	return KeyNum;
}

  • main.c
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"
#include "Stepper.h"

uint8_t KeyNum;

int main()
{
	Key_Init();
	Stepper_GPIOInit();
	
//	Stepper_RotateByStep(Forward, 512, 3);
//	Stepper_RotateByStep(Reversal, 512, 3);
//	Stepper_RotateByLoop(Forward, 1, 3);
	
	while(1)
	{	
		KeyNum = Key_GetNum();
		if (KeyNum == 1)	// 按下PB1上的按键,步进电机正转一圈
		{
			Stepper_RotateByLoop(Forward, 1, 3);
		}
		if (KeyNum == 2)	// 按下PB11上的按键,步进电机反转一圈
		{
			Stepper_RotateByLoop(Reversal, 1, 3);
		}
	}
}


  原创内容,整理不易,欢迎点赞,收藏~ 如有谬误敬请在评论区不吝告知,感激不尽!博主将持续更新有关嵌入式开发、机器学习方面的学习笔记~

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

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

相关文章

hcia回顾复习

一、OSI七层参考模型 OSI/RM 开放式系统互联参考模型 由ISO ---- 国际标准化组织 — 1979提出 核心思想 分层 :上层协议再下层协议提供服务的基础上再提供增值服务。 应用层 — 提供各种应用服务.可以将抽象语言转换为编码 .应用程序 APP&#xff1a;通过人机交互提供&#xff…

Win10打字输入法不显示输入框怎么办?

Win10的打字输入法是我们日常计算机使用中必不可少的工具之一&#xff0c;然而&#xff0c;有时候在使用过程中可能会遇到打字输入法不显示输入框的问题&#xff0c;这给我们的输入和操作带来了很大的困扰&#xff0c;如果您也遇到了这个问题&#xff0c;不要担心&#xff0c;以…

Linux--获取某个区间文本的指令:head和tail

Linux--获取文本前n行的指令&#xff1a;head 语法&#xff1a; head 选项 文件名 功能&#xff1a; head 用来显示档案的开头至标准输出中&#xff0c;默认head命令打印其相应文件的开头10行。 选项&#xff1a; -n <行数> 显示的行数 示例&#xff1a; ①生成默…

【UE5 Cesium】05-Cesium for Unreal 在子关卡中添加Actor

上一篇&#xff1a;【UE5 Cesium】04-Cesium for Unreal 将不同地区的倾斜摄影作为不同子关卡 步骤 首先将关卡切换到“DenverRooftop” 添加一个“立方体” 将关卡切换到“Globe” 然后再向场景中添加一个“椎体” 此时如果我们将关卡切换到“Boston”&#xff0c;只能看到“…

如何高效获取嵌入式系统知识和技能

学习嵌入式系统的方法&#xff1a; 设定明确的目标&#xff1a;在学习嵌入式系统之前&#xff0c;明确自己的学习目标和期望结果。这可以帮助你更有针对性地选择学习材料和项目&#xff0c;并保持专注和动力。 分解学习计划&#xff1a;将学习过程分解成小的可管理的任务和阶段…

SQL注入经验方法总结

SQL注入 先判断是哪种数据库。再进行后续操作。 SQL注入漏洞产生的原理 web应用程序&#xff0c;对用户输入的语句没有做严格的过滤&#xff0c;导致被输入的语句被拼接成恶意代码的SQL语句进入数据库中查询&#xff0c;修改信息等。 所以SQL注入漏洞需要的条件&#xff1a…

chatglm2 本地部署中遇到的问题

在本地GPU部署的时候&#xff0c;发现了报错&#xff0c; ModuleNotFoundError: No module named transformers_modules.chatglm2-6b 但是自己路径都是正确的&#xff0c; 确实是按照双斜杠来写的路径。 但依旧报错 最后发现是安装的 transformers 包的版本太新导致的。 …

抖音SEO账号矩阵系统源码

一、抖音SEO账号矩阵系统源码思路 1. 数据采集与分析 2. 排名算法设计 3. 用户管理模块 4. 内容推荐系统 二、抖音矩阵系统源码功能概述 &#xff08;1&#xff09;多平台多账号管理,支持抖音&#xff0c;快手&#xff0c;好看视频&#xff0c;B站&#xff0c;西瓜&#x…

jdbc获取数据库元数据信息

DatabaseMetaData 接口&#xff1a; 获取数据库&#xff0c;&#xff0c;&#xff0c;表&#xff0c;&#xff0c;列&#xff0c;&#xff0c;等元数据信息 jdbc使用&#xff1a; // 获取一个连接 Connection connection DriverManager.getConnection(url,username,password)…

葡萄酒数据可视化分析

葡萄酒数据可视化分析 必应壁纸供图 数据集&#xff1a;https://download.csdn.net/download/weixin_53742691/87982219 import pandas as pd import seaborn as sns import matplotlib.pyplot as pltwine pd.read_csv("wine_quality/wine_edited.csv") wine.hea…

chatgpt赋能python:用Python来制作动画

用Python来制作动画 Python是一种高级编程语言&#xff0c;可以用于许多任务&#xff0c;包括数据分析、网络编程&#xff0c;甚至是制作动画。在这篇文章中&#xff0c;我们将讨论如何使用Python来制作动画。 Python中的动画库 Python中有许多用于制作动画的库。其中最流行…

论文笔记--Goat: Fine-tuned LLaMA Outperforms GPT-4 on Arithmetic Tasks

论文笔记--Goat: Fine-tuned LLaMA Outperforms GPT-4 on Arithmetic Tasks 1. 文章简介2. 文章概括3 文章重点技术3.1 LLM的选择3.2 算数任务的可学习性(learnability)3.3 大模型的加减乘除 4. 数值实验结果5. 文章亮点6. 原文传送门7. References 1. 文章简介 标题&#xff…

选读SQL经典实例笔记01_检索和排序

1. 在WHERE子句中引用别名列 1.1. 当表里的某些列没有被恰当命名的时候&#xff0c;这个技巧尤其有用 1.2. sql select sal as salary, comm as commissionfrom empwhere salary &#xff1c; 5000 1.3. 内嵌视图 1.3.1. sql select *from (select sal as salary, comm …

按 DDD 设计这个新项目

一、专业术语 各种服务 IAAS&#xff1a;基础设施服务&#xff0c;Infrastructure-as-a-service PAAS&#xff1a;平台服务&#xff0c;Platform-as-a-service SAAS&#xff1a;软件服务&#xff0c;Software-as-a-service 二、架构演变 图片 从图中已经可以很容易看出架…

R 语言 ggplot2 PCA 主成分分析(虚拟数据集)

生成虚拟数据集 library(ggplot2)data.matrix <- matrix(nrow 100, ncol 10)colnames(data.matrix) <- c(paste("wt",1:5,sep ""),paste("ko",1:5,sep "") )rownames(data.matrix) <- paste("gene",1:100,sep…

vue安装|win11系统

1.安装node.js https://nodejs.org/en/download 下载对应系统对应位数的.msi文件&#xff0c; 下载完成后&#xff0c;一直点击next进行安装 自定义安装路径&#xff0c;我的安装路径为**“D:\nodejs”** # 检查node.js版本 node -V# 检查npm版本 npm -V在D:\nodejs下新建两…

DataGrip连接clickhouse

首先保证ClickHouse启动了&#xff1a; 先建一个工程&#xff1a; 建立数据库源连接&#xff1a; 用户名和密码可以不写&#xff1a; 添加ClickHouse驱动&#xff1a;最好不用自己下载的驱动&#xff0c;会出现一些错误以及连接失败&#xff0c;用在线下载的。 选择一个版…

《深入浅出SSD:固态存储核心技术、原理与实战》----学习记录(三)

第3章 SSD存储介质&#xff1a;闪存 3.1 闪存物理结构 3.1.1 闪存器件原理 1978年诞生的世界上第一块固态硬盘就是基于DRAM的。但由于保存在DRAM中的数据有掉电易失性&#xff0c;当然还有成本因素&#xff0c;所以现在的固态硬盘一般都不采用DRAM&#xff0c;而是使用闪存…

JS对象的浅拷贝与深拷贝

一. 浅拷贝 定义&#xff1a;浅拷贝是按位拷贝对象&#xff0c;它会创建一个新对象&#xff0c;这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型&#xff0c;拷贝的就是基本类型的值&#xff1b;如果属性是内存地址&#xff08;引用类型&#xff09;&#xff0c…

DETRs Beat YOLOs on Real-time Object Detection论文详解

论文题目&#xff1a;DETRs Beat YOLOs on Real-time Object Detection 论文地址&#xff1a;https://arxiv.org/abs/2304.08069 论文代码&#xff1a;mirrors / facebookresearch / ConvNeXt GitCode 等我毕业再打败吧&#xff0c;别打败YOLO&#xff0c;广大研究生们不同…