STM32F103——基础篇

news2024/11/15 8:28:29

目录

1、寄存器基础知识

2、STM32F103系统架构

2.1 Cortex M3 内核&芯片

2.2 STM32F103系统架构

3、存储器映射

4、寄存器映射

4.1 寄存器描述解读

4.2 寄存器映射举例

4.3 寄存器地址计算 

4.4 stm32f103xe.h 寄存器映射


1、寄存器基础知识

概念:寄存器(Register)是单片机内部一种特殊的内存,它可以实现对单片机各个功能的控制。简单的来说可以把寄存器当成一些控制开关,控制包括内核及外设的各种状态。所以无论是51单片机还是 STM32,都需要用寄存器来实现各种控制,以完成不同的功能。

由于寄存器资源非常宝贵,一般都是一个位或者几个位控制一个功能, 对于 STM32 来说,其寄存器是 32 位的,一个 32 位的寄存器,可能会有 32 个控制功能,相当于 32 个开关,由于 STM32 的复杂性,它内部有几百个寄存器,所以整体来说 STM32 的寄存器还是比较复杂的。不过,千万不要被其吓到了,实际上 STM32 是由于内部有很多外设,所以导致寄存器很多,实际上已经把它分好类,每个外设也就那么几个或者几十个寄存器,学起来就不难了。

从大方向来区分,STM32 寄存器分为两类,如下图:

 注意:其中,内核寄存器,我们一般只需要关心中断控制寄存器和 SysTick 寄存器即可,其他三大类,我们一般很少直接接触。而外设寄存器,则是学到哪个外设,就了解哪个外设相关寄存器即可,所以整体来说,需要关心的寄存器并不是很多,而且很多都是有共性的,比如STM32F103ZET6 有 8 个定时器,我们只需要学习了其中一个的相关寄存器,其他 7 个基本都是一样。

经过上面一波了解之后,再给大家举个简单的例子, 我们知道寄存器的本质是一个特殊的内存,对于STM32 来说,以 GPIOB 的 ODR 寄存器为例,其寄存器地址为:0X40010C0C,所以对其赋值可以写成:

(*(unsigned int *))(0X40010C0C) = 0XFFFF;

这样我们就完成了对 GPIOB->ODR 寄存器的赋值,全部 0XFFFF,表示 GPIOB 所有 IO 口(16 个 IO 口)都输出高电平。对于我们来说,0X40010C0C就是一个寄存器的特殊地址。

虽然上面的代码实现了需要的功能,但是从实用的角度来说,这么写肯定是不好的,可读性极差,可维护性也很差,所以一般会使用结构体来访问,比如改写成这样:

GPIOB->ODR = 0XFFFF;

这样可读性就比之前的代码好多了,可维护性也相对好一点。至于 GPIOB 结构体怎么来的,在后续会给大家介绍。

2、STM32F103系统架构

STM32F103 是 ST 公司基于 ARM 授权 Cortex M3 内核而设计的一款芯片,而 Cortex M 内核使用的是 ARM v7-M 架构,是为了替代老旧的单片机而量身定做的一个内核,具有低成本、低功耗、实时性好、中断响应快、处理效率高等特点。

2.1 Cortex M3 内核&芯片

ARM公司提供内核(如Cortex M3,简称CM3,下同)授权,完整的MCU还需要很多其他组件。芯片公司(ST、NXP、TI、GD、华大等)在得到CM3内核授权后,就可以把CM3内核用在自己的硅片设计中,添加:存储器,外设,I/O以及其它功能块。不同厂家设计出的单片机会有不同的配置,包括存储器容量、类型、外设等都各具特色,因此才会有市面上各种不同应用的ARM芯片。Cortex M3内核和芯片的关系如下图:

从上图可以看出,ARM公司提供CM3内核和调试系统,其他的东西(外设(IIC、SPI、UART、TIM等)、存储器(SRAM、FLASH等)、I/O等)由芯片制造商设计开发。这里ST公司就是STM32F103芯片的制造商。

2.2 STM32F103系统架构

STM32F103的系统主要由:四个驱动单元(可以主动发起通信,图中黑色①区域)和四个被动单元(只能被驱动工作,图中黑色②区域)组成。如下图,内部系统结构简图:

总线矩阵为分界线,该分界线的左边的称为主动单元,右边的称为被动单元。四个主动单元分别为红色方框框住的红色字体①②③④;四个被动单元分别为黄色方框框住的黄色字体①②③④;其分类如下表:

 注意:这里的驱动/被动单元都是指连接了总线矩阵的部分,未连接总线矩阵的部分,则不算作驱动/被驱动单元。

接下来我们讲一下这些单元。 

1. I Code总线(I-Bus)

这是Cortex M3内核的指令总线,连接闪存指令接口(如:FLASH),用于获取指令。由于该总线功能单一,并没有直接连接到总线矩阵,因此被排除在驱动单元之外。
2. D Code 总线(D-Bus)
这是Cortex M3内核的数据总线,连接闪存存储器数据接口(如:SRAM、FLASH等),用于各种数据访问,如常量、变量等。
3. 系统总线(S-Bus)
这是Cortex M3内核的系统总线,连接所有外设(如:GPIO、SPI、IIC、TIM等),用于控制各种外设工作,如配置各种外设相关寄存器等。
4. DMA 总线
DMA是直接存储访问控制器,可以实现数据的自动搬运,整个过程不需要CPU处理。如可以实现DMA传输内存数据到DAC,输出任意波形,传输过程不需要CPU参与,可以大大节省CPU支,从而更高效的处理事务。STM32F103ZET6内部有2个DMA控制器,可以实现内存到外设、外设到内存、内存到内存的数据传输。
5. 内部FLASH
内部FLASH即单片机的硬盘,用于代码/数据存储,CPU通过ICode总线经FLASH接口访问内部FLASH,FLASH最高访问速度是24Mhz,因此以72M速度访问时,需要插入2个时钟周期延迟。
6. 内部SRAM
内部SRAM即单片机的内存,用于数据存储,直接挂载在总线矩阵上面,CPU通过D Code总线实现0等待延时访问SRAM,最快总线频率可达72Mhz,从而保证高效高速的访问内存
7. FSMC
FSMC即灵活的静态存储控制器,实际上就是一个外部总线接口,可以用来访问外部SRAM、NAND/NOR FLASH、LCD等。它也是直接挂在总线矩阵上面的,以方便CPU快速访问外挂器件。
8. AHB/APB
AHB总线连接总线矩阵,同时通过2个APB桥连接APB1和APB2,AHB总线速度最大为72Mhz,APB2总线速度最大也是72Mhz,但是APB1总线速度最大只能是36Mhz。这三个总线上面挂载了STM32内部绝大部分外设。
9. 总线矩阵
总线矩阵协调内核系统总线和DMA主控总线之间的访问仲裁,仲裁利用轮换算法,保证各个总线之间的有序访问,从而确保工作正常。

3、存储器映射

STM32是一个32位单片机,他可以很方便的访问4GB以内的存储空间(2^32 = 4GB),因此Cortex M3内核将下图中的所有结构,包括:FLASH、SRAM、外设及相关寄存器等全部组织在同一个4GB的线性地址空间内,我们可以通过C语言来访问这些地址空间,从而操作相关外设(读/写)。数据字节以小端格式(小端模式)存放在存储器中,数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。

存储器本身是没有地址信息的,我们对存储器分配地址的过程就叫存储器映射。这个分配一般由芯片厂商做好了,ST将所有的存储器及外设资源都映射在一个4GB的地址空间上(8个块),从而可以通过访问对应的地址,访问具体的外设。ST将4GB空间分成8个块,每个块512MB,如上图所示,从图中我们可以看出有很多保留区域(Reserved),这是因为一般的芯片制造厂家是不可能把4GB空间用完的,同时,为了方便后续型号升级,会将一些空间预留(Reserved)。映射关系及8个存储块的功能如下表所示:

 这里我们重点挑前面3个存储块介绍。

 第一个块是Block 0,用于存储代码,即FLASH空间;

用户FLASH大小是512KB,这是对于我们使用的STM32F103ZET6来说,如果是其他型号,可能FLASH会更小,当然,如果ST喜欢,也是可以随时推出更大容量的STM32F103单片机的,因为这里保留了一大块地址空间。还有,STM32的出厂固化BootLoader非常精简,整个BootLoder只占了2KB FLASH空间。

第二个块是Block 1,用于存储数据,即SRAM空间。

这 个 块 仅 使 用 了 64KB 大 小 ( 仅 大 容 量 STM32F103 型 号 才 有 这 么 多 SRAM , 比 如STM32F103ZET6等),用于SRAM访问,同时也有大量保留地址用于扩展。

第三个块是Block 2,用于外设访问,STM32内部大部分的外设都是放在这个块里面的,该存储块里面包括了AHB、APB1和APB2三个总线相关的外设,其中AHB和APB2是高速总线(72Mhz max),APB1是低速总线(36M max)。

同样可以看到,各个总线之间,都有预留地址空间,方便后续扩展。关于STM32各个外设具体挂在哪个总线上面,大家可以参考前面的 STM32F103系统结构图 和 STM32F103存储器映射图进行查找对应。 

4、寄存器映射

给存储器分配地址的过程叫存储器映射,寄存器是一类特殊的存储器,它的每个位都有特定的功能,可以实现对外设/功能的控制,给寄存器的地址命名的过程就叫寄存器映射。 

举个简单的例子,大家家里面的纸张就好比通用存储器,用来记录数据是没问题的,但是不会有具体的动作,只能做记录,而你家里面的电灯开关,就好比寄存器了,假设你家有8个灯,就有8个开关(相当于一个8位寄存器),这些开关也可以记录状态,同时还能让电灯点亮/关闭,是会产生具体动作的。为了方便区分和使用,我们会给每个开关命名,比如厨房开关、大厅开关、卧室开关等,给开关命名的过程,就是寄存器映射。

当然STM32内部的寄存器有非常多,远远不止8个开关这么简单,但是原理是差不多的,每个寄存器的每一个位,一般都有特定的作用。

4.1 寄存器描述解读

GPIOODR寄存器为例。

 ① 寄存器名字
每个寄存器都有一个对应的名字,以简单表达其作用,并方便记忆,这里GPIOx_ODR表示寄存器英文名,x可以从A~E,说明有5个这样的寄存器(每个端口有一个,事实上最新的STM32F103型号,可能还有F,G等端口,IO数量更多)。
②寄存器偏移量及复位值
地址偏移量表示相对该外设基地址的偏移,比如GPIOB,通过查询可知其外设基地址是:0x4001 0C00。那么GPIOB_ODR寄存器的地址就是:0x4001 0C0C。知道了外设基地址和地址偏移量,我们就可以知道任何一个寄存器的实际地址。

复位值表示该寄存器在系统复位后的默认值,可以用于分析外设的默认状态。这里全部是0。
③寄存器位表
描述寄存器每一个位的作用(共32bit),这里表示ODR寄存器的第15位(bit),位名字为ODR15,rw表示该寄存器可读写(r,可读取;w,可写入)。
④位功能描述
描述寄存器每个位的功能,这里表示位0~15,对应ODR0~ODR15,每个位控制一个IO口的输出状态。其他寄存器描述,参照以上方法解读接口。

4.2 寄存器映射举例

从前面的学习我们知道 GPIOB_ODR 寄存器的地址为:0x4001 0C0C,假设我们要控制 GPIOB的 16 个 IO 口都输出 1,则可以写成:

*(unsigned int *)(0x40010C0C) = 0XFFFF;

这里我们先要将 0x4001 0C0C 强制转换成 unsigned int 类型指针,然后用*对这个指针的值进行设置,从而完成对 GPIOB_ODR 寄存器的写入。

这样写代码功能是没问题,但是可读性和可维护性都很差,使用起来极其不便,因此我们将代码改为:
#define GPIOB_ODR *(unsigned int *)(0x40010C0C)
GPIOB_ODR = 0XFFFF;

这样,我们就定义了一个 GPIOB_ODR 的宏,来替代数值操作,很明显,GPIOB_ODR 的可读性和可维护性,比直接使用数值操作来的直观和方便。这个宏定义过程就可以称之为寄存器的映射。当然,为了简单,我们只举了一个简单实例,实际上大量寄存器的映射,使用结构体是最方便的方式。

4.3 寄存器地址计算 

STM32F103大部分外设寄存器地址都是在存储块2上面的。具体某个寄存器地址,由三个参数决定:

 1、总线基地址(BUS_BASE_ADDR);

2,外设基于总线基地址的偏移量(PERIPH_OFFSET);

3,寄存器相对外设基地址的偏移量(REG_OFFSET)。

可以表示为:寄存器地址 = BUS_BASE_ADDR(总线基地址)+ PERIPH_OFFSET(外设基于总线基地址的偏移量)+ REG_OFFSET(寄存器相对外设基地址的偏移量);

 总线基地址(BUS_BASE_ADDR),STM32F103内部有三个总线(APB1、APB2和AHB),对应的总线基地址,下表中APB1的基地址,也叫外设基地址,表中的偏移量就是相对于外设基地址的偏移量。如下:

偏移量是怎么偏移得到的那个值呢?

总线APB1基地址相对于自身基地址偏移的偏移量为:0;

总线APB2基地址相对于总线APB1基地址偏移的偏移量为:0x1 0000;

总线AHB基地址相对于总线APB1基地址偏移的偏移量为:0x1 8000;

注意:AHB的总线基地址是0X4001 8000,从该基地址到0X4002 0000,只挂了SDIO一个外设,后续的AHB外设基地址都大于等于0X4002 0000。为了方便计算,我们可以将AHB的总线基地址改成:0X4002 0000,而SDIO则单独定义一个基地址给他即可。

外设基于总线基地址的偏移量(PERIPH_OFFSET),不同外设偏移量不一样,以GPIO为例,GPIO外设基地址及相对总线偏移量如下表所示:

 上表的偏移量,就是外设基于APB2总线基地址的偏移量(PERIPH_OFFSET)。

知道了外设基地址,再查询找到具体某个寄存器相对外设基地址的偏移量就可以知道该寄存器的实际地址了,以GPIOB的相关寄存器为例, GPIOB 寄存器相对外设基地址的偏移量如下表所示:

上表的偏移量,就是寄存器基于外设基地址的偏移量(REG_OFFSET)。

因此,我们根据前面的公式,很容易可以计算出GPIOB_ODR的地址:

GPIOB_ODR地址 = APB2总线基地址 + GPIOB外设偏移量 + 寄存器偏移量

所以得到:GPIOB_ODR 地址 = 0X4001 0000 + 0XC00 + 0X0C = 0X4001 0C0C
举了这个例子之后相信头明白了,其他寄存器的地址大家都应该可以熟练掌握并计算出来。

4.4 stm32f103xe.h 寄存器映射

STM32F103所有寄存器映射都在stm32f103xe.h里面完成,包括各种基地址定义、结构体定义、外设寄存器映射、寄存器位定义(占了绝大部分)等,整个文件有1W多行,非常庞大。我们没有必要对该文件进行全面分析,因为很多内容都是相似的,我们只需要知道寄存器是如何被映射的,就可以了,至于寄存器位定义这些内容,知道是怎么回事就可以了。

我们还是以GPIO为例进行说明,看看stm32f103xe.h是如何对GPIO的寄存器进行映射的,通过对GPIO寄存器映射,了解stm32f103xe.h的映射规则。stm32f103xe.h文件主要包含五个部分内容,如下:

寄存器映射主要涉及到上表中加粗的两个组成部分:外设寄存器结构体类型定义和寄存器映射,总结起来,包括3个步骤:

(1) 外设寄存器结构体类型定义
(2)外设基地址定义
(3)寄存器映射(通过将外设基地址强制转换为外设结构体类型指针即可)

以GPIO为例,其寄存器结构体类型定义如下:

typedef struct
{
 __IO uint32_t CRL; /* GPIO_CRL 寄存器,相对外设基地址偏移量:0X00 */
 __IO uint32_t CRH; /* GPIO_CRH 寄存器,相对外设基地址偏移量:0X04 */
 __IO uint32_t IDR; /* GPIO_IDR 寄存器,相对外设基地址偏移量:0X08 */
 __IO uint32_t ODR; /* GPIO_ODR 寄存器,相对外设基地址偏移量:0X0C */
 __IO uint32_t BSRR; /* GPIO_BSRR 寄存器,相对外设基地址偏移量:0X10 */
 __IO uint32_t BRR; /* GPIO_BRR 寄存器,相对外设基地址偏移量:0X14 */
 __IO uint32_t LCKR; /* GPIO_LCKR 寄存器,相对外设基地址偏移量:0X18 */
} GPIO_TypeDef;

GPIO外设基地址定义如下:

#define PERIPH_BASE 0x40000000UL /* 外设基地址 */

#define APB1PERIPH_BASE PERIPH_BASE /* APB1 总线基地址 */
#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000UL) /* APB2 总线基地址 */
#define AHBPERIPH_BASE (PERIPH_BASE + 0x00020000UL) /* AHB 总线基地址 */

#define GPIOA_BASE (APB2PERIPH_BASE + 0x00000800UL) /* GPIOA 基地址 */
#define GPIOB_BASE (APB2PERIPH_BASE + 0x00000C00UL) /* GPIOB 基地址 */
#define GPIOC_BASE (APB2PERIPH_BASE + 0x00001000UL) /* GPIOC 基地址 */
#define GPIOD_BASE (APB2PERIPH_BASE + 0x00001400UL) /* GPIOD 基地址 */
#define GPIOE_BASE (APB2PERIPH_BASE + 0x00001800UL) /* GPIOE 基地址 */
#define GPIOF_BASE (APB2PERIPH_BASE + 0x00001C00UL) /* GPIOF 基地址 */
#define GPIOG_BASE (APB2PERIPH_BASE + 0x00002000UL) /* GPIOG 基地址 */
GPIO外设寄存器映射定义如下:
#define GPIOA ((GPIO_TypeDef *)GPIOA_BASE) /* GPIOA 寄存器地址映射 */
#define GPIOB ((GPIO_TypeDef *)GPIOB_BASE) /* GPIOB 寄存器地址映射 */
#define GPIOC ((GPIO_TypeDef *)GPIOC_BASE) /* GPIOC 寄存器地址映射 */
#define GPIOD ((GPIO_TypeDef *)GPIOD_BASE) /* GPIOD 寄存器地址映射 */
#define GPIOE ((GPIO_TypeDef *)GPIOE_BASE) /* GPIOE 寄存器地址映射 */
#define GPIOF ((GPIO_TypeDef *)GPIOF_BASE) /* GPIOF 寄存器地址映射 */
#define GPIOG ((GPIO_TypeDef *)GPIOG_BASE) /* GPIOG 寄存器地址映射 */

以上三部分代码,就完成了STM32F103内部GPIOA~GPIOG的寄存器映射,其原理其实是比较简单的,包括两个核心知识点:1,结构体地址自增;2,地址强制转换;

结构体地址自增:我们第一步就定义了GPIO_TypeDef结构体类型,其成员包括:CRL、CRH、IDR、ODR、BSRR、BRR和LCKR,每个成员是uint32_t类型,也就是4个字节,这样假设:CRL地址是0的话,CRH就是0X04,IDR就是0X08,ODR就是0X0C,以此类推。

地址强制转换:以GPIOB为例,GPIOB外设的基地址为:GPIOB_BASE(0X4001 0C00),我们使用GPIO_TypeDef将该地址强制转换为GPIO结构体类型指针:GPIOB,这样GPIOB->CRL的地址就是:GPIOB_BASE(0X4001 0C00),GPIOB->CRH的地址就是:GPIOB_BASE + 0X04(0X4001 0C04),GPIOB->IDR的地址就是:GPIOB_BASE + 0X08(0X4001 0C08),以此类推。

这样我们就使用结构体方式完成了对GPIO寄存器的映射,其他外设的寄存器映射也都是这个方法,这里就不一一介绍了。

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

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

相关文章

【C语言进阶】指针的高级应用(上)

本专栏介绍:免费专栏,并且会持续更新C语言基础知识,欢迎各位订阅关注。 关注我,带你了解更多关于机器人、嵌入式、人工智能等方面的优质文章,坚持更新! 大家的支持才是更新的最强动力! 文章目录…

详解PHP反射API

PHP中的反射API就像Java中的java.lang.reflect包一样。它由一系列可以分析属性、方法和类的内置类组成。它在某些方面和对象函数相似,比如get_class_vars(),但是更加灵活,而且可以提供更多信息。反射API也可与PHP最新的面向对象特性一起工作&…

掌握 JVM 的参数及配置

点击下方关注我,然后右上角点击...“设为星标”,就能第一时间收到更新推送啦~~~ JVM(Java虚拟机)是Java编程语言的核心组件之一,它负责执行Java程序,并提供一系列参数和配置选项,可以调整Java程…

探秘企业DevOps一体化平台建设终极形态丨IDCF

笔者从事为企业提供研发效能改进解决方案相关工作十几年,为国内上百家企业提供过DevOps咨询及解决方案落地解决方案,涉及行业包括:金融、通信、制造、互联网、快销等多种行业。 DevOps的核心是研发效能改进,效能的提升离不开强大…

Linux基本开发工具(一)

文章目录 Linux基本开发工具(一)Linux安装和卸载软件Linux 软件包管理器 yum关于sudo命令关于yum源的换源问题 vim编辑器的使用vim三种模式(常见)vim的基本操作vim配置 Linux基本开发工具(一) Linux安装和…

Dubbo中使用netty

技术主题 netty在Dubbo中的使用,主要集中在网络通信上, 技术原理 Dubbo是什么 高性能、轻量级的开源java的RPC框架,提供三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。 Dubbo的传输结构 1、魔数标识符(四个字节),用于区分不同…

机器人开发--兴颂雷达介绍

机器人开发--兴颂雷达介绍 1 介绍2 使用手册参考 1 介绍 佛山市兴颂机器人科技有限公司(Hinson)是一家集研发、设计、生产、销售机器人(AGV)导航核心零部件、并提供整体运动控制方案的自主创新型国家高新技术企业。 2 使用手册 兴颂激光雷达使…

HDFS中的sequence file

sequence file序列化文件 介绍优缺点格式未压缩格式基于record压缩格式基于block压缩格式 介绍 sequence file是hadoop提供的一种二进制文件存储格式一条数据称之为record&#xff08;记录&#xff09;&#xff0c;底层直接以<key, value>键值对形式序列化到文件中 优…

【flink】开启savepoint

先启动一个任务 flink run -c com.yang.flink.CDCJob test-cdc.jar开启savepoint 命令&#xff1a; flink savepoint JobID 文件地址 flink savepoint e929a11d79bdc5e6f140f2cfb92e1335 file:///workspace/flinkSavepoints/backend这样就开启好了 操作中的错误 详细信…

HTTP——八、确认访问用户身份的认证

HTTP 一、何为认证二、BASIC认证BASIC认证的认证步骤 三、DIGEST认证DIGEST认证的认证步骤 四、SSL客户端认证1、SSL 客户端认证的认证步骤2、SSL 客户端认证采用双因素认证3、SSL 客户端认证必要的费用 五、基于表单认证1、认证多半为基于表单认证2、Session 管理及 Cookie 应…

【ONE·Linux || 基础IO(二)】

总言 文件系统与动静态库相关介绍。 文章目录 总言2、文件系统2.1、背景知识2.2、磁盘管理2.2.1、磁盘文件系统图2.2.2、inode与文件名 2.3、软硬链接 3、动静态库3.1、站在编写库的人的角度&#xff1a;如何写一个库&#xff1f;3.1.1、静态库制作3.1.3、动态库制作 3.2、站在…

初识MySQL数据库之用户管理

目录 一、用户管理 二、用户 1. 用户信息 2. 创建用户 3. 用户登录测试 4. 删除用户 5. 设置用户远端登录 6. 修改密码 6.1 修改当前用户的密码 6.2 root用户修改指定用户的密码 三、权限 1. 数据库中的各个权限含义 2. 给用户授权 3. 查看用户拥有权限 4. 授权…

VSCode---通过ctrl+鼠标滚动改变字体大小

打开设置然后在右边输editor.mouseWheelZoo勾选即可实现鼠标滚动改变字体大小 4.这种设置的字体大小是固定的

Wordpress升级版本后插件和主题常见出错及处理方法整理【持续更新】

Wordpress报错怎么解决&#xff1f; 一般常用的排查方法&#xff1a; 暂时禁用所有插件&#xff1b;将主题更改为默认主题&#xff1b; 修改wp-config.php文件&#xff1b;更新固定链接设置&#xff0c;确保设置正确&#xff1b;检查.htaccess文件是否存在且是否可写&#xf…

IL汇编实现两数相加输出结果

话说前面没有实现IL汇编2数相加&#xff1b;鼓捣了一下&#xff0c;实现的代码如下&#xff1b; .assembly extern mscorlib {}.assembly Test{.ver 1:0:1:0}.module test.exe.method static void main() cil managed{.maxstack 8.entrypoint.locals init (int32 V_0, int3…

数据集成、类的派生树、算子、软件核化。

数据集成、类的派生树、算子、软件核化TOC 数据集成&#xff1a;数据集成首先需要对数据进行分类、组织、排序&#xff0c;然后按照一定的规则合成、展示数据&#xff08;可以是生成式网页数据&#xff09;。对于元宇宙、大数据、大模型、基于搜索的计算、数据集成都是提高效率…

SpringBoot中Redis报错:NOAUTH Authentication required

1、问题 org.springframework.dao.InvalidDataAccessApiUsageException: NOAUTH Authentication required.; nested exception is redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required. … 2、解决 如果提供了密码还没解决&#xff0c;那可能是…

2021-06-16 Multisim74LS161S设计13进制计数器!

缘由求&#xff01;74LS161S设计13进制计数器&#xff01;-其他-CSDN问答

从URL取值传给后端

从URL传值给后端 http://127.0.0.1:8080/blog_content.html?id8点击浏览文章详情&#xff0c;跳转至详情页面 从 url 中拿出文章 id&#xff0c;传给后端 首先拿到url然后判断是否有值&#xff0c;从问号后面取值params.split(&) 以 & 作为分割然后遍历字符数组 param…

SQL分类及通用语法数据类型(超详细版)

一、SQL分类 DDL: 数据定义语言&#xff0c;用来定义数据库对象&#xff08;数据库、表、字段&#xff09;DML: 数据操作语言&#xff0c;用来对数据库表中的数据进行增删改DQL: 数据查询语言&#xff0c;用来查询数据库中表的记录DCL: 数据控制语言&#xff0c;用来创建数据库…