当前位置: 首页 > news >正文

第36章_瑞萨MCU零基础入门系列教程之步进电机控制实验

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写,需要的同学可以在这里获取: https://item.taobao.com/item.htm?id=728461040949

配套资料获取:https://renesas-docs.100ask.net

瑞萨MCU零基础入门系列教程汇总: https://blog.csdn.net/qq_35181236/article/details/132779862


第36章 步进电机控制实验

36.1 24BYJ-48步进电机工作原理

本书使用的步进电机型号是28BYJ-48,它是一款常见的步机电机,其名称的含义为外径28毫米四相八拍式永磁减速型步进电机。型号的含义如下:

  • 28:步进电机的有效最大外径是28毫米
  • B:表示是步进电机
  • Y:表示是永磁式
  • J:表示是减速型(减速比1:64)
  • 48:表示四相八拍

先说什么是“4相永磁式”的概念,28BYJ-48 的内部结构示意图如下所示。

先看里圈,它上面有8个齿,分别标注为0~7,这个叫做转子,顾名思义,它是要转动的。转子的每个齿上都带有永久的磁性,是一块永磁体,这就是“永磁式”的概念。

再看外圈,这个是定子,它是保持不动的,实际上它是跟电机的外壳固定在一起的。定子有ABCD四组共32个齿,每个齿上都缠上了一个线圈绕组。A组有8个线圈绕组,它们是串联在一起的,这8个线圈绕组会同时导通或关断。B、C、D组也是一样的,如此就形成了4相,在图中分别标注为 A-B-C-D,这就是“4相”的概念。相邻定子之间的夹角为360/32=11.25度。

步进电机一共有5根线引出,红色是公共端,接5v电源,其他四根分别对应A,B,C ,D 四个绕组的另外一端。怎样让电机转动起来呢?

假设初始状态时A导通,A组的8个线圈绕组都有磁力,吸引住8个转子,8个转子和8个A组定子对齐,如上图所示。

然后让A断开,B导通,此时B组的8个线圈绕组会把距离它最近的8个转子吸引过来,使得转子和B组的定子对齐。以0号转子为例,它从正对着A定子的位置,顺时针旋转到正对着B定子的位置,顺时针旋转了11.25度。

紧接着,让B断开,C导通,此时C组的8个线圈绕组会把距离它最近的8个转子吸引过来,使得转子和C组的定子对齐。以0号转子为例,它从正对着B定子的位置,顺时针旋转到正对着C定子的位置,再次顺时针旋转了11.25度。当我们依次单独导通ABCD时,电动机就顺时针转到起来了。

单独导通ABCD的某一组线圈绕组时,转子旋转11.25度,这个值就叫做步进角度。

而上述这种工作模式就是步进电机的单四拍模式。同样的道理,如果想让转子逆时针转动,可以依次单独导通DCBA。

我们再来介绍一种具有更优性能的工作模式,那就是在单四拍的每两个节拍之间再插入一个双绕组导通的中间节拍,组成八拍模式。

比如,在顺时针转动过程中,从 A 相导通到 B 相导通的中间,加入一个 A 相和 B 相同时导通的节拍,这个时候,由于 A、B 两个绕组的定子齿对它们附近的转子齿同时产生相同的吸引力,这将0号转子处于 A、B 两个定子中间,也就是新插入的这个节拍使转子转过了上述单四拍模式中步进角度的一半,即5.625度。这样一来,就使转动精度增加了一倍,而转子转动一圈则需要8*8=64拍了。另外,新增加的这个中间节拍,还会在原来单四拍的两个节拍引力之间又加了一把引力,从而可以大大增加电机的整体扭力输出,使电机更“有劲”了,而且更平顺。

下表给出八拍模式下电机绕组激励时序(电机引线颜色可能因厂家不同而不同):

本文将以八拍模式展开编程演示,当按照下表的数值,连续给电机提供激励时,电机就逆时针转起来。

28BYJ-48为减速电机,电机输出的转速并不等于转子的转速。下图是这个28BYJ-48步进电机的拆解图,从图中可以看到,位于最中心的那个白色小齿轮才是步进电机的转子输出,64个节拍只是让这个小齿轮转了一圈,然后它带动那个浅蓝色的大齿轮,这就是一级减速。

右上方的白色齿轮的结构,除电机转子和最终输出轴外的3个传动齿轮都是这样的结构,由一层多齿和一层少齿构成,而每一个齿轮都用自己的少齿层去驱动下一个齿轮的多齿层,这样每2个齿轮都构成一级减速,一共就有了4级减速。

36.2 电机驱动板工作原理

根据28BYJ-48电机原理,我们只需要将开发板的四个引脚(通常为GPIO)分别连接到电机,再按照电机的驱动逻辑给出一定的激励信号。但是开发板的GPIO驱动能力有限,需要在开发板和电机之间加入驱动电路,本教程选择了双路有刷直流马达驱动芯片MX1508,驱动电路原理图见下图:

开发板的GPIO0~GPIO3引脚直接连接MX1508的INA1、INB1、INA2、INB2。MX1508的输出端OUTA1、OUTB1、OUTA2、OUTB2分别接到步进电机28BYJ-48的A、B、C、D四个线圈。所以,可以通过开发板的4个GPIO引脚,间接控制电机的ABCD。并不是使用4个GPIO简单地控制ABCD,它们不是一一对应的关系。

需要先了解MX1508芯片内部电路和基本工作模式:

  1. 待机模式

在待机模式下,INAx=INBx=L。包括驱动功率管在内的所有内部电路都处于关断状态。电路消耗极低极低的电流。此时马达输出端 OUTAx 和 OUTBx 都为高阻状态(记为Z)。

  1. 正转模式

正转模式的定义为:INAx=H,INBx=L,此时马达驱动端 OUTAx 输出高电平,马达驱动端 OUTBx 输出低电平时,马达驱动电流从 OUTAx 流入马达,从 OUTBx 流到地端,此时马达的转动定义为正转模式。

  1. 反转模式

反转模式的定义为:INAx=L,INBx=H,此时马达驱动端 OUTBx 输出高电平,马达驱动端 OUTAx 输出低电平时,马达驱动电流从 OUTBx 流入马达,从 OUTAx 流到地端,此时马达的转动定义为反转模式。

  1. 刹车模式

刹车模式的定义为:INAx=H,INBx=H,此时马达驱动端 OUTAx 以及 OUTBx 都输出低电平,马达内存储的能量将通过 OUTAx 端 NMOS 管或者 OUTBx 端 NMOS 快速释放,马达在短时间内就会停止转动。注意在刹车模式下电路将消耗静态功耗。

  1. PWM 模式A

当输入信号 INAx 为 PWM 信号,INBx=0 或者 INAx=0,INBx 为 PWM 信号时,马达的转动速度将受到 PWM信号占空比的控制。在这个模式下,马达驱动电路是在导通和待机模式之间切换,在待机模式下,所有功率管都处于关断状态,马达内部储存的能量只能通过功率 MOSFET 的体二极管缓慢释放。

当输入信号 INAx 为 PWM 信号,INBx=1 或者 INAx=1,INBx 为 PWM 信号时,马达的转动速度将受到 PWM信号占空比的控制。在这个模式下,马达驱动电路输出在导通和刹车模式之间,在刹车模式下马达存储的能量通过低边的 NMOS 管快速释放。

综上所述,MX1508的真值表如下:

上述真表中,OUTAx/OUTBx输出Z(高阻态)、H(高电平)时,连接到的电机线圈绕组都不会导通,效果是一样的。

为了让ABCD输出8个节拍,可以按照下图控制GPIO0~GPIO3:

以第1个节拍为例,想让D输出0,ABC输出高电平或是高阻态,怎么办?换句话说,想让OUTB2=L,OUTA2、OUTA1、OUTB1等于H或Z,怎么办?

根据真值表,设置INA2=H、INB2=L,可以让OUTA2=H、OUTB2=L:

继续根据真值表,设置INA1=L、INB1=L,可以让OUTA1=Z、OUTB1=Z:

所以,要让D输出0,ABC输出高电平或是高阻态时,需要:INA1=L、INB1=L、INA2=H、INB2=L。即:GPIO0=0、GPIO1=0、GPIO2=1、GPIO3=0,用二进制表示即为:0b0100,即0x04。

将8个节拍对应的GPIO值存到数组中:

S_CW[8]= {0x04,0x0c,0x08,0x09,0x01,0x03,0x02,0x06};

把4个GPIO配置为输出后,将数组的值循环写到GPIO输出寄存器,就可以让电机转动起来。按照反向的顺序循环写GPIO输出寄存器,就可以实现电机反转。调节两个节拍间的周期,可以改变电机转速。

根据电机的参数:空载牵入频率≥600Hz 可知,两个节拍之间的时间间隔不宜小于1.6ms。

36.3 模块配置

本次实验实质上驱动的外设只有一个,那就是GPIO。但是为了更好的驱动电机,本次实验还使用了UART:让用户输入角度、速度,并使用定时器来实现精准延时。

本实验使用的步进电机模块会接到扩展板的GPIO组,会使用到4个GPIO来接电机驱动板的INA/B/C/D,扩展板GPIO组原理图如下图所示:


本实验使用的是GPIO0~3,所以需要在RASC中将这4个IO对应的引脚配置为通用输出模式,请读者参考本书前文对于GPIO的配置来配置这4个引脚。

36.4 外设驱动程序

本次实验使用到的IO设备、串口设备和定时器设备在《30.3 设备对象封装》中已经将结果,使用到的方法基本一致,请读者参考前文了解设备对象封装的概念和方法,以及下载本书配套资料调阅源码学习。

36.5 电机驱动程序

36.5.1 电机设备对象

对于电机,用户需要的操作是:启停、设定转动角度(角度、速度)。根据这些需求,封装出电机的结构体(dev_motor.h):

typedef struct StepMotor{char *name;MotorStatus status;int (*Init)(struct StepMotor *ptdev);int (*Start)(struct StepMotor *ptdev);int (*Stop)(struct StepMotor *ptdev);int (*SetAngle)(struct StepMotor *ptdev, int speed, int value);
}StepMotorDevice;

然后在dev_motor.c里构造一个StepMotor结构体,并给上层代码提高获得这个结构体的函数,代码如下:

static struct StepMotor gMotor = {.name   = "Step Motor",.status = 0,.Init   = StepMotorDevInit,.Start  = StepMotorDevStart,.Stop   = StepMotorDevStop,.SetAngle = StepMotorDevSetAngle
};struct StepMotor *MotorGetDevice(void)
{return &gMotor;
}

36.5.2 初始化函数

初始化函数中要实现的就是获取4个IO设备对象,代码如下:

static int StepMotorDevInit (struct StepMotor *ptdev)
{if(NULL == ptdev)   return -EINVAL;gINAIO = IODeviceFind("Step Motor INA");if(NULL == gINAIO)  return -ENODEV;gINBIO = IODeviceFind("Step Motor INB");if(NULL == gINBIO)  return -ENODEV;gINCIO = IODeviceFind("Step Motor INC");if(NULL == gINCIO)  return -ENODEV;gINDIO = IODeviceFind("Step Motor IND");if(NULL == gINDIO)  return -ENODEV;return ESUCCESS;
}

36.5.3 开启转动

本书并没有在Start函数中让步进电机转动,仅仅是修改状态表示电机处于开启状态,代码如下;

static int StepMotorDevStart(struct StepMotor *ptdev)
{if(NULL == ptdev)   return -EINVAL;if(ptdev->status == isStop){ptdev->status = isRunning;return ESUCCESS;}return -EIO;
}

36.5.4 停止转动

将电机状态标志赋值为0,并且让步进电机的4个IO都输出低电平。代码如下:

static int StepMotorDevStop (struct StepMotor *ptdev)
{if(NULL == ptdev)   return -EINVAL;if(ptdev->status == isRunning){ptdev->status = isStop;gINAIO->Write(gINAIO, 0);gINBIO->Write(gINBIO, 0);gINCIO->Write(gINCIO, 0);gINDIO->Write(gINDIO, 0);return ESUCCESS;}return -EIO;
}

36.5.5 设定转速和转动角度

通过前面的讲解可以知道,24BYJ-48步进电机内部收到64个节拍会转动1圈,转子通过减速齿轮驱动输出轴转动1/64圈。那么要想输出轴转动1圈,就需要给步进电机4096个节拍(64*64=4096)。如果想要转动指定角度angle,那么对应的拍数计算公式就是:

step=angle*4096/360

另外还可以顺序、逆序使用S_CW[8]数组的值来驱动电机以实现反转、正转。而电机转速则表现在每拍之间的间隔时间,间隔越长,转速越慢。

根据这些原理,就可以将设置步进电机转角和转速的功能封装到一个函数中了:

static const uint8_t EightBeat[8] = {0x04,0x0c,0x08,0x09,0x01,0x03,0x02,0x06};
static int StepMotorDevSetAngle(struct StepMotor *ptdev, int speed, int value)
{if(NULL == ptdev)   return -EINVAL;if(1 > speed)       return -EINVAL;int nAbsValue = (value>=0)?value:-value;unsigned int step = (unsigned int)(nAbsValue*4096/360);unsigned int phase = 0;if(isStop == ptdev->status)ptdev->Start(ptdev);for(unsigned int i=0; i<step; i++){if(value>0)phase = (i&0x07);elsephase = (7-(i&0x07));gINAIO->Write(gINAIO, ((EightBeat[phase]&0x08)==0)?0:1);gINBIO->Write(gINBIO, ((EightBeat[phase]&0x04)==0)?0:1);gINCIO->Write(gINCIO, ((EightBeat[phase]&0x02)==0)?0:1);gINDIO->Write(gINDIO, ((EightBeat[phase]&0x01)==0)?0:1);mdelay(speed);}ptdev->Stop(ptdev);return ESUCCESS;
}

36.6 测试程序

本次实验的方法是:让用户通过串口输入角度、速度,然后控制步进电机转动。代码如下:

void DeviceTest(void)
{UartDevicesRegister();TimerDevicesRegister();IODevicesRegister();StepMotorDevice *pMotor = MotorGetDevice();if(NULL == pMotor){xprintf("Failed to Find Motor Device!\r\n");return;}pMotor->Init(pMotor);pMotor->Start(pMotor);while(1){xprintf("Enter value(+- 0~360 degree) and speed(Greater than 1ms) parameters you want: \r\n\t");int value = 0, speed = 0;scanf("%d%d", &value, &speed);xprintf("\tValue:%d\tSpeed:%d\r\n", value, speed);pMotor->SetAngle(pMotor, speed, value);}
}

36.7 测试结果

将程序烧写到开发板中运行,打开串口助手,插上步进电机后,通过串口助手输入转角和转速:

步进电机就会逆时针或者顺时针转动指定的角度


本章完

相关文章:

第36章_瑞萨MCU零基础入门系列教程之步进电机控制实验

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…...

198.打家劫舍,213.打家劫舍II,337.打家劫舍III

代码随想录训练营第48天|198.打家劫舍&#xff0c;213.打家劫舍II&#xff0c;337.打家劫舍III 198.打家劫舍文章思路代码 213.打家劫舍III文章思路代码 337.打家劫舍III文章思路代码 总结 198.打家劫舍 文章 代码随想录|0198.打家劫舍 思路 d p [ i ] M a x ( d p [ i − …...

msvcp140.dll是什么东西,如何解决msvcp140.dll丢失的问题的方法分享

在现代生活中&#xff0c;电脑已经成为我们工作、学习和娱乐的重要工具。然而&#xff0c;电脑问题的出现往往会给我们的生活带来不便。其中&#xff0c;"msvcp140.dll丢失"是一个常见的电脑问题。本文将详细介绍这个问题的原因和解决方法&#xff0c;帮助大家更好地…...

音视频 SDL vs2017配置

一、首先我把SDL放在了C盘根目录下 二、新建空项目 三、添加main.cpp //main.cpp #include<iostream> #include <SDL.h>int main(int argc, char* argv[]) // main函数头必须这样写&#xff0c;因为SDL把main定义成了宏 {SDL_Delay(3000); // 让窗口在屏幕上保持…...

前端面试要点

0914 JScript深拷贝和浅拷贝&#xff08;js解构赋值算哪个&#xff1f;&#xff09; 深拷贝和浅拷贝 回流和重绘 回流和重绘 webpack打包流程 Webpack打包 虚拟DOM 虚拟DOM git合并分支 git合并分支 CSS盒子模型 CSS盒子模型 0911 WebPack分包 webpack分包 ts泛型 ts泛型 优化…...

shell字符串处理之字符串比较

引言 我们在使用shell编写脚本时&#xff0c;经常需要对字符串进行处理&#xff0c;如字符串大小比较、模式匹配、替换、截断等。本文将梳理字符串比较中常见的用法。 字符串比较 1. 直接比较字符串 a$1 b$2 c"" # 等于 if [ $a "abc" ];thenecho $a …...

怎么获取别人店铺的商品呢?

jd.item_search_shop(获得店铺的所有商品) 为了进行电商平台 的API开发&#xff0c;首先我们需要做下面几件事情。 1&#xff09;开发者注册一个账号 2&#xff09;然后为每个JD应用注册一个应用程序键&#xff08;App Key) 。 3&#xff09;下载JDAPI的SDK并掌握基本的API…...

【数据结构】二叉树的链式结构

【数据结构】二叉树的链式存储结构 二叉树的存储结构 typedef int BTDataType; // 二叉树的结构 typedef struct BinaryTreeNode {BTDataType data; // 树的值struct BinaryTreeNode *left; // 左孩子struct BinaryTreeNode *right;// 右孩子 } BinaryTreeNode;二…...

模拟实现C语言--strlen函数

模拟实现C语言–strlen函数 模拟实现C语言--strlen函数一、strlen函数是什么&#xff1f;二、strlen函数的模拟实现2.1 计数器方式实现strlen函数2.2 不创建临时变量计数器方式实现strlen函数2.3 指针-指针方式实现strlen函数 三、strlen函数的返回类型 一、strlen函数是什么&a…...

Spring Boot + Vue的网上商城之物流系统实现

Spring Boot Vue的网上商城之物流系统实现 思路 当构建一个物流系统时&#xff0c;我们可以按照以下步骤进行&#xff1a; 设计数据模型&#xff1a;首先确定系统中需要存储的数据&#xff0c;例如物流公司信息、物流订单信息等。根据需求设计相应的数据模型&#xff0c;包括…...

释放数据价值这道难题,Smartbi V11有解

《未来简史》预言&#xff1a;数据将成为人们未来的信仰。 未来已来&#xff0c;将至已至。如今&#xff0c;数据所扮演的角色与作用超乎想象。从政府将数据要素列入生产要素之中&#xff0c;到数据驱动型业务场景涌现&#xff0c;企业与组织对于数据及其价值的认可度明显提升…...

Day_14 > 指针进阶(3)> bubble函数

目录 1.回顾回调函数 2.写一个bubble_sort函数 2.1认识一下qsort函数 ​编辑2.2写bubble_sort函数 今天我们继续深入学习指针 1.回顾回调函数 我们回顾一下之前学过的回调函数 回调函数就是一个通过函数指针调用的函数 如果你把函数的指针&#xff08;地址&#xff09;…...

sql中怎么查books表下面的内容

要查询 books 表中的所有内容&#xff0c;你可以使用以下 SQL 语句&#xff1a; USE bookmanagement; -- 选择数据库 SELECT * FROM books; -- 查询books表中的所有内容如果你使用的是命令行界面 (mysql 客户端) 来操作数据库&#xff0c;可以直接在命令提示符中输入上述命令…...

Vulnhub系列靶机---HarryPotter-Aragog-1.0.2哈利波特系列靶机-1

文章目录 方式一信息收集主机发现端口扫描目录扫描wpscan工具 漏洞利用msf工具数据库权限用户权限root提权 方式二信息收集gobuster扫描wpscan扫描 漏洞利用POC 靶机文档&#xff1a;HarryPotter: Aragog (1.0.2) 下载地址&#xff1a;Download (Mirror) 方式一 信息收集 主机…...

.NET 8发布首个RC,比.NET 7的超级快更快

.NET 8 发布了首个 RC。据称 RC 阶段会发布两个版本&#xff0c;正式版将于 2023 年 11 月 14 日至 16 日在 .NET Conf 2023 上推出。.NET 8 是长期支持 (LTS) 版本&#xff0c;将会获得 3 年技术支持。 公告写道&#xff0c;此版本为 Android 和 WASM 引入了全新的 AOT 模式、…...

在 Substance Painter中自定义Shader

为什么要学习在Substance Painter中自定义Shader&#xff1f; 答&#xff1a;需要实现引擎与Substance Painter中的渲染效果一致&#xff0c;材质的配置也一致&#xff0c;所见即所得。 基础概述 首先在着色器设置这里&#xff0c;我们可以查看当前渲染使用的着色器 如果没有…...

【自学开发之旅】Flask-restful-Jinjia页面编写template-回顾(五)

restful是web编程里重要的概念 – 一种接口规范也是一种接口设计风格 设计接口&#xff1a; 要考虑&#xff1a;数据返回、接收数据的方式、url、方法 统一风格 rest–表现层状态转移 web–每一类数据–资源 资源通过http的动作来实现状态转移 GET、PUT、POST、DELETE path…...

input 的 placeholder 样式

::placeholder 伪元素 这个伪元素可以改变 input、textarea 占位文本的样式。 input::placeholder {color: green; }完整的兼容性写法&#xff1a; input {&::-webkit-input-placeholder, /* WebKit browsers*/ &:-moz-input-placeholder, /* Mozilla Firefox 4 to …...

4.4-Spring源码循环依赖终极讲解

回顾上期内容 new 容器 new AnnotateBeanDefinitionReader 的时候创建很多创世纪的类&#xff0c;其中有一个ConfigurationPostProcessor是用来解析配置类的&#xff0c;将其注册起来存到Bean定义的Map中【这个类是基于Bean工厂后置处理器的】 这一步是将配置类注册到Bean定…...

腾讯云4核8G服务器选CVM还是轻量比较好?价格对比

腾讯云4核8G云服务器可以选择轻量应用服务器或CVM云服务器标准型S5实例&#xff0c;轻量4核8G12M服务器446元一年&#xff0c;CVM S5云服务器935元一年&#xff0c;相对于云服务器CVM&#xff0c;轻量应用服务器性价比更高&#xff0c;轻量服务器CPU和CVM有区别吗&#xff1f;性…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

Matlab实现任意伪彩色图像可视化显示

Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中&#xff0c;如何展示好看的实验结果图像非常重要&#xff01;&#xff01;&#xff01; 1、灰度原始图像 灰度图像每个像素点只有一个数值&#xff0c;代表该点的​​亮度&#xff08;或…...

文件上传漏洞防御全攻略

要全面防范文件上传漏洞&#xff0c;需构建多层防御体系&#xff0c;结合技术验证、存储隔离与权限控制&#xff1a; &#x1f512; 一、基础防护层 前端校验&#xff08;仅辅助&#xff09; 通过JavaScript限制文件后缀名&#xff08;白名单&#xff09;和大小&#xff0c;提…...

手动给中文分词和 直接用神经网络RNN做有什么区别

手动分词和基于神经网络&#xff08;如 RNN&#xff09;的自动分词在原理、实现方式和效果上有显著差异&#xff0c;以下是核心对比&#xff1a; 1. 实现原理对比 对比维度手动分词&#xff08;规则 / 词典驱动&#xff09;神经网络 RNN 分词&#xff08;数据驱动&#xff09…...

使用python进行图像处理—图像滤波(5)

图像滤波是图像处理中最基本和最重要的操作之一。它的目的是在空间域上修改图像的像素值&#xff0c;以达到平滑&#xff08;去噪&#xff09;、锐化、边缘检测等效果。滤波通常通过卷积操作实现。 5.1卷积(Convolution)原理 卷积是滤波的核心。它是一种数学运算&#xff0c;…...