【STM32】SPI通信外设硬件SPI读写W25Q64

【STM32】SPI通信协议&W25Q64Flash存储器芯片(学习笔记)-CSDN博客 

SPI通信外设

SPI外设简介

  • STM32内部集成了硬件SPI收发电路,可以由硬件自动执行时钟生成、数据收发等功能,减轻CPU的负担
  • 可配置8位/16位数据帧、高位先行/低位先行(标黑常用)
  • 时钟频率: fPCLK / (2, 4, 8, 16, 32, 64, 128, 256),就是SCK,一般体现的是传输速度,单位为Hz或者bit/s,最大进行2分频,72M/2=36MHz,I2C最大400kHz,SPI最大频率比I2C大90倍,SPI1时钟频率比SPI2大一倍
  • 支持多主机模型、主或从操作
  • 可精简为半双工/单工通信
  • 支持DMA,DMA自动帮我们搬运数据
  • 兼容I2S协议,数字音频信号传输的专用协议
  • STM32F103C8T6 硬件SPI资源:SPI1(APB2的外设)、SPI2(APB1的外设)

兼容I2S协议: 应用场景

 三条主要总线

STM32F103C8T6 有三条主要总线,分别是 AHB(高级高性能总线)、APB1(高级外设总线 1)和 APB2(高级外设总线 2),各总线频率如下:

  • AHB 总线:其最高频率为 72MHz,通常系统时钟(SYSCLK)会直接作为 AHB 总线的时钟。
  • APB1 总线:它的最高频率是 36MHz,APB1 总线挂载着一些低速外设,如 UART2 - UART5、SPI2、SPI3、I2C1、I2C2 等。
  • APB2 总线:最高频率为 72MHz,APB2 总线挂载着高速外设,像 GPIO 端口、USART1、SPI1 等。

 SPI框图

1. 引脚部分

  • MOSI(Master Out Slave In):主设备输出,从设备输入引脚。在 SPI 通信中,主设备通过此引脚向从设备发送数据。
  • MISO(Master In Slave Out):主设备输入,从设备输出引脚。从设备通过此引脚向主设备发送数据。
  • SCK(Serial Clock):串行时钟引脚,由主设备产生,用于同步主设备和从设备之间的数据传输。
  • NSS(Slave Select):从设备选择引脚,主设备通过拉低此引脚电平来选中对应的从设备。

2. 数据传输相关模块

  • 发送缓冲区:用于暂存要发送的数据,数据由软件写入,然后发送到移位寄存器。
  • 接收缓冲区:用于暂存接收到的数据,数据从移位寄存器读出后存储在此,等待软件读取。
  • 移位寄存器:是 SPI 数据传输的核心部件。在发送数据时,它从发送缓冲区获取数据,按照时钟信号一位一位地通过 MOSI 引脚发送出去;在接收数据时,通过 MISO 引脚一位一位地接收数据,然后将完整的数据存入接收缓冲区。“LSBFIRST 控制位” 决定数据是低位(LSB) 在前还是高位(MSB) 在前进行传输。

3. 控制寄存器部分

  • SPI_CR1:控制寄存器 1,包含多个控制位:
    • LSBFIRST:控制数据传输时是低位在前还是高位在前。
    • SPE(SPI Enable):使能 SPI 外设。
    • BR[2:0]:波特率控制位,用于设置 SPI 的时钟频率,即波特率。
    • MSTR(Master Select):主从模式选择位,设置该 SPI 设备为主设备还是从设备。
    • CPOL(Clock Polarity):时钟极性控制位,决定 SCK 时钟信号的空闲状态电平(高电平或低电平)。
    • CPHA(Clock Phase):时钟相位控制位,用于选择 SPI 的两种不同时钟相位模式。
    • 还有其他如 CRC 相关控制位、双线双向模式控制位等,用于设置 SPI 的各种工作模式和特性。
  • SPI_CR2:控制寄存器 2,包含以下控制位:
    • TXEIE(Transmit Buffer Empty Interrupt Enable):发送缓冲区空中断使能位。
    • RXNEIE(Receive Buffer Not Empty Interrupt Enable):接收缓冲区非空中断使能位。
    • ERRIE(Error Interrupt Enable):错误中断使能位。
    • SSOE(Slave Select Output Enable):从设备选择输出使能位。
    • TXDMAEN(Transmit DMA Enable):发送直接内存访问(DMA)使能位。
    • RXDMAEN(Receive DMA Enable):接收 DMA 使能位。
  • SPI_SR:状态寄存器,包含多个状态标志位:
    • BSY(Busy):忙标志位,当 SPI 正在进行数据传输时,该位被置 1。
    • OVR(Overrun):溢出标志位,当接收缓冲区已满,又有新的数据到来时,该位被置 1。
    • MODF(Mode Fault):模式错误标志位,当 SPI 在主模式下 NSS 引脚被意外拉低时,该位被置 1。
    • CRCERR(CRC Error):CRC 校验错误标志位。
    • TXE(Transmit Buffer Empty):发送缓冲区空标志位。
    • RXNE(Receive Buffer Not Empty):接收缓冲区非空标志位。
  • 波特率发生器:根据 SPI_CR1 中 BR [2:0] 的设置,产生相应频率的时钟信号 SCK,以控制数据传输的速率。
  • 主控制电路:负责协调 SPI 各个模块的工作,根据控制寄存器的设置来管理数据的发送和接收过程。
  • 通信电路:在 SPI 通信过程中,处理数据的收发以及与其他模块的交互,确保通信的正常进行。

大致分为两部分,左上角就是数据寄存器和移位寄存器配合部分;和串口、I2C的设计思路具有异曲同工之妙,主要为了实现数据流传输,右下角部分就是控制逻辑了;下面来看看框图细节:

首先,左上角核心部分,就是移位寄存器,右边的数据从低位,一位一位的从MOSI移出,然后MSO,一位一位的移入左边的数据高位,显然移位寄存器是一个右移的状态,所以目前图上表示的是低位先行的配置,对应右下角有一个LSBFLRST控制位,这一位可以控制是低位先行还是高位先行,可以查一下数据手册

目前框图的LSBFIRST状态应该是1,低位先行,如果LSBFIRST给0的话,就是高位先行,这个框图还要变动一下,就移位寄存器变为左移,输出从左边一出去,输入,从右边移进来。然后就是两个缓冲区,这两个缓冲区实际上就是数据寄存器DR,下面发送缓冲区就是发送数据寄存器TDR,上面接收缓冲区就是接收数据寄存器RDR,和串口那里一样,TDR和RDR占用同一个地址,统一叫做DR;

连续发送数据流过程:在主设备中,将要发送的数据写入发送缓冲区(TDR)。当移位寄存器没有数据移位时,TDR的数据就会转入至移位寄存器进行移位,当发送缓冲区中的数据发送完成后,SPI 状态寄存器(SPI_SR)中的 TXE(发送缓冲区空)标志位置 1。然后移位寄存器工作

移位寄存器工作:发送缓冲区的数据会在 SCK 时钟信号的驱动下,一位一位地移入移位寄存器,然后通过 MOSI 引脚发送到从设备。同时,从设备在 SCK 时钟的同步下,通过 MISO 引脚将数据发送回主设备(如果是双向通信)。

数据接收与存储:在主设备接收数据时,从设备发送的数据在 SCK 时钟信号的同步下,通过 MISO 引脚一位一位地移入主设备的移位寄存器,然后再存入接收缓冲区。当接收缓冲区中有数据时,SPI_SR 中的 RXNE(接收缓冲区非空)标志位置 1。

数据读取软件可以通过查询 RXNE 标志位或者利用接收缓冲区非空中断,从接收缓冲区(SPI_DR)中读取接收到的数据。如果是连续接收数据,需要及时处理已接收的数据,以便接收新的数据,保证接收过程的连续性。

数据传输设计思路SPI和I2C和串口的区别:设计思路区别

 框图中的“波特率发生器”有什么作用?

1. 定义与基本功能

波特率发生器是一种用于生成特定频率时钟信号的电路模块。在 SPI(Serial Peripheral Interface,串行外设接口)通信中,它的主要功能是产生串行时钟信号 SCK(Serial Clock)。SCK 信号用于同步主设备和从设备之间的数据传输,确保数据能够按照预定的速率和时序准确地发送和接收。

2. 波特率的设置与控制

  • 控制位设置:波特率发生器的工作受 SPI 控制寄存器(如 SPI_CR1 中的 BR [2:0] 位)的控制。通过对这些控制位进行编程设置,可以改变波特率发生器的输出时钟频率。例如,在 STM32 的 SPI 模块中,BR [2:0] 位有不同的组合,对应不同的分频系数。
  • 具体示例:当 BR [2:0] 设置为不同的值时,波特率发生器会将系统时钟(通常是 AHB 总线时钟)按照相应的分频系数进行分频,从而得到不同频率的 SCK 时钟信号。如果系统时钟频率为 72MHz,当 BR [2:0] 设置为 “110” 时,对应的分频系数为 128,那么此时 SCK 的频率就是 72MHz / 128,约为 562.5kHz。

3. 对通信的影响

  • 数据传输速率:波特率发生器生成的 SCK 时钟频率决定了 SPI 通信的数据传输速率。较高的 SCK 频率意味着数据可以在更短的时间内传输完成,从而提高通信效率。但同时,过高的频率可能会受到传输线的电气特性、设备的处理能力等因素的限制,导致数据传输错误。
  • 设备兼容性:不同的 SPI 设备可能对 SCK 时钟频率有不同的要求。波特率发生器可以根据与之通信的从设备的特性,灵活地调整 SCK 时钟频率,以确保主设备和从设备之间能够正常通信。例如,一些低速的 SPI 从设备可能无法处理过高频率的时钟信号,此时就需要通过波特率发生器降低 SCK 的频率。

4. 与其他模块的协同工作

波特率发生器产生的 SCK 时钟信号与 SPI 的其他模块协同工作。在数据发送过程中,发送缓冲区的数据会在 SCK 时钟信号的驱动下,一位一位地通过 MOSI 引脚发送出去;在数据接收过程中,MISO 引脚上的数据会在 SCK 时钟信号的同步下,一位一位地被移入移位寄存器。同时,波特率发生器的工作也受到主控制电路的管理和协调,以确保整个 SPI 通信过程的稳定和准确。

 NSS任何实现多主机切换功能?NSS多主机切换

 SPI基本结构 

主模式全双工连续传输  

1. 时钟与数据传输

  • SCK(时钟信号):由主设备产生,为数据传输提供同步时钟,确保主从设备数据收发时序一致。
  • 数据发送(MOSI 输出):主设备通过 MOSI 依次发送数据0xF10xF20xF3,每个数据按位(b0~b7)在 SCK 驱动下传输。
  • 数据接收(MISO 输入):主设备通过 MISO 接收从设备返回的数据0xA10xA20xA3,同样按位同步接收。

2. 关键标志位变化

  • TXE(发送缓冲区空标志)
    • 硬件自动置位:当发送缓冲区数据发送到移位寄存器后,TXE 被硬件置 1,表示发送缓冲区空闲。
    • 软件清除:需通过软件向SPI_DR写入新数据来清除该标志(如写入0xF1后,TXE 置 1,再写入0xF2即清除)。
  • RXNE(接收缓冲区非空标志)
    • 硬件自动置位:当接收缓冲区收到完整数据(如0xA1)后,RXNE 被硬件置 1。
    • 软件清除:通过软件读取SPI_DR数据来清除该标志(如读取0xA1后,RXNE 标志清除)。
  • BSY(忙标志)
    • 硬件自动置位:SPI 开始数据传输时,BSY 置 1,表示外设处于忙状态。
    • 硬件自动清除:所有数据传输完成后,BSY 由硬件自动清零。

3. 软件操作流程

  • 发送数据:软件先写入第一个数据(如0xF1SPI_DR),等待 TXE=1(发送缓冲区空),再写入下一个数据(如0xF2),循环直至数据发送完毕。
  • 接收数据:软件等待 RXNE=1(接收缓冲区有数据),然后从SPI_DR读取数据(如读取0xA1),完成一次接收操作,循环处理后续数据。

4. 整体时序逻辑

  • 发送缓冲区、接收缓冲区与标志位TXERXNE配合,确保数据连续发送和接收。BSY标志则全程反映 SPI 外设的工作状态,直到所有数据传输结束才恢复空闲状态。通过这种机制,SPI 实现了主模式全双工连续数据传输的高效控制。

非连续传输  

这张图展示了 STM32 SPI 外设工作在 非连续传输发送模式BIDIMODE=0 且 RXONLY=0)时,TXE(发送缓冲区空标志)和 BSY(忙标志)的变化过程,具体解析如下:

1. 基础配置与信号

  • 时钟配置:图中示例配置 CPOL=1(时钟空闲状态为高电平)、CPHA=1(数据在时钟第二个边沿采样),定义了 SPI 通信的时钟极性和相位。
  • SCK(时钟信号):由主设备生成,为数据传输提供时序同步,驱动 MOSI 引脚按位发送数据。
  • MOSI(输出):主设备通过 MOSI 依次发送数据 0xF10xF20xF3,每个数据按 b0~b7 位在 SCK 时钟下逐位传输。

2. 关键标志位变化

  • TXE(发送缓冲区空标志)
    • 当发送缓冲区数据转移到移位寄存器后,硬件自动将 TXE 置 1,表示缓冲区空闲。
    • 软件需通过向 SPI_DR 写入新数据来清除该标志(如写入 0xF1 后,TXE 置 1,写入 0xF2 时清除)。
  • BSY(忙标志)
    • 硬件控制:SPI 开始数据传输时,BSY 置 1,表示外设处于忙状态;所有传输结束后,BSY 自动清零。

3. 非连续传输的软件操作特点

  • 数据写入延迟:与连续传输不同,非连续传输中软件写入数据存在延迟。例如:
    • 先写入 0xF1 到 SPI_DR,启动第一次传输。
    • 等待 TXE=1 后,较晚写入 0xF2;再次等待 TXE=1 后,又较晚写入 0xF3
  • 结束等待:最后需等待 BSY=0,确认所有非连续的传输操作完全结束,SPI 外设回归空闲状态。

4. 整体时序逻辑

图中体现了非连续传输的 “间隔性”:每次数据发送依赖软件主动写入新数据触发,且两次传输之间存在等待 TXE 标志的间隔。BSY 标志全程反映 SPI 工作状态,仅在数据传输过程中保持为 1,其余时间(如等待软件写入新数据阶段)可能短暂清零,直到所有传输完成最终清零。

非连续传输在SCK频率低时无影响;

在SCK频率高时有缺点:不同SCK频率不同间隙的示波器波形

 最后看手册很重要:坚持到最后都牛逼

 硬件SPI读写W25Q64

 本节代码在软件SPI读写W25Q64芯片基础上做修改,代码参考软件SPI读写W25Q64芯片:【江协科技STM32】软件SPI读写W25Q64芯片(学习笔记)-CSDN博客

接线图

因为这里是硬件读写SPI,涉及STM32内部硬件外设的引脚,都要查询引脚定义表

引脚定义表 

引脚复用: 

  硬件SPI

 硬件SPI代码实际上就两部分:

1、SPI外设初始化代码

Ⅰ卡其时钟,开启SPI和GPIO的时钟

Ⅱ 初始化GPIO口,其中,SCK和MOSI是由硬件外设控制的输出信号,所以配置为复用推挽输出;

MISO是由硬件外设控制的输入信号,所以配置为上拉或者浮空输入。

Ⅲ 配置SPI外设,初始化SPI

Ⅳ 使能SPI

void HerSPI_Init(void)
{/*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);	//开启SPI1的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA4引脚初始化为推挽输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA5和PA7引脚初始化为复用推挽输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA6引脚初始化为上拉输入/*SPI初始化*/SPI_InitTypeDef SPI_InitStructure;						//定义结构体变量SPI_InitStructure.SPI_Mode = SPI_Mode_Master;			//模式,选择为SPI主模式SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;	//方向,选择2线全双工SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		//数据宽度,选择为8位SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;		//先行位,选择高位先行SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;	//波特率分频,选择128分频SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;				//SPI极性,选择低极性SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;			//SPI相位,选择第一个时钟边沿采样,极性和相位决定选择SPI模式0SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;				//NSS,选择由软件控制SPI_InitStructure.SPI_CRCPolynomial = 7;				//CRC多项式,暂时用不到,给默认值7SPI_Init(SPI1, &SPI_InitStructure);						//将结构体变量交给SPI_Init,配置SPI1/*SPI使能*/SPI_Cmd(SPI1, ENABLE);									//使能SPI1,开始运行/*设置默认电平*/HerSPI_W_SS(1);											//SS默认高电平
}

2、SPI外设操作时序,完成交换应该字节的流程 

①等待TXE为1,等待发送寄存器位空,发送寄存器不为空就不着急写

②写入数据到发送数据寄存器,开始产生时序

③//等待RXNE 接收数据寄存器非空

④ 读取接收到的数据并返回

uint8_t MySPI_SwapByte(uint8_t ByteSend)
{while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);	//等待发送数据寄存器空SPI_I2S_SendData(SPI1, ByteSend);								//写入数据到发送数据寄存器,开始产生时序while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);	//等待RXNE 接收数据寄存器非空return SPI_I2S_ReceiveData(SPI1);								//读取接收到的数据并返回
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二叉树之树的高以及遍历

二叉树的高其实很简单就一句话: 从根节点到叶节点的最长路径中的边数就是二叉树的高 int FindHeight(Btree root){int leftheight;int rightheight;if(rootNULL){return -1;}else{leftheightFindHeight(root->left );rightheightFindHeight(root->right );}r…

DeepSeek技术架构解析:MoE混合专家模型

一、前言 2025年初,DeepSeek V3以557万美元的研发成本(仅为GPT-4的1/14)和开源模型第一的排名,在全球AI领域掀起波澜。其核心创新之一——混合专家模型(Mixture of Experts, MoE)的优化设计,不…

VMware主机换到高配电脑,高版本系统的问题

原来主机是i3 ,windows7系统,vmware 14.0,虚机系统是ubuntu 14.04。目标新机是i7 14700KF,windows11系统。原以为安装虚拟机,将磁盘文件,虚拟机配置文件拷贝过去可以直接用。 新目标主机先安装了vmware 15,运行原理虚机&#xff0…

数字化转型驱动卫生用品安全革新

当315晚会上晃动的暗访镜头揭露卫生巾生产车间里漂浮的异物、纸尿裤原料仓中霉变的碎屑时,这一触目惊心的场景无情地撕开了“贴身安全”的遮羞布,暴露的不仅是部分企业的道德缺失,更凸显了当前检测与监管体系的漏洞,为整个行业敲响…

VideoHelper 油猴脚本,重塑你的视频观看体验

VideoHelper 油猴脚本,重塑你的视频观看体验 在日常上网看视频时,你是否也被这些问题困扰:视频网站开头的广告又臭又长,找个合适的播放倍速要在一堆选项里翻半天,每次手动调音量、点全屏按钮繁琐又影响沉浸感&#xf…

(C语言)习题练习 sizeof 和 strlen

sizeof 上习题,不知道大家发现与上一张的习题在哪里不一样嘛? int main() {char arr[] "abcdef";printf("%zd\n", sizeof(arr));printf("%zd\n", sizeof(arr 0));printf("%zd\n", sizeof(*arr));printf(&…

Java多线程与高并发专题——使用 Future 有哪些注意点?Future 产生新的线程了吗?

Future 的注意点 1. 当 for 循环批量获取 Future 的结果时容易 block,get 方法调用时应使用 timeout 限制 对于 Future 而言,第一个注意点就是,当 for 循环批量获取 Future 的结果时容易 block,在调用 get方法时,应该…

STM32基础教程——PWM驱动LED呼吸灯

目录 前言 技术实现 原理图 接线图 代码实现 内容要点 PWM基本结构 开启外设时钟 配置GPIO端口 配置时基单元 初始化输出比较单元 输出PWM波形 输出比较通道重映射 前言 PWM(Pulse Width Modulation):一种通过调节脉冲信号的占空比(高电平持续时间与整…

算法基础——栈

一、栈的概念 栈是⼀种只允许在⼀端进⾏数据插⼊和删除操作的线性表。 进⾏数据插⼊或删除的⼀端称为栈顶,另⼀端称为栈底。不含元素的栈称为空栈。进栈就是往栈中放⼊元素,出栈就是将元素弹出栈顶。 二、栈的模拟实现 1. 创建 本质还是线性表&#…

JVM类文件结构详解

文章目录 前言代码示例1.魔数2.版本3.常量池4.访问标识与继承信息访问标识继承信息 5.Field 信息6 Method 信息构造方法分析(method-main)main方法分析(method-main) 7.附加属性 前言 在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文…

5.安全相关(双手启动、安全触边传感器)

一、关于双手启动按钮的使用规范 本文介绍双手启动按钮的使用。概括来讲: 双手按下之间的时间差间隔应该在0.5-2秒之间。一旦释放任何一个按钮,启动信号输出结束。只有两个按钮都被释放之后,才能再次触发双手启动信号。如果某按钮被按下超过…

电脑上不了网普通用户排除方法

1:首先通过电脑的运行/CMD/ipconfig /all 命令查看电脑的ip地址是否正常如图: 2:在命令行中运行:ping 127.0.0.1 如图则正常,否则要重新安装网卡驱动 程序。 3:用ping命令,ping一下同网段的电…

【中文翻译】第3章(1/3)-The Algorithmic Foundations of Differential Privacy

为方便阅读,故将《The Algorithmic Foundations of Differential Privacy》翻译项目内容搬运至此; 教材原文地址:https://www.cis.upenn.edu/~aaroth/Papers/privacybook.pdf 中文翻译版 Github 项目地址1:https://github.com/gu…

2.1词法分析任务

编译器结构 前端 词法分析器的任务 字符流到记号流 eg: 把这些单词就叫做记号 EOF结束符号!

Linux操作系统7- 线程同步与互斥5(POSIX条件变量生产者消费者模型的进一步使用)

上篇文章:Linux操作系统7- 线程同步与互斥4(基于POSIX条件变量的生产者消费者模型)-CSDN博客 本篇代码仓库: 支持处理简单任务的生产者消费者模型代码 生产者-消费者-保存者三线程两队列模型 多生产多消费的生产者消费者模型 进一…

【嵌入式学习2】C语言 - VScode环境搭建

目录 ## 语言分类 ## c语言编译器 ## VScode相关配置 ## 语言分类 编译型语言:C,C解释型语言:python,JS ## c语言编译器 分类GCC 系列MinGWCygwinMSVC系列一套编程语言编译器将GCC编译器和GNU Binutils移植到Win32平台下的产物…

使用Doris broker load导入数据到带Kerberos的HA HDFS的命令详解

以下是关于 Doris Broker Load 结合 Kerberos 认证的 HDFS 数据导入的详细解析: 一、Broker Load 核心原理 Broker Load 是 Doris 中用于从 HDFS/S3 等远程存储系统异步导入大数据的工具,其核心流程如下: 任务提交:用户通过 SQL…

数字化转型 2.0:AI、低代码与智能分析如何重塑企业竞争力?

引言:数字化转型进入2.0时代 在过去的十几年里,企业的数字化转型(1.0)主要围绕信息化和自动化展开,例如引入ERP、CRM等系统,提高办公效率,减少人为失误。然而,随着市场竞争加剧&…

指针,数组 易混题解析(一)

目录 一.相关知识点 1.数组名是什么? 两个例外: 2.strlen 3.sizeof 4. * ( ) 与 [ ] 的互换 二.一维数组 三.字符数组 1. 字符 (1)sizeof (2)strlen 2.字符串 (1)si…

ABC392题解

A 算法标签: 模拟 #include <iostream> #include <algorithm> #include <cstring>using namespace std;int main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int w[3];for (int i 0; i < 3; i) cin >> w[i];sort(w, w 3);if (w[0]…