26、江科大stm32视频学习笔记——I2C读写W25Q64

news2024/9/23 9:24:00

一、W25Q64简介

1、W25Q64的内存空间结构:  一页256字节,4K(4096 字节)为一个扇区,16个扇区为1块,容量为8M字节,共有128个块,2048 个扇区。  

2、W25Q64每页大小由256字节组成,每页的256字节用一次页编程指令即可完成。

3、擦除指令分别支持: 16页(1个扇区)、128页、256页、全片擦除。 

二、电路图

1、软件模拟的SPI:线可以任意接

2、硬件模拟的SPI:要按以下方式连接

3、本次软件模拟和硬件模拟使用同一个电路图,方便切换

CS(片选):PA4                                   DO(从机输出):PA6

CLK(时钟):PA5                                 DI(从机输入):PA7

三、软件SPI读写W25Q64

1、SPI.c(初始化寄存器,实现读取一个字节的功能)

#include "stm32f10x.h"                  // Device header

void MySPI_W_SS(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}

void MySPI_W_SCK(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)BitValue);
}

void MySPI_W_MOSI(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_7, (BitAction)BitValue);
}

uint8_t MySPI_R_MISO(void)
{
	return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6);
}


void MySPI_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;  //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	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);
	
	MySPI_W_SS(1);      //SS默认高电平(下降沿为开始工作,低电平状态为工作中,上升沿为结束工作)
	MySPI_W_SCK(0);     //SCK默认为低电平(上升沿移入数据,下降沿移出数据)
}

void MySPI_Start(void)
{
	MySPI_W_SS(0);
}

void MySPI_Stop(void)
{
	MySPI_W_SS(1);
}

//模式0
uint8_t MySPI_SwapByte(uint8_t ByteSend)
{
	uint8_t i, ByteReceive = 0x00;
	for (i = 0; i < 8; i ++)
	{
		//先SS下降沿,移出数据,SCK上升沿,移入数据,再SCK下降沿,移出数据,下面只管主机,
		MySPI_W_MOSI(ByteSend & (0x80 >> i));   //将数据移出到MOSI线
		MySPI_W_SCK(1);                         //上升沿移入数据
		//当MISO为1时,置变量指定位为1,当MISO为0时,不做处理,指定位为默认的初值0
		if (MySPI_R_MISO() == 1){ByteReceive |= (0x80 >> i);}  //将移入的数据读取出来
		MySPI_W_SCK(0);                         //下降沿移出数据
	}
	return ByteReceive;                         //读取出来的数据
}
/*
	1、for循环的优化
		MySPI_W_MOSI(ByteSend & 0x80 );   //将数据移出到MOSI线
		ByteSend << 1;                    //将数据左移动1位,去掉最高位,最低位置0
		MySPI_W_SCK(1);                         //上升沿移入数据
		if (MySPI_R_MISO() == 1){ByteSend |= 0x01;}  //将移入的数据读取出来,如果是0不管,如果是1,将最低位置1
		MySPI_W_SCK(0);                         //下降沿移出数据
	2、模式1
		MySPI_W_SCK(1);                         //上升沿移出来数据
		MySPI_W_MOSI(ByteSend & (0x80 >> i));   //将数据移出到MOSI线
		MySPI_W_SCK(0);                         //下降沿移入数据
		if (MySPI_R_MISO() == 1){ByteReceive |= (0x80 >> i);}  //将移入的数据读取出来
*/

		

2、W25Q64.c

#include "stm32f10x.h"                  // Device header
#include "MySPI.h"
#include "W25Q64_Ins.h"

/**
  * 函    数:W25Q64初始化
  * 参    数:无
  * 返 回 值:无
  */
void W25Q64_Init(void)
{
	MySPI_Init();					//先初始化底层的SPI
}

/**
  * 函    数:MPU6050读取ID号
  * 参    数:MID 工厂ID,使用输出参数的形式返回
  * 参    数:DID 设备ID,使用输出参数的形式返回
  * 返 回 值:无
  */
void W25Q64_ReadID(uint8_t *MID, uint16_t *DID)
{
	MySPI_Start();								//SPI起始
	MySPI_SwapByte(W25Q64_JEDEC_ID);			//交换发送读取ID的指令
	*MID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//交换接收MID,通过输出参数返回
	*DID = MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//交换接收DID高8位
	*DID <<= 8;									//高8位移到高位
	*DID |= MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//或上交换接收DID的低8位,通过输出参数返回
	MySPI_Stop();								//SPI终止
}

/**
  * 函    数:W25Q64写使能
  * 参    数:无
  * 返 回 值:无
  */
void W25Q64_WriteEnable(void)
{
	MySPI_Start();								//SPI起始
	MySPI_SwapByte(W25Q64_WRITE_ENABLE);		//交换发送写使能的指令
	MySPI_Stop();								//SPI终止
}

/**
  * 函    数:W25Q64等待忙
  * 参    数:无
  * 返 回 值:无
  */
void W25Q64_WaitBusy(void)
{
	uint32_t Timeout;
	MySPI_Start();								//SPI起始
	MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);				//交换发送读状态寄存器1的指令
	Timeout = 100000;							//给定超时计数时间
	while ((MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0x01) == 0x01)	//循环等待忙标志位
	{
		Timeout --;								//等待时,计数值自减
		if (Timeout == 0)						//自减到0后,等待超时
		{
			/*超时的错误处理代码,可以添加到此处*/
			break;								//跳出等待,不等了
		}
	}
	MySPI_Stop();								//SPI终止
}

/**
  * 函    数:W25Q64页编程
  * 参    数:Address 页编程的起始地址,范围:0x000000~0x7FFFFF
  * 参    数:DataArray	用于写入数据的数组
  * 参    数:Count 要写入数据的数量,范围:0~256
  * 返 回 值:无
  * 注意事项:写入的地址范围不能跨页
  */
void W25Q64_PageProgram(uint32_t Address, uint8_t *DataArray, uint16_t Count)
{
	uint16_t i;
	
	W25Q64_WriteEnable();						//写使能
	
	MySPI_Start();								//SPI起始
	MySPI_SwapByte(W25Q64_PAGE_PROGRAM);		//交换发送页编程的指令
	MySPI_SwapByte(Address >> 16);				//交换发送地址23~16位
	MySPI_SwapByte(Address >> 8);				//交换发送地址15~8位
	MySPI_SwapByte(Address);					//交换发送地址7~0位
	for (i = 0; i < Count; i ++)				//循环Count次
	{
		MySPI_SwapByte(DataArray[i]);			//依次在起始地址后写入数据
	}
	MySPI_Stop();								//SPI终止
	
	W25Q64_WaitBusy();							//等待忙
}

/**
  * 函    数:W25Q64扇区擦除(4KB)
  * 参    数:Address 指定扇区的地址,范围:0x000000~0x7FFFFF
  * 返 回 值:无
  */
void W25Q64_SectorErase(uint32_t Address)
{
	W25Q64_WriteEnable();						//写使能
	
	MySPI_Start();								//SPI起始
	MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB);	//交换发送扇区擦除的指令
	MySPI_SwapByte(Address >> 16);				//交换发送地址23~16位
	MySPI_SwapByte(Address >> 8);				//交换发送地址15~8位
	MySPI_SwapByte(Address);					//交换发送地址7~0位
	MySPI_Stop();								//SPI终止
	
	W25Q64_WaitBusy();							//等待忙
}

/**
  * 函    数:W25Q64读取数据
  * 参    数:Address 读取数据的起始地址,范围:0x000000~0x7FFFFF
  * 参    数:DataArray 用于接收读取数据的数组,通过输出参数返回
  * 参    数:Count 要读取数据的数量,范围:0~0x800000
  * 返 回 值:无
  */
void W25Q64_ReadData(uint32_t Address, uint8_t *DataArray, uint32_t Count)
{
	uint32_t i;
	MySPI_Start();								//SPI起始
	MySPI_SwapByte(W25Q64_READ_DATA);			//交换发送读取数据的指令
	MySPI_SwapByte(Address >> 16);				//交换发送地址23~16位
	MySPI_SwapByte(Address >> 8);				//交换发送地址15~8位
	MySPI_SwapByte(Address);					//交换发送地址7~0位
	for (i = 0; i < Count; i ++)				//循环Count次
	{
		DataArray[i] = MySPI_SwapByte(W25Q64_DUMMY_BYTE);	//依次在起始地址后读取数据
	}
	MySPI_Stop();								//SPI终止
}

3、main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "W25Q64.h"

uint8_t MID;							//定义用于存放MID号的变量
uint16_t DID;							//定义用于存放DID号的变量

uint8_t ArrayWrite[] = {0x01, 0x02, 0x03, 0x04};	//定义要写入数据的测试数组
uint8_t ArrayRead[4];								//定义要读取数据的测试数组

int main(void)
{
	/*模块初始化*/
	OLED_Init();						//OLED初始化
	W25Q64_Init();						//W25Q64初始化
	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "MID:   DID:");
	OLED_ShowString(2, 1, "W:");
	OLED_ShowString(3, 1, "R:");
	
	/*显示ID号*/
	W25Q64_ReadID(&MID, &DID);			//获取W25Q64的ID号
	OLED_ShowHexNum(1, 5, MID, 2);		//显示MID
	OLED_ShowHexNum(1, 12, DID, 4);		//显示DID
	
	W25Q64_SectorErase(0x000000);					//扇区擦除
	/*
		验证扇区擦除功能(方法:注释掉这一句)
		如果不擦除,一开始写入AA、BB、CC、DD,后面再次写入55、66、77、88,则读出来00、22、44、88
		即如果不进行擦除,则读出的数据=原始数据&写入的数据
	*/
	W25Q64_PageProgram(0x000000, ArrayWrite, 4);	//将写入数据的测试数组写入到W25Q64中
	W25Q64_ReadData(0x000000, ArrayRead, 4);		//读取刚写入的测试数据到读取数据的测试数组中
	/*
		数据是不能跨页写入
		验证:
		若写入55  66  77  88  
		W25Q64_PageProgram(0x0000FF, ArrayWrite, 4);	//数据不能跨页写入,66  77  88返回到页首写入
		W25Q64_ReadData(0x0000FF, ArrayRead, 4);		//读取数据可以跨页读出
		则读出的是55 FF FF FF  ,FF为第二页的数据,第二页是擦除了的,没有写入,默认是FF
		W25Q64_PageProgram(0x0000FF, ArrayWrite, 4);
		W25Q64_ReadData(0x000000, ArrayRead, 4);		//读出:66 77 88 FF
	*/
	
	/*显示数据*/
	OLED_ShowHexNum(2, 3, ArrayWrite[0], 2);		//显示写入数据的测试数组
	OLED_ShowHexNum(2, 6, ArrayWrite[1], 2);
	OLED_ShowHexNum(2, 9, ArrayWrite[2], 2);
	OLED_ShowHexNum(2, 12, ArrayWrite[3], 2);
	
	OLED_ShowHexNum(3, 3, ArrayRead[0], 2);			//显示读取数据的测试数组
	OLED_ShowHexNum(3, 6, ArrayRead[1], 2);
	OLED_ShowHexNum(3, 9, ArrayRead[2], 2);
	OLED_ShowHexNum(3, 12, ArrayRead[3], 2);
	
	while (1)
	{
		
	}
}

 四、硬件读写I2C

只需要在软件的基础上添加以下的代码

#include "stm32f10x.h"                  // Device header

void MySPI_W_SS(uint8_t BitValue)//SS还是软件模拟
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}

/*
	初始化步骤
	1、开启时钟
	2、初始化GPIO口
	(1)SCK、MOSI是由硬件外设控制的输出信号:复用推挽输出
	(2)MISO是硬件外设的输入信号:上拉输入(输入设备可以有很多个,不存在复用输入)
	(3)SS为软件控制的输出信号,配置为通用推挽输出
	3、配置SPI外设:	用结构体
	4、开关控制:调用SPI_Cmd,给SPI使能	
*/
void MySPI_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	
	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);
	
	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);
	
	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);
	
	SPI_InitTypeDef SPI_InitStructure;
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;   	//主机
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //双线全双工
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;   //8位数据帧
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;  //高位先行
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;  //波特率预分频器,配置SCK时钟的频率.SPI1:72MHz/128,SPI2:36MHz/128
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;    //默认低电平,空闲默认低电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;   //第一个边沿开始采样(移入)
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;      //一般选择软件NSS模式(不用了解)
	SPI_InitStructure.SPI_CRCPolynomial = 7;		//随便填
	SPI_Init(SPI1, &SPI_InitStructure);
	
	SPI_Cmd(SPI1, ENABLE);
	
	MySPI_W_SS(1);//默认不选中从机
}

void MySPI_Start(void)
{
	MySPI_W_SS(0);
}

void MySPI_Stop(void)
{
	MySPI_W_SS(1);
}


/*
	等待TXE为1,发送寄存器为空,发送寄存器不为空,先不着急写
	过程:
	写入数据到TDR-->转移到移位寄存器——>一旦移位寄存器有数据,时序波形就会自动产生(则ByteSend就会通过MOSI一位一位地移出去)
	——>在MOSI线上,就自动产生发送的时序波形
	由于是非连续传输,时序产生的时间内,不必提前把下个数据放到TDR,直接等待这段时间过去就行
	在发送的同时,MISO会移位进行接收
	发送和接收是同步
	接收移位完成时,会收到一个字节数据这时会置标志位置RXNE
*/
/*
	步骤总结(完成一个字节的交换)
	1、等待TXE为1
	2、写发送的数据至TDR,一旦TDR写出数据来。时序就会自动生成
	3、等待RXNE为1,发送完成,即接收完成,RXNE置1
	4、读取RDR接收的数据,就是置换接收的一个字节
注意:(1)必须是发送,同时接收,要先写东西,触发时序
	  (2)根据手册,
		发送缓冲器空闲标志(TXE):写入DR时,会顺便执行清楚TXE的操作,无须手动清除
		接收缓冲器非空(RXNE):读取SPI数据寄存器可以清除此标志
*/
uint8_t MySPI_SwapByte(uint8_t ByteSend)
{
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);//若没有数据,则MOSI线为SET
	
	SPI_I2S_SendData(SPI1, ByteSend);//ByteSend为要写入到DR,即TDR的数据(要发送的数据),之后会转入到移位寄存器

	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);//接收数据完毕的时候,MISO线有标志位RXNE
	
	return SPI_I2S_ReceiveData(SPI1);//读取DR,从RDR中,把交换接收的数据读取出来,返回值为RDR接收的数据
}

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

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

相关文章

排序算法经典模型: 梯度提升决策树(GBDT)的应用实战

目录 一、Boosting训练与预测 二、梯度增强的思想核心 三、如何构造弱学习器和加权平均的权重 四、损失函数 五、梯度增强决策树 六、GBDT生成新特征 主要思想 构造流程 七、梯度增强决策树以及在搜索的应用 7.1 GDBT模型调参 7.1.1 框架层面参数 n_estimators su…

leetcode:三数之和---双指针

问题&#xff1a; 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复…

阿里Animate Anyone:任何静态图像都能动起来,让C罗、梅西、内马尔一起跳科目三!

目录 前言 相关链接 摘要 方法 效果展示 为各种角色制作动画 比较 更多应用 前言 2024年一开年&#xff0c;社交媒体和朋友圈就被一系列惊艳舞蹈视频占领了。钢铁侠跳起了科目三&#xff0c;马斯克也在摆着网红舞步&#xff0c;这些大约10秒的视频都是借助大模…

C# Socket通信从入门到精通(16)——单个同步UDP服务器监听多个客户端C#代码实现

前言: 我们在开发UDP通信程序时,有时候我们也需要开发UDP服务器程序,这个服务器只需要和一个客户端实现通信,比如这篇博文C# Socket通信从入门到精通(15)——单个同步UDP服务器监听一个客户端C#代码实现,但是在实际项目中有的时候需要和多个客户端进行通信,这时和一个…

Pandas实践指南:从基础到高级数据分析

Pandas实践指南&#xff1a;从基础到高级数据分析 引言Pandas基础1. 安装和基本配置2. DataFrame和Series的基础3. 基础数据操作 数据清洗与预处理1. 缺失值处理2. 数据转换3. 数据过滤 数据分析与操作1. 数据聚合和分组操作2. 时间序列数据处理3. 条件逻辑和数据分割 高级数据…

将AWS iot消息数据发送S3

观看此文章之前&#xff0c;请先学习AWS iot的数据收集&#xff1a; 使用Linux SDK客户端向AWS Iot发送数据-CSDN博客 上述的文章向大家展示了如何从客户端向AWS iot发送数据&#xff0c;那么数据收到之后&#xff0c;我们如何通过AWS的服务进行数据处理或者保存呢&#xff1…

Unity - gamma space下还原linear space效果

文章目录 环境目的环境问题实践结果处理要点处理细节【OnPostProcessTexture 实现 sRGB 2 Linear 编码】 - 预处理【封装个简单的 *.cginc】 - shader runtime【shader需要gamma space下还原记得 #define _RECOVERY_LINEAR_IN_GAMMA】【颜色参数应用前 和 颜色贴图采样后】【灯…

【C#】基础巩固

最近写代码的时候各种灵感勃发&#xff0c;有了灵感&#xff0c;就该实现了&#xff0c;可是&#xff0c;实现起来有些不流畅&#xff0c;总是有这样&#xff0c;那样的卡壳&#xff0c;总结下来发现了几个问题。 1、C#基础内容不是特别牢靠&#xff0c;理解的不到位&#xff…

vivo 海量基础数据计算架构应用实践

作者&#xff1a;来自 vivo 互联网大数据团队 本文根据刘开周老师在“2023 vivo开发者大会"现场演讲内容整理而成。公众号回复【2023 VDC】获取互联网技术分会场议题相关资料。 本文介绍了vivo在万亿级数据增长驱动下&#xff0c;基础数据架构建设的演进过程&#xff0c;…

如何创建以业务为中心的AI?

AI是企业的未来&#xff0c;这一趋势越来越明显。各种AI模型可以帮助企业节省时间、提高效率并增加收入。随着越来越多的企业采用AI&#xff0c;AI很快就不再是一种可有可无的能力&#xff0c;而是企业参与市场竞争的必备能力。 然而&#xff0c;作为一名业务决策者&#xff0c…

【jetson笔记】torchaudio报错

原因是因为pip安装的包与jetson不兼容导致 自己安装或者cmake编译也会报错 需要拉取官方配置好的docker镜像 拉取docker镜像 具体容器可以看官网&#xff0c;按照自己需求拉取即可 https://catalog.ngc.nvidia.com/orgs/nvidia/containers/l4t-ml 如果其他包不需要只需要torc…

【学习笔记】遥感影像分类相关精度指标

文章目录 0.混淆矩阵1. 精度名词解释2. Kappa系数3.举个栗子参考资料 0.混淆矩阵 混淆矩阵是分类精度的评定指标。是一个用于表示分为某一类别的像元个数与地面检验为该类别数的比较阵列。 对检核分类精度的样区内所有的像元&#xff0c;统计其分类图中的类别与实际类别之间的…

来自世坤!寻找Alpha 构建交易策略的量化方法

问&#xff1a;常常看到有人说Alpha seeking&#xff0c;这究竟是什么意思&#xff1f; 推荐这本《Finding Alphas: A Quantitative Approach to Building Trading Strategies》。我拿到的PDF是2019年的第二版。来自WorldQuant&#xff08;世坤&#xff09;的Igor Tulchinshky…

【数据结构与算法】栈(Stack)之 浅谈数组和链表实现栈各自的优缺点

文章目录 1.栈介绍2. 哪种结构实现栈会更优&#xff1f;3.栈代码实现&#xff08;C语言&#xff09; 往期相关文章&#xff1a; 线性表之顺序表线性表之链表 1.栈介绍 栈是一种特殊的线性表&#xff0c;只允许在栈顶&#xff08;Top&#xff09;进行插入和删除元素操作&#…

Toolbar

记录一下遇到的问题 Toolbal 使用过程中左右出现间隙 代码&#xff1a; <com.google.android.material.appbar.AppBarLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"xmlns:t…

SAP 消息编号 KI235

在执行AFAB折旧运行的时候&#xff0c;折旧没有运行出来 通过AFBP查询&#xff0c;出现一下报错 原因是因为在ASCET当中没有配置科目分配对象&#xff0c;所以系统无法把折旧费和CO&#xff08;成本中心&#xff09;关联起来 “科目设置”必选勾选 重新运行AFAB &#xff0c;就…

【新书推荐】2.4节 数据宽度

本节内容&#xff1a;计算机受制于物理器件的制约&#xff0c;存储或读写数据的宽度是有长度限制的&#xff0c;通常我们使用数据位的位数来表示数据宽度&#xff0c;如8位、16位、32位、64位等。 ■计算机计数与数学计数的区别&#xff1a;数学中的数据可以是无穷大或无穷小&a…

01.领域驱动设计:微服务设计为什么要选择DDD学习总结

目录 1、前言 2、软件架构模式的演进 3、微服务设计和拆分的困境 4、为什么 DDD适合微服务 5、DDD与微服务的关系 6、总结 1、前言 我们知道&#xff0c;微服务设计过程中往往会面临边界如何划定的问题&#xff0c;不同的人会根据自己对微服务的理 解而拆分出不同的微服…

解读IP风险画像标签:深度洞察网络安全

在当今数字化的世界中&#xff0c;网络安全成为企业和个人关注的焦点。IP风险画像标签作为网络安全的利器&#xff0c;扮演着深度洞察网络风险的角色。本文将深入解读IP风险画像标签&#xff0c;揭示其在网络安全领域的重要性和功能。 1. IP风险画像标签是什么&#xff1f; I…

Kubernetes/k8s之安全机制:

k8s当中的安全机制 核心是分布式集群管理工具&#xff0c;容器编排&#xff0c;安全机制核心是:API SERVER作为整个集群内部通信的中介&#xff0c;也是外部控制的入口&#xff0c;所有的安全机制都是围绕api server开设计的。 请求api资源 1、认证 2、鉴权 3、准入机制 三…