MCU、ARM体系结构,单片机基础,单片机操作
计算机基础
计算机的组成
输入设备、输出设备、存储器、运算器、控制器
- 输入设备:将其他信号转换为计算机可以识别的信号(电信号)。
- 输出设备:将电信号(0、1)转为人或其他设备能理解的信号。
- 运算器:CPU对信息处理和运算的部件,常进行算术运算和逻辑运算,其核心是算术逻辑单元ALU,CPU中用各种各样的数字电路搭配成各种各样的运算电路,如:加、减法等。
- 控制器:整个计算机的指挥中心
- 存储器:存放程序和数据的部件,也是计算机能够实现“存储程序控制”的基础。
程序:指令的有序集合
ROM: flash (EMMC)、磁盘空间 、掉电不丢失数据
只读存储器_百度百科
RAM: 内存、掉电丢失数据
随机存取存储器_百度百科
IO逻辑(输入/输出)
计算机系统中的高低电平逻辑1和0,数据在计算机中的存储、传输、运算都是以二进制形式进行的。
数据的传输通过总线真正传递的是电信号,高低电平(0、1)。运算在电路中进行,集成电路中运算。
电压:电压差 电势差
模拟信号:模拟信号是连续的,模拟信号可以是任意数值状态;
数字信号:数字信号是离散(不连续)的,数字信号只有“0”和“1”两种状态
三级存储结构
cache: 速度快、价格贵、容量小、断电丢失、CPU可以直接访问。存储当前正在执行的程序中的活跃部分,以便快速地向CPU提供指令和数据
基本原理:
高速缓存Cache详解(西电考研向)_多路组相联-CSDN博客
主存储器:速度、价格、容量介于CACHE和辅助存储器之间、断电丢失、CPU可以直接访问。存储当前正在执行的程序和数据
辅助存储器:速度慢、价格低、容量大、断电不丢失、cpu不可以直接访问。存储暂时不运行的程序和数据,需要时再传送到主存
Cache对程序员来说一般会有透明性,也就是程序员其实是看不到Cache的,因此不能对它进行操作。
总线
总线(Bus)是计算机各种功能部件之间传送信息的公共通信干线,它是由导线组成的传输线束, 按照计算机所传输的信息种类,计算机的总线可以划分为数据总线、地址总线和控制总线,分别用来传输数据、数据地址和控制信号(系统总线)。
数据总线
(1)是CPU与内存或其他器件之间的数据传送的通道。
(2)数据总线的宽度决定了CPU和外界的数据传送速度。
(3)每条传输线一次只能传输1位二进制数据。如: 8根数据线一次可传送一个8位二进制数据(即一个字节)。
(4)数据总线是数据线数量之和。
地址总线
(1)CPU是通过地址总线来指定存储单元的。
(2)地址总线决定了cpu所能访问的最大内存空间的大小。如: 10根地址线能访问的最大的内存为1024位二进制数据(1024个内存单元)
(3)地址总线是地址线数量之和。
控制总线
(1)CPU通过控制总线对外部器件进行控制。
(2)控制总线的宽度决定了CPU对外部器件的控制能力。
(3)控制总线是控制线数量之和。
总结:
数据总线的宽度决定CPU与其他元器件一次最大传送的数据量;
地址总线的宽度决定CPU的寻址能力;
控制总线决定CPU对其他元器件的控制能力。
例子
DMA总线
DMA(Direct Memory Access)即直接存储器访问,使用DMA总线可以不通过CPU直接在存储器及外设之间进行数据传递。(不做控制功能)
单片机基础
单片机简介
单片机(Single-Chip Microcomputer)是一种集成电路芯片。
微控制单元(Microcontroller Unit;MCU) ,又称单片微型计算机(Single Chip Microcomputer )或者单片机,其采用集成电路技术将具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、定时器/计时器、多种I/O口和中断系统等功能集成到一块硅片上。可以说单片机就是一个小而完善的微型计算机系统。
https://www.bilibili.com/video/BV1HW411a7SS/?spm_id_from=333.337.search-card.all.click&vd_source=2820d6227cdfd0cc24c48e011da53b66
SoC(System on Chip),片上系统SoC的定义多种多样,由于其内涵丰富、应用范围广,很难给出准确定义。一般说来, SoC称为系统级芯片,也有称片上系统,意指它是一个产品,是一个有专用目标的集成电路,其中包含完整系统并有嵌入软件的全部内容。同时它又是一种技术,用以实现从确定系统功能开始,到软/硬件划分,并完成设计的整个过程。SoC就是定制功能版本的MCU
百度百科
单片机型号
51单片机(8051)
STC89C51 宏晶科技 STC AT89C51 ATMEL
宏晶科技公司
宏晶科技_百度百科
ATMEL公司
ATMEL公司_百度百科
32单片机
STM32 意法半导体ST GD32 兆易创新GD
32位处理器 - 处理数据宽度是32位的。
处理器位数:CPU单次运算最大处理的数据位数
意法半导体
意法半导体_百度百科
兆易创新
兆易创新科技集团股份有限公司_百度百科
开发板/最小系统板
开发板通常是学习用途,功能比较全,接口丰富,是用于研发、研究、学习的一块板子。
STM32U5开发板介绍
最小系统板是个核心板,集成了核心的通用功能,可以根据需求定制各种不同的底板,通用性较好。再者核心板作为一块独立的模块被分离出来,也降低了开发的难度,增加了系统的稳定性和可维护性通常用于做项目,也可以作为模块在产品里在直接用。
STM32
简介
https://www.st.com.cn/zh/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus.html
STM32 | 产品 | STM32 | MCU单片机 | 意法半导体STM | STMCU中文官网
STM32是意法半导体公司生成一款32位的微控制器。
STM32功能强大、性能优异、片上资源丰富、功耗低、是一款经典的嵌入式微控制器。
命名规范
ST | 意法半导体 |
M | 微控制器 |
32 | 32位处理器 |
类型 | F 通用/基础型 foundation G 多用途型 general-purpose L 低功耗 low power H 高性能 High performance S 简单/标准型 Standard U超低功耗 |
系列 | 0 精简系列 1/2/3 增强系列 4/7 高性能系列 |
子型号 | 00/01/02/03/05/07 |
引脚数量 | K/6-32脚 C/8-48脚 R-64脚 V-100脚 Z-144脚 A-168脚 I-176脚 B-208脚 N-216脚 |
存储量 | 6 : 32KB 8 : 64KB B :128KB C :256KB D : 384KB E : 512KB G : 1MB I : 2MB |
封装 | U - UQFN封装 T - TQFP封装 |
工作温度 | 6 - -40 ~ 85度 |
STM32的优势
STM32 | 产品 | STM32 | MCU单片机 | 意法半导体STM | STMCU中文官网
产品型号丰富,可选择性强;
运算速度快,功耗低;
处理器外设接口丰富;
库函数开发体系学习资料多,应用广泛。
ARM体系结构
STM32G030采用ARM Cortex-M0+内核架构
STM32U575采用ARM Cortex-M33内核架构
M33内核详情:
https://www.st.com.cn/content/st_com/zh/arm-32-bit-microcontrollers/arm-cortex-m33.html
想了解其他架构请点击下方链接
冯·诺依曼架构&哈佛架构(嵌入式学习)_冯诺依曼架构-CSDN博客
认识ARM
- ARM代表一个公司
安谋国际科技股份有限公司_百度百科
ARM是一家公司,ARM公司是一家芯片知识产权(IP)供应商,它与一般的半导体公司最大的不同就是不制造芯片且不向终端用户出售芯片,而是通过转让设计方案,由合作伙伴生产出各具特色的芯片。
- ARM可以表示一些处理器的统称
早期经典处理器:ARM7 ARM9 ARM11
后续处理器开始以cortex命名
Cortex-X系列
超高性能
Cortex-A系列
针对开放式操作系统的高性能处理器
应用于智能手机、数字电视、智能平板等高端运用
Cortex-R系列
提供非常高的性能和吞吐量,同时保持精准的时序属性和可预测的中断延时,通常用于时序关键的应用中
针对实时系统、满足实时性的控制需求
应于汽车制动系统、动力系统等
Cortex-M系列
为单片机驱动的系统提供了低成本优化方案
应用于传统的微控制器市场、智能传感器、汽车周边、物联网设备等
- ARM表示一种指令集
指令:能够指示处理器执行命令称为指令 + - << >>
指令集:处理器能够识别的指令的集合称为指令集
ARM指令集:所有指令(机器码),都专用32bit存储空间,代码灵活,指令简洁,执行ARM指令PC每次自加4
Thumb指令集:所有指令(机器码),都专用16bit存储空间,代码灵活,指令简洁,执行ARM指令PC每次自加2
ARM的命名有指令集架构、 处理器架构、 处理器型号三类命名规则
架构:
arm-v4,arm-v5,arm-v6,arm-v7(32Bits),arm-v8(64Bits)
架构指支持的汇编指令集(不同架构,汇编指令集不同)
问:目前主流处理器架构?
ARM架构、Intel X86/X64架构、MIPS架构、RISC-V(开源)
指令集(RISC和CISC)
精简指令集(RISC)-->微处理器
只保留常用的的简单指令,硬件结构简单,复杂操作一般通过简单指令的组合实现,一般指令长度固定,且多为单周期指令。
RISC处理器在功耗、体积、价格等方面有很大优势,所以在嵌入式移动终端领域应用极为广泛
举例:如有加法运算器 ,没有乘法运算器 3*3 ---》3+3+3
复杂指令集(CISC)-->电脑CPU
不仅包含了常用指令,还包含了很多不常用的特殊指令,硬件结构复杂,指令条数较多,一般指令长度和周期都不固定
CISC处理器在性能上有很大优势,多用于PC及服务器等领域
Cortex-M33的寄存器
(1)通用寄存器
R0-R12:13个通用寄存器。其中 R0-R7为低端寄存器,可作为16位或32 位指令操作数,R8-R12为高端寄存器,只能用作32位操作数
R13:栈指针寄存器 SP(the stark pointer),它用于访问堆栈内存(例如,堆栈PUSH或POP操作)。
R14:链接寄存器LR(the link register),用于存储子程序或者函数调用的返回地址
R15:程序计数器PC(the program counter register)存储下一条将要执行的指令的地址。
(2)特殊寄存器
xPSR:组合程序状态寄存器,该寄存器由三个程序状态寄存器组成
应用程序状态寄存器 (APSR):保存程序计算结果的状态标志 N负数标志 Z零标志 C进位借位标志 V溢出标志
中断程序状态寄存器 (IPSR):包含当前ISR(中断服务程序)的异常编号
执行程序状态寄存器 (EPSR):包含Thumb状态位
CONTROL:控制寄存器
控制处理器处于线程模式时,使用哪个堆栈
=0,使用MSP 处理器模式时,固定使用MSP
=1,使用PSP
CPU运行原理
根据下载的程序运行,程序是指令的有序集合
一条指令(机器码)的执行通常分为三个阶段:
1)取指:控制器将PC寄存器中的值发送给内存,内存将对应地址中的指令(机器码)传送回CPU的指令寄存器IR中
2)译码:指令译码器对IR中的指令进行识别,将指令(机器码)解析(翻译)成具体的运算操作(+/-/*...)
3)执行:控制器控制运算器中对应的运算单元进行运算,运算结果写入寄存器
注意:PC每取地址一次,自加一次。PC的值自动增加使PC指向内存中的下一条指令
思考:
1.运算器不同,处理指令不同。不同的处理器上如何运行同一个c语言程序?
- 假设指令集有乘法指令,结果并没有乘法运算器,怎么办?
指令流水线
指令的执行是按照流水线
取指--》取指器 根据PC值取指令
译码--》译码器
执行--》执行器
以上三个器件,都是单周期的器件,三个器件的工作是独立
指令1 指令2 指令3 指令4 指令5
1 取指
2 译码 取指
3 执行 译码 取指
4 执行 译码 取指
5 执行 译码 取指
6 执行 译码
7 执行
PC永远指向当前取指指令的地址,一旦取到指令,pc后移4byte,保存下一条指令地址。
指令流水线机制的引入确实能够大大的提升指令执行的速度,但在实际执行程序的过程中很多情况下流水线时是无法形成的,比如芯片刚上电的前两个周期、执行跳转指令后的两个周期等。
所以指令流水线的引入以及优化只能使平均指令周期不断的接近1而不可能真正的达到1,且流水线级数越多芯片设计的复杂,程度就越高,芯片的功耗就越高。
编译原理
gcc编译流程分为四个步骤:
1:预编译处理:主要是进行宏替换和拷贝包含的头文件到本文件
2:编译:检查代码的规范性,是否有语法错误等,没错的话将代码编译成汇编语言
3:汇编:将汇编文件转换成二进制目标文件
4:链接:链接库函数生成可执行文件
机器码(二进制)是处理器能直接识别的语言,不同的机器码代表不同的运算指令,处理器能够识别哪些机器码是由处理器的硬件设计所决定的,不同的处理器机器码不同,所以机器码不可移植
汇编语言是机器码的符号化,即汇编就是用一个符号来代替一条机器码,所以不同的处理器汇编也不一样,即汇编语言也不可移植
C语言在编译时我们可以使用不同的编译器将C源码编译成不同架构处理器的汇编,所以C语言可以移植
ARM的数据类型
char(字节):8位
halfword(半字):16位
word(全字):32位
doubleword:64位(cortex-a)
quadword:128位(ARM-v8)
ARM-v7架构:32bit处理器
ARM-v8架构:64bit处理器
处理器的32位和64位什么含义?
32位:一条指令可以进行32位数据的运算
64位:一条指令可以进行64位数据的运算
字节序
大端对齐
低地址存到高地址,高地址存放到低地址
小端对齐
低地址存到低地址,高地址存放到高地址
注:ARM一般使用的是小端对齐
ARMv8-M的指令集
ARM处理器支持两种指令集:ARM 和 Thumb。
ARM指令集 32位精简指令集; 指令长度固定;
降低编码数量产生的耗费,减轻解码和流水线的负担;
Thumb指令集指令宽度16位;
Thumb指令集是ARM指令集的一个子集;
与32位指令集相比,大大节省了系统的存储空间;(密度高)
Thumb指令集不完整,所以必须配合ARM指令集一同使用。
•Arm Cortex-M处理器中使用的指令集称为Thumb指令集。这个指令集包含一系列扩展。Cortex-M33的指令集是Cortex-M23处理器指令集的超集。为了便于项目迁移,以前的Cortex-M处理器中可用的所有指令在Armv8-M架构中也可用。一般来说,Cortex-M处理器中的指令集提供了向上兼容的特性。例如:Cortex-M23的指令集是Cortex-M0/M0+处理器中指令集的超集。
•Cortex-M33的指令集是Cortex-M3和Cortex-M4处理器指令集的超集。除了双精度浮点指令和缓存预加载指令外,Cortex-M7处理器支持的所有指令都可以在Cortex-M33中使用。(注:Cortex-M33没有双精度FPU选项或缓存存储器控制器功能。)向上兼容性是Cortex-M处理器家族的一个重要特征,因为它提供了软件的可重用性和可移植性。Armv8-M基线指令集中使用的许多指令的大小都是16位。这使得高代码密度成为可能。对于一般的数据处理和控制任务,程序代码可以主要由16位指令(而不是32位)组成,以减少程序内存的大小。
问:Thumb指令集和ARM指令集的区别?
系统架构
系统主要由以下几个模块组成 :
● 二个主模块 :
– Cortex-M0+ 内核及先进高性能总线 (AHB bus)
– 通用 DMA (通用的直接存储器存取)
● 三个从模块 :
– 内部 FLASH
– 内部SRAM
– AHB和AHB到APB的连接桥,所有的外设都挂在APB总线上
问:flash和SRAM的区别?
Flash存储器是一种非易失性存储器,可以在掉电之后保存数据,通常用于存储程序代码。Flash存储器的可写入次数有限,且需要执行擦除操作才能写入新的数据,因此,在使用过程中需要注意擦写周期和数据备份问题。
SRAM存储器则是一种易失性存储器,具有相对较快的读写速度和无限的读写次数,但掉电时将会丢失所有内容。SRAM存储器主要用于暂存数据和临时变量,读写操作由CPU直接完成,访问速度较快。
单片机的Flash存储器和SRAM存储器通常都嵌入在单片机芯片内部,能够方便地实现对程序和数据的读写操作。通常,编译器会将程序代码烧录到Flash存储器中,并使用SRAM存储器来存储变量、函数堆栈和其他临时数据。
问:什么是外设?如何理解片上外设(片上资源)?
与传统的外设不同,片上外设通常具有以下优点:
高效性:片上外设能够与主处理器实现高速的数据传输,响应时间短,执行效率高。
集成度高:片上外设多个模块都嵌入到处理器芯片内部,极大地降低了PCB面积和电路复杂度。
低功耗:处理器和片上外设采用相同的工艺,能够满足高密度和低功耗的需求。
可靠性高:提高了整体系统的可靠性和稳定性,也降低了电磁干扰的可能。
问:AHB和APB的区别?
AHB(高级高性能总线)是高速总线,是一种系统总线,它主要负责连接处理器、DMA等一些内部接口。AHB系统由主模块、从模块和基础结构3部分组成,整个AHB总线上的传输都由主模块发出,由从模块负责回应。
APB(高级外设总线)是低速总线,它主要负责连接外围设备,它又分为APB1和APB2,它的总线架构不像 AHB支持多个主模块,在APB里面唯一的主模块就是APB桥。
如何开发
开发环境搭建
STM32CubeMX
ST公司出品 工具链接
工具链接 https://www.st.com/zh/development-tools/stm32cubemx.html
STM32CubeMX是一种图形工具,通过分步过程可以非常轻松地配置STM32微控制器和微处理器,以及为Arm® Cortex®-M内核或面向Arm® Cortex®-A内核的特定Linux®设备树生成相应的初始化C代码。
作用及功能:
(1)工程项目搭建和配置
(2)直观选择微控制器
(3)图形化引脚功能配置、引脚冲突提示
(4)动态配置时钟树
(5)动态设置参数和初始化
Keil uVision5
Keil Product Downloads
Keil μVision 5 也称MDK-ARM、Realview MDK
MDK ——》Microcontroller Development Kit
MDK包含以下几个部分:
μVision5:一种集成开发环境,提供了多种不同的功能,如编辑器、编译器、调试器等。
ARM编译器:一种嵌入式ARM C / C++编译器,可在多种不同的微控制器平台上运行。
Device Family Pack:一种特定于属于不同微控制器平台/系列/型号的软件包,包括库文件、设备描述文件等。
Debugger:一款高级调试器,支持多种不同的调试功能,如单步调试、断点调试、内存映射等。
STM32环境获取及搭建
具体安装步骤见以下文件
STM32环境搭建
软件介绍
【Keil5教程及技巧】耗时一周精心整理万字全网最全Keil5(MDK-ARM)功能详细介绍【建议收藏-细细品尝】-CSDN博客
汇编语言
c语言中哪些代码可以生成汇编指令?
1》带#号预处理,辅助编译器怎么编译,编译什么内容
预处理器是C语言编译器的一个组成部分,它在编译代码之前对代码进行处理。预处理器指令以#号开头,告诉编译器在编译代码之前执行一些操作。其中,#include指令用于将头文件包含到源代码中,#define指令用于定义宏。预处理器的主要作用是辅助编译器编译代码。 例如在编译时将头文件中的函数声明插入到源代码中,或者将宏替换为实际的值。预处理器处理完代码后,编译器将生成目标代码,最终生成可执行文件。
2》带;号的语句,可以编译生成指令
在编译器中,分号是语句结束的标志,编译器会将分号之前的语句编译成指令并添加到指令序列中。
汇编整体分类
1》指令:编译完生成一条机器码存储在内存单元当中,CPU执行时能完成对应的操作(类似于C中的语句)
2》伪操作(相当于c中的#的内容,告诉编译器怎么编译):不会生成机器码也不会占用内存,其作用是告诉编译器怎样编译(类似于C中的预处理指令)
3》伪指令:不是指令,编译器在编译时将其替换成等效的指令 (如:cpu中没有乘法器,对应没有乘法指令,3*3 ---》用加法器实现3+3+3,替换实现)
汇编中注释代码用@或;注释一行 ,/* */注释一段代码
指令分类
1.数据处理指令: 对数据进行逻辑、算数运算
2.跳转指令: 实现程序的跳转,实质是修改PC
3.Load/Store指令: 对内存的读写操作
4.状态寄存器传送指令: 对状态寄存器进行读写操作
5.异常中断产生指令: 触发软中断,常用于内核的系统调用 //SWI:软中断
6.协处理器指令: 操作协处理器的指令
//如3*3 ---》用加法器实现3+3+3,比较慢。我们可以外接一个协处理器(乘法器)(每个协处理器的功能比较单一),协处理器指令就是操作这个协处理器的,用的比较多的cp15协处理器。
程序编写
AREA STACK, NOINIT, READWRITE
__initial_spAREA RESET, DATA, READONLY
__Vectors DCD __initial_sp DCD main AREA |.text|, CODE, READONLYENTRY
mainloopB loop END
解释:
1. AREA STACK, NOINIT, READWRITE: 这一行指定了一个名为STACK的内存区域,它用于存储堆栈。NOINIT表示这个内存区域在程序启动时不需要初始化,READWRITE表示这个内存区域可以被读取和写入。
2. __initial_sp: 这一行定义了一个名为`__initial_sp`的符号,它表示堆栈指针的初始值。在这里,它被定义为堆栈的起始地址。通常,这个符号会在链接脚本中进一步定义为实际的堆栈内存区域的起始地址。
3. AREA RESET, DATA, READONLY: 这一行指定了一个名为RESET的内存区域,用于存储重置向量表。DATA表示这个区域包含数据,READONLY表示这个区域只能被读取。
4. __Vectors DCD __initial_sp: 这一行定义了一个重置向量表,用于指示程序启动时应该执行的操作。`DCD`表示存储一个双字(32位)的数据。在这里,第一个双字存储的是堆栈指针的初始值,即__initial_sp。
5. DCD main: 这一行将程序的入口地址(main函数)添加到重置向量表中。这意味着程序在启动时将跳转到main函数开始执行。
6. AREA |.text|, CODE, READONLY: 这一行指定了一个名为.text的内存区域,用于存储代码。CODE表示这个区域包含代码,READONLY表示这个区域只能被读取。
7. ENTRY main: 这一行指定了程序的入口点为main函数。这意味着程序将从`main`函数开始执行。
8. loop B loop: 这一行是一个无限循环,它会不断地跳转到`loop`标签所在的位置,导致程序永远循环执行这条指令。
9. END: 这一行表示程序的结束。
数据搬移指令
MOV R0,#1 ;MOV搬移指令 相当于R0=1
MOV R1,R0 ; R1=R0
AREA STACK, NOINIT, READWRITE
__initial_spAREA RESET, DATA, READONLY
__Vectors DCD __initial_sp DCD main AREA |.text|, CODE, READONLYENTRY
mainMOV R0,#1MOV R1,R0
loopB loop END
验证
注意:需要连接上LINK,记得先装驱动
如果是立即数,前边必须加#
什么是立即数?
立即数的概念
立即数(Immediate Value)是在计算机编程和汇编语言中常见的一种操作数类型。它是指在指令中直接编码的数值,而不是存储在内存或寄存器中的值。立即数通常是常量或者由程序员明确指定的值,可以直接参与到算术运算、逻辑运算或者数据处理中,无需从其他地方读取。
寻址方式:
寻址方式_百度百科
立即数是保存在指令中的数,取指令的同时将值取过去,和普通变量的区别是,变量保存在内存中的数据,需要单独取值运算。
立即数的本质:立即数是包含在指令当中的数据(即属于指令的一部分)
立即数的优点:读取指令的同时也将立即数读取到了内存中,速度快
立即数的缺点:数量有限
注:使用mov 给寄存器里面存放值的时候,#号后面需是有效数(1:立即数,2:取反之后是立即数),如果不是立即数需要用ldr指令进行存放。
LDR R0,=0X12345678
算术运算指令
MOV R0,#1
MOV R1,#2
ADD R2,R1,R0;加法---->R2=R1+R0;
SUB R2,R1,R0;减法---->R2=R1-R0;
MUL R2,R1,R0;乘法---->R2=R1*R0;
逻辑运算指令
MOV R0,#1
MOV R1,#2
MOV R2,#3
AND R3,R1,R0 ;与---->R3=R1&R0
ORR R3,R1,R0 ;或---->R3=R1|R0
EOR R3,R1,R0 ;异或---->R3=R1^R0
LSL R3,R2,R1 ;左移---->R3=R2<<R1
LSR R3,R2,R1 ;右移---->R3=R2>>R1
xPSR状态寄存器
N (Negative) - 负标志:如果最近的算术操作的结果是负数,此位被置位。
Z (Zero) - 零标志:如果最近的算术或逻辑操作的结果是零,此位被置位。
C (Carry) - 进位标志:如果最近的加法或乘法操作产生了进位,或者减法操作产生了借位,此位被置位。
V (Overflow) - 溢出标志:如果最近的有符号整数运算产生了溢出,此位被置位。
Q (Saturation) - 饱和标志:如果一个饱和运算发生了饱和,此位被置位(仅在支持饱和运算的指令集架构中有效)。
GE (Greater Equal) - 大于等于标志:这是四个位(GE[3:0]),用于比较两个操作数,分别对应无符号和有符号的比较结果。
除了这些条件码标志,APSR还包含一些控制位,如:
I (Interrupt Disable) - 中断禁止标志:如果被置位,硬件中断被屏蔽。
F (Fast Interrupt Disable) - 快速中断禁止标志:如果被置位,快速中断(FIQ)被屏蔽。
T (Thumb) - Thumb标志:如果被置位,处理器处于Thumb状态;否则,它处于ARM状态。
MOV R0,#1 ;指令
MOV R1,#2 ;指令
;默认情况下数据运算不会对条件位(NZCV)产生影响,我们可以在指令后添加后缀'S'
SUBS R2,R0,R1 ;加S并使用减法指令产生负数,验证N位,发现被置位
;测试Z和减法C位
MOV R0,#1 ;指令
MOV R1,#1 ;指令
SUBS R2,R0,R1 ;加S并使用减法指令产生0,验证Z位,发现Z和C都被置1,因为减法时产生借位C会被置0,结果0没有借位
;测试加法C位
MOV R0,#0XFFFFFFFE ;0XFFFFFFFE不是立即数,但是编译没有报错,看一下仿真里编译窗口里,MOV被替换为MVN了,数也变了
MOV R1,#3
ADDS R2,R1,R0 ;加法指令产生了进位(注意这里是32位),C位被置1
;验证V
LDR R0,=0X7FFFFFFE ;0X7FFFFFFE加了3之后产生溢出
MOV R1,#3 ;0X7FFFFFFE加了3之后产生溢出
ADDS R2,R1,R0 ;加法指令产生了进位(注意这里是32位),V位被置1
分支/跳转指令
B (Branch):这是一个基本的无条件跳转指令,用于将程序计数器(PC)设置为指令中指定的地址,从而跳转到程序的其他部分执行。语法:B <label>,其中<label>是跳转的目标标签。
BL (Branch with Link):这个指令不仅跳转到指定的地址,还将当前指令的下一个指令的地址(即返回地址)保存到链接寄存器(LR,通常是R14)中。这允许在跳转后通过返回指令(如MOV PC, LR)返回到跳转前的位置。语法:BL <label>。
不保存返回地址
jump
LDR R3,=0X11111111
LDR R2,=0X22222222
LDR R1,=0X33333333
LDR R0,=0X44444444
main
LDR R0,=0X11111111
LDR R1,=0X22222222
LDR R2,=0X33333333
LDR R3,=0X44444444
LDR R4,=0X08000008
B jump
保存返回地址
jump
LDR R3,=0X11111111
LDR R2,=0X22222222
LDR R1,=0X33333333
LDR R0,=0X44444444
MOV PC,LR
main
LDR R0,=0X11111111
LDR R1,=0X22222222
LDR R2,=0X33333333
LDR R3,=0X44444444
LDR R4,=0X08000008
BL jump
LDR R0,=0X11111111
LDR R1,=0X22222222
LDR R2,=0X33333333
LDR R3,=0X44444444
load/store指令
单寄存器操作指令 ldr / str
对内存的读写操作,将运算结果从cpu写到内存
LDR R1,=0XFF00FF00
LDR R2,=0X20000000
STR R1,[R2] ;把R1当中的数存到R2的地址中
LDR R3,[R2] ;把内存R2地址中的数据读取到CPU R3寄存器中
索引形式
1> 前索引
MOV R1,#0XFFFFFFFF
MOV R2,#0X20000000
STR R1,[R2,#8] ;基址加变址寻址
讲原理加法器 R2加8,如果STR R1,[R2] 也走加法器 R2+0
所以可以根据汇编的语法格式反思CPU的硬件设计
比如 int a[10] 编译器只知道a的首地址,其他的没统计,如a[6] 找地址可以a
2>后索引
MOV R1,#0XFFFFFFFF
MOV R2,#0X20000000
STR R1,[R2],#4 ; 将R1寄存器的内容存到【R2】地址,然后R2=R2+4
这样做的目的可以做连续存储,压栈时用的比较多 存完一个数,他就把地址自动指向下一个了
3>自动索引(前后索引)
MOV R1,#0XFFFFFFFF
MOV R2,#0X20000000
STR R1,[R2,#4]! ; 将R1寄存器的内容存到【R2+4】地址,然后R2=R2+4
LDR同样支持三种索引方式
批量寄存器操作指令ldm/stm
将r1到r4中的值存储到r0指向地址空间中,连续16个字节的地址空间
stm r0, {r1-r4}
LDR R1,=0X1LDR R2,=0X2LDR R3,=0X3LDR R4,=0X4LDR R0,=0X20000000STM R0!,{R1-R4}
LDR R1,=0X1LDR R2,=0X2LDR R3,=0X3LDR R4,=0X4LDR R0,=0X20000000STM R0!,{R1-R3,R4}
LDR R1,=0X1LDR R2,=0X2LDR R3,=0X3LDR R4,=0X4LDR R0,=0X20000000STM R0!,{R1,R3,R2,R4}
栈的操作指令 stmfd / ldmfd
栈的种类
空栈(Empty)
栈指针指向的地址是空的,在栈中存储数据时,可以直接存储,存储完成之后需要将栈指针再次指向空的位置。
满栈(Full)
栈指针指向的地址有数据,在栈中存储数据时,需要先将栈指针,指向一个空的位置,然后在存储数据。
增栈(Ascending)
栈指针向高地址方向移动
减栈(Descending)
栈指针向低地址方向移动
操作栈的方式
满增栈,满减栈,空增栈,空减栈
FA:Full Ascending 满增
FD:Full Descending 满减
EA:Empty Ascending 空增
ED:Empty Descending 空减
ARM默认采用的是满减栈
stmfd/ldmfd<code> sp!, {寄存器列表}
stmfd sp!, {r1-r4}(写) (压栈)
ldmfd sp!, {r0-r3}(读) (出栈)
LDR R1,=0X11111111
LDR R2,=0X22222222
LDR R3,=0X33333333
LDR R4,=0X44444444
ADD SP,SP,#0X100 ;将栈指针地址增加,默认是0X20000000
STMFD SP!,{R1-R4} ;压栈
LDMFD SP!,{R0-R3} ;出栈
程序中运用
stmfd sp!, {r1-r4,lr}(写) (压栈)
ldmfd sp!, {r1-r4,pc}(读) (出栈) //r1-r4出栈给r1-r4, 将lr的值出栈给pc
MY_ADD
STMFD SP!,{R1-R4,LR} ;压栈
LDR R1,=6
LDR R2,=8
ADD R5,R1,R2
LDMFD SP!,{R1-R4,PC} ;出栈
main
LDR R1,=0X11111111
LDR R2,=0X22222222
LDR R3,=0X33333333
LDR R4,=0X44444444
ADD SP,SP,#0X100 ;将栈指针地址增加,默认是0X20000000
BL MY_ADD
ADD R5,R1,R2
push/pop指令
JUMP
PUSH {R1-R4,LR} ;压栈
LDR R1,=0X11111111
POP{R0-R3,PC} ;出栈main
LDR R1,=0X11111111
LDR R2,=0X22222222
LDR R3,=0X33333333
LDR R4,=0X44444444
ADD SP,SP,#0X100 ;将栈指针地址增加,默认是0X20000000
BL JUMP
-栈的应用-》叶子函数的调用过程
叶子函数是指一个函数内部没有调用其他函数的函数,也就是说,它是程序调用树的末端节点,不依赖于其他函数。
F
PUSH {R1,R2,LR} ;压栈
MOVS R1,#5
MOVS R2,#4
ADDS R3,R1,R2
POP{R1,R2,PC} ;出栈main
ADD SP,SP,#0X100
MOVS R1,#3
MOVS R2,#2
BL F
ADDS R3,R1,R2
T
B T
-栈的应用-》非叶子函数的调用过程
非叶子函数是指一个函数内部调用了其他函数的函数,也就是说,它不是程序调用树的末端节点,可以被其他函数调用。
F
PUSH {R1,R2,LR} ;压栈
MOVS R1,#5
MOVS R2,#4
BL D
ADDS R3,R1,R2
POP{R1,R2,PC} ;出栈
D
PUSH {R1,R2,LR} ;压栈
MOVS R1,#7
MOVS R2,#6
ADDS R3,R1,R2
POP{R1,R2,PC} ;出栈
main
ADD SP,SP,#0X100
MOVS R1,#3
MOVS R2,#2
BL F
ADDS R3,R1,R2
T
B T
专用寄存器操作指令(了解)
ADD SP,SP,#0X100
MOVS R1,#3
MOVS R2,#2
MRS R3,PSR ;读PSR的内容
LDR R4,=0XF0123456
MSR PSR,R4 ;向PSR写内容
MRS R3,PSR
异常中断产生指令(了解)
不讲,因为咱们用不到 一般用到的人写内核的
CPU执行完这个指令后产生一个软中断
协处理器指令(了解)
操作协处理器的指令(一般用不到-----协助cpu处理数据)
1.数据运算
2.内存访问
3.与主处理器通信
MRC 将协处理器中寄存器的内容读取到ARM处理器的寄存器中
MCR 将ARM理器中寄存器的内容读取到协处理器的寄存器中
协处理器指令
- 协处理器数据运算指令
CDP
- 协处理器储存器访问指令
STC 将协处理器中的数据储存到存储器
LDC 将存储器中的数据读取到协处理器中
- 协处理器寄存器传送指令
MRC 将协处理器中寄存器的数据传送到ARM处理器中的寄存器
MCR 将ARM处理器寄存器中的数据读取到协处理器寄存器中
伪指令
本质:本身不是指令,但是cpu替换成等效的操作。
举例1:
延时一个指令周期(耗时一条指令的时间) (cpu没有这个指令)
NOP ;执行NOP和MOV R0,R0一个效果,执行NOP,cpu替换成MOV R0,R0
MOV R0,R0
举例2:
LDR的两种形式
;->指令
LDR R1,[R2]
;->伪指令
LDR R1,=0x12345678 ;R1 = 0x12345678
;可以将任何一个32bit的数据放入寄存器
伪操作
指令是arm公司规定的,而伪操作是编译器规定的,不同的编译器伪操作指令不同。
(后期我们学的linux,用linux的编译器)
相关文章:
MCU、ARM体系结构,单片机基础,单片机操作
计算机基础 计算机的组成 输入设备、输出设备、存储器、运算器、控制器 输入设备:将其他信号转换为计算机可以识别的信号(电信号)。输出设备:将电信号(0、1)转为人或其他设备能理解的…...
黑马点评项目测试总结
黑马点评项目测试面经总结: 一,怎么使用使用Postman进行接口测试? 1,安装Postman 2. 创建请求: 打开Postman,点击"New"按钮创建一个新的请求。在弹出的窗口中,选择请求的类型&#x…...
YOLOv8-ultralytics-8.2.103部分代码阅读笔记-loaders.py
loaders.py ultralytics\data\loaders.py 目录 loaders.py 1.所需的库和模块 2.class SourceTypes: 3.class LoadStreams: 4.class LoadScreenshots: 5.class LoadImagesAndVideos: 6.class LoadPilAndNumpy: 7.class LoadTensor: 8.def autocast_list(source…...
Ubuntu Linux 图形界面工具管理磁盘分区和文件系统(八)
本文为Ubuntu Linux操作系统- 第八弹~~ 今天接着上文的内容,讲Linux磁盘分区存储的相关知识~ 上期回顾:命令行-管理磁盘分区和文件系统 今天看酷酷的雪獒铠甲!!雪獒铠甲合体~ 文章目录 磁盘管理器GNOME Disks主要功能安装命令 磁盘…...
Windows系统修改文件的默认打开方式的3种方式
文章目录 1.右键打开方式2.属性3.设置-按文件类型打开 1.右键打开方式 2.属性 3.设置-按文件类型打开 word文档 excel表格...
2023 年“泰迪杯”数据分析技能赛B 题企业财务数据分析与造假识别
2023 年“泰迪杯”数据分析技能赛B 题企业财务数据分析与造假识别 一、背景 财务数据是指企业经营活动和财务结果的数据记录,反映了企业的财务状况 与经营成果。对行业、企业的财务数据进行分析,就是要评价其过去的经营业绩、 衡量现在的财务状况、预测…...
数据分析系列---requests的使用
🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 主环境和虚拟环境 主环境是电脑上安装的python环境 虚拟环境在项目中可以实现环境的隔离,假设DemoA和DemoB分别用到了某个三方库1.0和2.0版本,那么在一个…...
sql删除冗余数据
工作或面试中经常能遇见一种场景题:删除冗余的数据,以下是举例介绍相应的解决办法。 举例: 表结构: 解法1:子查询 获取相同数据中id更小的数据项,再将id不属于其中的数据删除。-- 注意:mysql中…...
ElementUI 问题清单
1、form 下面只有一个 input 时回车键刷新页面 原因是触发了表单默认的提交行为,给el-form 加上submit.native.prevent就行了。 <el-form inline submit.native.prevent><el-form-item label"订单号"><el-inputv-model"query.order…...
uniapp 微信小程序webview 和 h5数据通信
项目是uniapp编写,因为是先开发了h5和app,小程序是突然要用的,做兼容开发已经来不及,由于微信小程序webview载入h5 因为通信必须要特殊限制(网页向小程序 postMessage 时,会在以下特定时机触发并收到消息&a…...
3D 生成重建021-LRM基于大模型的生成式3D生成模型
3D 生成重建021-LRM基于大模型的生成式3D生成模型 文章目录 0 论文工作1 论文方法2 实验结果 0 论文工作 论文提出了一种名为大型重建模型 (LRM) 的新型模型,该模型可在短短 5 秒内根据单张输入图像预测物体的 3D 模型。与许多先前仅在 ShapeNet 等小型数据集上进行…...
12.6深度学习_模型优化和迁移_整体流程梳理
七、整体流程梳理 1. 引入使用的包 用到什么包,临时引入就可以,不用太担心。 import time import osimport numpy as np import pandas as pd import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvisio…...
CCF-GESP 编程能力认证 C++ 七级 2024年9月份判断题详细解析
链接:CCF-GESP 编程能力认证 C 七级 2024年9月份选择题详细解析-CSDN博客 目录 第 1 题 第 2 题 第 3 题 第 4 题 第 5 题 第 6 题 第 7 题 第 8 题 第 9 题 第 10 题 第 1 题 表达式 a << 1 的结果为 a(错误) 【a是字符常…...
ESP32-S3模组上跑通ES8388(20)
接前一篇文章:ESP32-S3模组上跑通ES8388(19) 二、利用ESP-ADF操作ES8388 2. 详细解析 上一回解析完了es8388_init函数中的第7段代码,本回继续往下解析。为了便于理解和回顾,再次贴出es8388_init函数源码,在components\audio_hal\driver\es8388\es8388.c中,如下: …...
UE5.5 Geometry库平面切割原理分析
平面切割--FMeshPlaneCut 平面定义: 面上一个点 法线 算法流程如下 求几何体所有顶点和面的有向距离(Signs) Sign计算: float Sign (VertexPos - PlaneOrigin).Dot(PlaneNormal); 遍历所有几何体所有交叉边, 进行SplitEdge 对于位于切割面两侧的交叉边(Sign…...
JAVAWeb中的Servlet学习
一 Servlet简介 1.1动态资源和静态资源 静态资源 无需在程序运行时通过代码运行生成的资源,在程序运行之前就写好的资源.例如:html css js img ,音频文件和视频文件 动态资源 需要在程序运行时通过代码运行生成的资源,在程序运行之前无法确定的数据,运行时动态生成,例如Servle…...
【Linux】多线程
目录 线程 线程和进程的关系 虚拟地址与物理地址的映射(三级映射) 编辑 线程的使用 线程安全 临界资源和临界区 互斥锁 同步与互斥 互斥锁的使用 锁的初始化 加锁与解锁 信号量 信号与信号量的区别 信号量的使用 Lock_guard与unique_lock …...
如何使用Python库连接Redis
1、redis-py 库封装一个 Redis 工具类可以帮助我们简化 Redis 的操作并提高代码的复用性和可维护性。 安装redis pip install redisimport redis import logginglogging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__)class RedisUtils:def __init__(s…...
mybatis一对多的查询怎么查?
1.问题描述 我有一个班级,班级里有很多学生,我需要一个查询把班级和学生信息查出来,怎么查? 这里有个问题,就是我班级的命名和学生的命名可能重了。 例如: class Gradle{ private String id; private …...
[C++]友元函数和友元类
1. 友元函数 1.1 友元函数的概念 友元函数是一个非成员函数,它被类声明为“友元”,从而能够访问类的私有成员和保护成员。正常情况下,类的外部函数是不能访问类的私有成员的,而友元函数打破了这一限制。 class MyClass { priva…...
实战:MyBatis适配多种数据库:MySQL、Oracle、PostGresql等
概叙 很多时候,一套代码要适配多种数据库,主流的三种库:MySQL、Oracle、PostGresql,刚好mybatis支持这种扩展,如下图所示,在一个“namespace”,判断唯一的标志是iddatabaseId,刚好写…...
2024年天津市职业院校技能大赛高职组 “信息安全管理与评估”样题第三阶段
(四)第三阶段竞小组(赛项)目(300分) 第三阶段竞赛内容是:网络安全渗透(夺旗挑战赛CTF) 本模块要求参赛者作为攻击方,运用所学的信息收集、漏洞发现、漏洞利用等渗透测试技…...
游戏引擎学习第36天
仓库 :https://gitee.com/mrxiao_com/2d_game 回顾之前的内容 在这个程序中,目标是通过手动编写代码来从头开始制作一个完整的游戏。整个过程不使用任何库或现成的游戏引擎,这样做的目的是为了能够全面了解游戏执行的每一个细节。开发过程中࿰…...
数仓技术hive与oracle对比(一)
准备 包括软硬件环境、数据、测试数据三方面的准备内容。 环境 虚拟机软件virtualbox7,同样的虚拟机配置:内存2G、cpu一核,物理主机同一台macbookpro(13-2020款),所以硬盘IO读写速度一致。 综上&#x…...
LeetCode题集-5 - 最长回文子串(一)
题目:给你一个字符串 s,找到 s 中最长的回文子串。 这一题作为中等难度,常规解法对于大多数人应该都没有难度。但是其中也有超难的解决办法,下面我们就一起由易到难,循序渐进地来解这道题。 01、暴力破解法 对于大多…...
A3026 Java+jsp+servlet+mysql高校学生请假管理系统
高校学生请假管理系统 1.摘要2. 绪论3.功能结构4.界面展示5.源码获取 1.摘要 高校学生请假管理系统 摘要:随着计算机的发展与不断进步,各个领域都出现了新的技术,曾经各种规模之间的竞争已经发展成为技术之间的竞争,管理和人才之…...
LDO低压差线性稳压器
1. 简介 LDO 是 “Low Dropout Regulator” 的缩写,中文称为“低压差线性稳压器”。LDO 稳压器是一种用于电压调节的电子设备,它的主要特点是输出电压和输入电压之间的压差非常低。这种特性使得 LDO 在许多应用场景中非常有用,特别是在需要高…...
Angular由一个bug说起之十一:排序之后无法展开 Row
问题现象 在使用 Material Table 时,排序功能触发了一个奇怪的 Bug:表格的 Row 无法展开。最终排查发现,问题的根源在于 trackBy 的错误使用。trackBy 方法接受两个参数:index(数据索引)和 row(…...
wlanapi.dll丢失怎么办?有没有什么靠谱的修复wlanapi.dll方法
在遇到各种系统文件错误当中,其中之一就是“wlanapi.dll文件丢失”的问题。这种问题通常发生在Windows操作系统上,特别是当系统试图执行与无线网络相关的任务时。wlanapi.dll是一个重要的系统文件,它负责处理Windows无线网络服务的许多功能。…...
redis安装和使用教程【保姆级】
1.下载 通过网盘分享的文件:redis 链接: https://pan.baidu.com/s/1Tu1KZkf33YJFdul8s6SzqQ?pwd8888 提取码: 8888 2.启动 进入根目录,使用redis-server redis.windows.conf命令启行启动Redis服务, 如下图所示为启动成功,默认…...
Github 2024-12-01 开源项目月报 Top20
根据Github Trendings的统计,本月(2024-12-01统计)共有20个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目10TypeScript项目9Go项目2HTML项目1Shell项目1Jupyter Notebook项目1屏幕截图转代码应用 创建周期:114 天开发语言:TypeScript, Py…...
C总结(C语言知识点,深化重难点)
C语言 1.使用C语言的7个步骤2.ASCII码3.提高程序可读性的机巧4.如何使用多种整形5.打印多种整形6.课移植类型:stdint.h和inttypes.h7.浮点数常量8.浮点值的上溢和下溢9.使用数据类型11.常量和C预处理器12.转换说明的意义12.1转换不匹配13.副作用和序列点14.数组简介…...
[Collection与数据结构] 位图与布隆过滤器
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...
Redis与缓存
目录 缓存 缓存优缺点 缓存更新策略 超时剔除 先删缓存再更新数据库 旁路缓存(先更新数据库,再删缓存) 先更新数据库,再更新缓存 读写穿透 编辑 异步缓存写入模式 缓存常见问题 缓存穿透 缓存雪崩 缓存击穿 缓存 在业务开发…...
Ubuntu Linux 文件、目录权限问题(五)
本文为Ubuntu Linux操作系统- 第五弹 此文是在上期文件目录的内容操作基础上接着讲权限问题 上期回顾:Ubuntu Linux 目录和文件的内容操作 文件访问者身份与文件访问权限 Linux文件结构 所有者(属主)所属组(属组)其他…...
AI 名人堂:Jeff Dean
Jeff Dean,谷歌的高级研究员和人工智能领域的领军人物,以其在大规模分布式计算系统和人工智能系统的杰出贡献而闻名。 谷歌AI掌门人 TensorFlow项目负责人 美国工程院院士 2AGI.NET AI 名人堂 AI 名人堂:Jeff DeanAI 名人堂:Je…...
基础排序算法详解:冒泡排序、选择排序与插入排序
引言 上一章,我们聊到了排序的基本概念和常见算法的分类。这一次,我们从基础开始,深入剖析三种常见的O(n) 排序算法:冒泡排序、选择排序 和 插入排序。 它们是学习排序算法的入门神器,不仅实现简单,还能帮…...
Flink如何基于数据版本使用最新离线数据
业务场景 假设批量有一张商户表,表字段中有商户名称和商户分类两个字段。 批量需要将最新的商户名称和分类的映射关系推到hbase供实时使用。 原实现方案 a.原方案内容 为解决批量晚批问题,批量推送hbase表时一份数据产生两类rowkey:T-1和…...
什么是反向代理?作用、原理和实例详解
🚀 什么是反向代理?作用、原理和实例详解 在现代的网络架构中,反向代理(Reverse Proxy)无处不在。无论是负载均衡、加速缓存,还是WebSocket 支持,反向代理都是必不可少的工具。 这篇文章将带您…...
国产GPU中,VLLM0.5.0发布Qwen2.5-14B-Instruct-GPTQ-Int8模型,请求返回结果乱码
概述 国产GPU: DCU Z100 推理框架: vllm0.5.0 docker容器化部署 运行如下代码: python -m vllm.entrypoints.openai.api_server --model /app/models/Qwen2.5-14B-Instruct-GPTQ-Int8 --served-model-name qwen-gptq --trust-remote-code --enforce…...
Stable Diffusion本地部署:从零开始的完整指南
1、引言 Stable Diffusion是计算机视觉领域的一个生成式大模型,能够进行文生图(txt2img)和图生图(img2img)等图像生成任务。它利用深度学习技术,特别是RealisticVision v2.0模型,能够创造出接近…...
隐式神经网络实现低光照图像增强
✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…...
Flutter动画(三)内建显式动画Widget
常见的内建显式动画Widget: ListenableBuilder: AnimatedBuilder AnimatedWidget AlignTransition DecoratedBoxTransition DefaultTextStyleTransition PositionedTransition RelativePositionedTransition RotationTransition ScaleTransiti…...
springSecurity自定义登陆接口和JWT认证过滤器
下面我会根据该流程图去自定义接口: 我们需要做的任务有: 登陆:1、通过ProviderManager的方法进行认证,生成jwt;2、把用户信息存入redis;3、自定义UserDetailsService实现到数据库查询数据的方法。 校验&a…...
Spring Boot日志:从Logger到@Slf4j的探秘
写在前面 Hello大家好,今日是2024年的第一天,祝大家元旦快乐?? 2024第一篇文章从SpringBoot日志开始 文章目录 一、前言二、日志有什么用?三、日志怎么用?四、自定义日志打印 ?? 常见日志框架说明4.1 在程序中得到?志对象【…...
使用 LabVIEW 与 PLC 通信的方式
要将 PLC 与 LabVIEW 或其他 NI 产品进行通信,首先需要明确 PLC 支持的通信协议和接口类型。NI 提供了多种方案,包括 OPC 服务器、Modbus、Ethernet/IP 和其他工业通信协议。下面将详细介绍这些方法,并进行比较分析,帮助你选择最适…...
python录制鼠标键盘操作循环播放
依赖 pip install pynput 程序: from pynput import mouse, keyboard import time import threading# 用于存储录制的鼠标和键盘事件 mouse_events [] keyboard_events []# 定义事件处理函数# 处理鼠标事件 def on_move(x, y):mouse_events.append((move, x, y))def on_cl…...
开发者如何使用GCC提升开发效率Opencv操作
看此篇前请先阅读 https://blog.csdn.net/qq_20330595/article/details/144134160?spm=1001.2014.3001.5502 https://blog.csdn.net/qq_20330595/article/details/144134160?spm=1001.2014.3001.5502 https://blog.csdn.net/qq_20330595/article/details/144216351?spm=1001…...
异常与文件
目录 1.异常 1.1.概念 1.2.常见异常 1.3.异常处理方式 1.3.1.try except 1.3.2.try except else 1.3.3.try except else finally 2.文件 2.1.文件分类 ps:python 程序的数据保存在哪里? 2.2.常见的文件类型 2.3.python 操作文件的函数 2.3.1.读取文件…...
【C语言】完成程序设计填空
文章目录 1、请阅读下面的程序,在空白处填写正确的代码,要求各在一行从头开始输出m和n的值。2、求100~599之间的所有水仙花数,即各位数字的立方和恰好等于该数本身的数。3、以下程序的功能是:将值为三位正整数的变量x中的数值按照个位、十位、百位的顺序 拆分并输出。请填空…...