【STM32-学习笔记-14-】FLASH闪存

news2025/1/20 7:37:16

文章目录

  • FALSH闪存
    • 一、FLASH简介
    • 二、FLASH基本结构
    • 三、FLASH解锁
    • 四、使用指针访问存储器
    • 五、FLASH擦除以及编程流程
      • Ⅰ、程序存储器全擦除
          • 1. 读取FLASH_CR的LOCK位
          • 2. 检查LOCK位是否为1
          • 3. 设置FLASH_CR的MER = 1和STRT = 1(如果LOCK位=0)
          • 4. 检查FLASH_SR的BSY位
          • 5. 读取并验证所有页的数据(如果BSY位=0)
      • Ⅱ、程序存储器页擦除
          • 1. 读取FLASH_CR的LOCK位
          • 2. 检查LOCK位是否为1
          • 3. 设置FLASH_CR的PER = 1和STRT = 1(如果LOCK位=0)
          • 4. 检查FLASH_SR的BSY位
          • 5. 读取并验证被擦除页的数据(如果BSY位=0)
      • Ⅲ、程序存储器编程
          • 1. 读取FLASH_CR的LOCK位
          • 2. 检查LOCK位是否为1
          • 3. 设置FLASH_CR的PG位=1(如果LOCK位=0)
          • 4. 在指定的地址写入半字(16位)
          • 5. 检查FLASH_SR的BSY位
          • 6. 读取编程地址并检查写入的数据(如果BSY位=0)
      • Ⅳ、闪存控制寄存器(FLASH_CR)
    • 六、选项字节
      • Ⅰ、选项字节擦除
      • Ⅱ、选项字节擦除
    • 七、器件电子签名
    • 八、读写内部FLASH
      • Ⅰ、FLASH函数
      • Ⅱ、使用示例:
        • MyFALSH.c
        • MyFALSH.h
        • Store.c
        • Store.h
    • 九、读取设备ID

FALSH闪存

ICP(In-Circuit Programming)和IAP(In Application Programming)是两种不同的微控制器编程方式

  • ICP(在线编程): ICP指的是通过JTAG/SWD协议或者系统加载程序(Bootloader,串口)下载用户应用程序到微控制器中的过程。它是一种在线编程方式,允许开发者直接将程序下载到微控制器中,通常用于开发和调试阶段

  • IAP(在应用编程): IAP即在应用编程,是用户通过自己编写的程序,在程序运行过程中,对User Flash的部分区域进行烧写,达到升级固件作用的方式。IAP的目的是为了在产品发布后,可以通过预留的通信口对产品中的固件程序进行更新升级。通常,为了实现IAP功能,需要在设计固件程序时编写两个项目代码,第一个项目程序不执行正常的功能操作,而只是通过某种通信方式接收程序或数据,执行对第二部分代码的更新,这个项目程序称为boot loader程序。第二个项目代码才是真正的功能代码。 这两部分代码都同时烧录在User Flash中。IAP允许在应用程序中重新烧写闪存存储器中的内容,但需要至少有一部分程序已经使用ICP方式烧到闪存存储器中(Bootloader)。IAP可以在不需要操作硬件平台的情况下实现升级(远程)

一、FLASH简介

  • STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分,通过闪存存储器接口(外设)可以对程序存储器和选项字节进行擦除和编程

  • 读写FLASH的用途:

    • 利用程序存储器的剩余空间来保存掉电不丢失的用户数据

    • 通过在程序中编程(IAP),实现程序的自我更新

  • 在线编程(In-Circuit Programming – ICP)用于更新程序存储器的全部内容,它通过JTAG、SWD协议或系统加载程序(Bootloader)下载程序

  • 在程序中编程(In-Application Programming – IAP)可以使用微控制器支持的任一种通信接口下载程序

  • 存储器映像:

    • 类型起始地址存储器用途
      ROM0x0800 0000程序存储器Flash存储C语言编译后的程序代码
      ROM0x1FFF F000系统存储器存储BootLoader,用于串口下载
      ROM0x1FFF F800选项字节存储一些独立于程序代码的配置参数
      RAM0x2000 0000运行内存SRAM存储运行过程中的临时变量
      RAM0x4000 0000外设寄存器存储各个外设的配置参数
      RAM0xE000 0000内核外设寄存器存储内核各个外设的配置参数

二、FLASH基本结构

image-20250118113700939

image-20250118113802184

三、FLASH解锁

  • FPEC共有三个键值:

    • RDPRT键 = 0x000000A5

    • KEY1 = 0x45670123

    • KEY2 = 0xCDEF89AB

      1. RDPRT键(0x000000A5)
        • 这个键值主要用于读保护操作。在STM32中,读保护是一种安全机制,用于防止外部对FLASH存储器内容的非法读取。当需要设置或修改读保护级别时,会用到这个键值。不过在解锁FPEC的过程中,RDPRT键并不直接参与解锁操作
      2. KEY1(0x45670123)和KEY2(0xCDEF89AB)
        • 这两个键值是专门用于解锁FPEC的关键序列。在STM32的FLASH编程和擦除操作之前,必须先解锁FPEC,否则无法对FLASH控制寄存器(FLASH_CR)进行写操作
  • 解锁:

    • 复位后,FPEC被保护,不能写入FLASH_CR

    • FLASH_KEYR先写入KEY1,再写入KEY2,解锁

    • 错误的操作序列会在下次复位前锁死FPECFLASH_CR

    • 解锁步骤:

      • 首先,需要向FLASH_KEYR(FLASH钥匙寄存器)写入KEY1(0x45670123)。这一步是解锁序列的第一步,相当于输入解锁密码的第一部分
      • 紧接着,再向FLASH_KEYR写入KEY2(0xCDEF89AB)。这是解锁序列的第二步,完成这一步后,FPEC就被解锁了。解锁后,就可以对FLASH_CR进行写操作,进而进行FLASH的编程、擦除等操作了
  • 加锁: 设置FLASH_CR中的LOCK位锁住FPECFLASH_CR

    • 加锁方法

      • 加锁操作只需要设置FLASH_CR(FLASH控制寄存器)中的LOCK位为1即可。一旦LOCK位被设置,FPEC和FLASH_CR就会被锁住,直到下一次复位。这样可以有效防止在正常工作过程中,由于程序错误或其他意外情况导致FLASH内容被非法修改

四、使用指针访问存储器

  • 使用指针指定地址下的存储器:
    • uint16_t Data = *((__IO uint16_t *)(0x08000000));
      • *((__IO uint16_t *)(0x08000000)); 含义:读出0x08000000地址下的数据,每次读出16位数据
  • 使用指针指定地址下的存储器:
    • *((__IO uint16_t *)(0x08000000)) = 0x1234;
  • 其中:
    • #define __IO volatile
    • 加上volatile的目的是为防止编译器优化

五、FLASH擦除以及编程流程

Ⅰ、程序存储器全擦除

image-20250118130601773

  • 详细解释:

  • 1. 读取FLASH_CR的LOCK位
    • 操作:首先,需要检查FLASH控制寄存器(FLASH_CR)中的LOCK位的状态
    • 目的:确定FLASH是否被锁定。如果LOCK位为1,表示FLASH处于锁定状态,无法进行擦除或写入操作
    2. 检查LOCK位是否为1
    • 操作:判断LOCK位的值

      • 如果LOCK位=1:表示FLASH被锁定,需要执行解锁过程

          • 操作:按照特定的顺序和键值对FLASH进行解锁
          • 详细步骤
            1. 向FLASH_KEYR寄存器写入KEY1(0x45670123)
            2. 向FLASH_KEYR寄存器写入KEY2(0xCDEF89AB)
          • 目的:解锁FLASH,使其可以接受擦除或写入操作
      • 如果LOCK位=0:表示FLASH未被锁定,可以继续进行擦除操作

    3. 设置FLASH_CR的MER = 1和STRT = 1(如果LOCK位=0)
    • 操作:在FLASH未锁定的情况下,设置FLASH_CR寄存器中的MER(Mass Erase Request,全擦除请求)位为1,并设置STRT(Start,启动)位为1
      • STRT位为1:启动信号
      • MER位为1:表示开始全擦除
    • 目的:启动全擦除操作。MER位的设置告诉FLASH控制器需要进行全擦除,而STRT位的设置则正式触发擦除过程
    4. 检查FLASH_SR的BSY位
    • 操作:在擦除过程中,不断检查FLASH状态寄存器(FLASH_SR)中的BSY(Busy,忙碌)位
      • 如果BSY位=1:表示擦除操作正在进行中,需要继续等待
      • 如果BSY位=0:表示擦除操作已经完成,可以进行下一步操作
    5. 读取并验证所有页的数据(如果BSY位=0)
    • 操作:在擦除操作完成后,读取FLASH中所有页的数据,并进行验证,确保所有数据都被正确擦除
    • 目的:确认擦除操作的效果,确保所有数据都被成功清除

Ⅱ、程序存储器页擦除

image-20250118130830137

  • 详细解释:

  • 1. 读取FLASH_CR的LOCK位
    • 操作:首先,需要检查FLASH控制寄存器(FLASH_CR)中的LOCK位的状态
    • 目的:确定FLASH是否被锁定。如果LOCK位为1,表示FLASH处于锁定状态,无法进行擦除或写入操作
    2. 检查LOCK位是否为1
    • 操作:判断LOCK位的值

      • 如果LOCK位=1:表示FLASH被锁定,需要执行解锁过程

          • 操作:按照特定的顺序和键值对FLASH进行解锁
          • 详细步骤
            1. 向FLASH_KEYR寄存器写入KEY1(0x45670123)
            2. 向FLASH_KEYR寄存器写入KEY2(0xCDEF89AB)
          • 目的:解锁FLASH,使其可以接受擦除或写入操作
      • 如果LOCK位=0:表示FLASH未被锁定,可以继续进行擦除操作

    3. 设置FLASH_CR的PER = 1和STRT = 1(如果LOCK位=0)
    • 操作:在FLASH未锁定的情况下,设置FLASH_CR寄存器中的PER(Page Erase Request,页擦除请求)位为1,并设置STRT(Start,启动)位为1
    • 详细步骤
      1. STRT位为1:启动信号
      2. PER位为1:表示开始页擦除
      3. 根据FLASH_AR寄存器中的页起始地址,开始擦除这一页
    • 目的:启动页擦除操作。PER位的设置告诉FLASH控制器需要进行页擦除,而STRT位的设置则正式触发擦除过程
    4. 检查FLASH_SR的BSY位
    • 操作:在擦除过程中,不断检查FLASH状态寄存器(FLASH_SR)中的BSY(Busy,忙碌)位
      • 如果BSY位=1:表示擦除操作正在进行中,需要继续等待
      • 如果BSY位=0:表示擦除操作已经完成,可以进行下一步操作
    5. 读取并验证被擦除页的数据(如果BSY位=0)
    • 操作:在擦除操作完成后,读取被擦除页的数据,并进行验证,确保该页的数据都被正确擦除
    • 目的:确认擦除操作的效果,确保指定的页已经被成功清除

Ⅲ、程序存储器编程

image-20250118131332587

  • 详细解释:

  • 1. 读取FLASH_CR的LOCK位
    • 操作:首先读取FLASH控制寄存器(FLASH_CR)中的LOCK位
    • 目的:确定FLASH是否处于锁定状态,因为锁定状态下不能进行写入操作
    2. 检查LOCK位是否为1
    • 操作:判断LOCK位的值
      • 如果LOCK位=1:表示FLASH被锁定,需要执行解锁序列
      • 如果LOCK位=0:表示FLASH未被锁定,可以进行写入操作
    3. 设置FLASH_CR的PG位=1(如果LOCK位=0)
    • 操作:在FLASH未锁定的情况下,设置FLASH_CR寄存器中的PG(Program,编程)位为1
    • 目的:启动编程(写入)操作
    4. 在指定的地址写入半字(16位)
    • 操作:将需要写入的数据(半字,即16位)写入到指定的FLASH地址
      • 任何非半字的数据,FPEC都会产生总线错误
    • 一次只能写入半字(16位)
    5. 检查FLASH_SR的BSY位
    • 操作:在写入过程中,不断检查FLASH状态寄存器(FLASH_SR)中的BSY(Busy,忙碌)位
      • 如果BSY位=1:表示写入操作正在进行中,需要继续等待
      • 如果BSY位=0:表示写入操作已经完成,可以进行下一步操作
    6. 读取编程地址并检查写入的数据(如果BSY位=0)
    • 操作:在写入操作完成后,从指定的FLASH地址读取数据,并与写入的数据进行比较,以验证写入是否成功
    • 目的:确保数据正确写入到FLASH中,防止写入错误

Ⅳ、闪存控制寄存器(FLASH_CR)

image-20250118135013553

六、选项字节

image-20250118132602912

  • nUSERUSER的反码,在写入选项字节时,需要在对应位置写入其反码(硬件自动完成)(保障措施)
  • RDP:写入RDPRT键(0x000000A5)后解除读保护

  • USER:配置硬件看门狗和进入停机/待机模式是否产生复位

  • Data0/1:用户可自定义使用

  • WRP0/1/2/3:配置写保护,每一个位对应保护4个存储页(中容量)

Ⅰ、选项字节擦除

  • 检查FLASH_SRBSY位,以确认没有其他正在进行的闪存操作

  • 解锁FLASH_CROPTWRE位

  • 设置FLASH_CROPTER位为1

  • 设置FLASH_CRSTRT位为1

  • 等待BSY位变为0

  • 读出被擦除的选择字节并做验证

Ⅱ、选项字节擦除

  • 检查FLASH_SRBSY位,以确认没有其他正在进行的编程操作

  • 解锁FLASH_CROPTWRE位

  • 设置FLASH_CROPTPG位为1

  • 写入要编程的半字到指定的地址

  • 等待BSY位变为0

  • 读出写入的地址并验证数据

七、器件电子签名

  • 电子签名存放在闪存存储器模块的系统存储区域,包含的芯片识别信息在出厂时编写,不可更改,使用指针读指定地址下的存储器可获取电子签名(STM32的ID号)

  • 闪存容量寄存器:

    • 基地址:0x1FFF F7E0

    • 大小:16位

  • 产品唯一身份标识寄存器:

    • 基地址: 0x1FFF F7E8

    • 大小:96位

八、读写内部FLASH

image-20250118151354221

Ⅰ、FLASH函数

/*------------ 所有STM32F10x设备通用的函数 -----*/
// 设置FLASH延迟
void FLASH_SetLatency(uint32_t FLASH_Latency);

// 使能或失能半周期访问
void FLASH_HalfCycleAccessCmd(uint32_t FLASH_HalfCycleAccess);

// 使能或失能预取指缓冲区
void FLASH_PrefetchBufferCmd(uint32_t FLASH_PrefetchBuffer);

// 解锁FLASH
void FLASH_Unlock(void);
// 锁定FLASH
void FLASH_Lock(void);

// 擦除指定页面
FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
// 擦除所有页面
FLASH_Status FLASH_EraseAllPages(void);
// 擦除选项字节
FLASH_Status FLASH_EraseOptionBytes(void);

// 编程一个字数据
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);
// 编程一个半字数据
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
// 编程选项字节数据
FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);

// 使能写保护
FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages);

// 使能或失能读出保护
FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState);

// 配置用户选项字节
FLASH_Status FLASH_UserOptionByteConfig(uint16_t OB_IWDG, uint16_t OB_STOP, uint16_t OB_STDBY);
// 获取用户选项字节
uint32_t FLASH_GetUserOptionByte(void);
// 获取写保护选项字节
uint32_t FLASH_GetWriteProtectionOptionByte(void);

// 获取读出保护状态
FlagStatus FLASH_GetReadOutProtectionStatus(void);

// 获取预取指缓冲区状态
FlagStatus FLASH_GetPrefetchBufferStatus(void);

// 配置FLASH中断
void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState);

// 获取FLASH标志位状态
FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG);
// 清除FLASH标志位
void FLASH_ClearFlag(uint32_t FLASH_FLAG);

// 获取FLASH状态
FLASH_Status FLASH_GetStatus(void);

// 等待FLASH最后一次操作完成
FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);

/*------------ 所有STM32F10x设备新增的函数 -----*/
// 解锁FLASH Bank1
void FLASH_UnlockBank1(void);

// 锁定FLASH Bank1
void FLASH_LockBank1(void);

// 擦除FLASH Bank1所有页面
FLASH_Status FLASH_EraseAllBank1Pages(void);

// 获取FLASH Bank1状态
FLASH_Status FLASH_GetBank1Status(void);

// 等待FLASH Bank1最后一次操作完成
FLASH_Status FLASH_WaitForLastBank1Operation(uint32_t Timeout);


#ifdef STM32F10X_XL//XL系列有两块FLASH:Bank1和Bank2
/*---- 仅适用于STM32F10x_XL容量设备的新增函数 -----*/
// 解锁FLASH Bank2
void FLASH_UnlockBank2(void);
// 锁定FLASH Bank2
void FLASH_LockBank2(void);

// 擦除FLASH Bank2所有页面
FLASH_Status FLASH_EraseAllBank2Pages(void);

// 获取FLASH Bank2状态
FLASH_Status FLASH_GetBank2Status(void);

// 等待FLASH Bank2最后一次操作完成
FLASH_Status FLASH_WaitForLastBank2Operation(uint32_t Timeout);

// 配置启动区
FLASH_Status FLASH_BootConfig(uint16_t FLASH_BOOT);
#endif

Ⅱ、使用示例:

MyFALSH.c
#include "stm32f10x.h"                  // Device header
//须在此实现>>读取、擦除、编程<<三个功能

//读取***********************************************
//读取32位字
uint32_t MyFLASH_ReadWord(uint32_t Addr)
{	 
	return *((__IO uint32_t *)(Addr));;
}
//读取16位半字
uint16_t MyFLASH_ReadHalfWord(uint32_t Addr)
{	 
	return *((__IO uint16_t *)(Addr));;
}
//读取8位字节
uint8_t MyFLASH_ReadByte(uint32_t Addr)
{	 
	return *((__IO uint8_t *)(Addr));;
}

//擦除***********************************************
//全擦除
void MyFLASH_EraseAllPages(void)
{
	FLASH_Unlock();//解锁
	FLASH_EraseAllPages();//全擦除
	FLASH_Lock();//上锁
}
//页擦除
void MyFLASH_ErasePage(uint32_t PageAddr)
{
	FLASH_Unlock();//解锁
	FLASH_ErasePage(PageAddr);//指定地址页擦除
	FLASH_Lock();//上锁
}

//编程***********************************************
//编程一个字
void MyFLASH_ProgramWord(uint32_t Addr, uint32_t Data)
{
	FLASH_Unlock();//解锁
	FLASH_ProgramWord(Addr, Data);//编程一个字数据
	FLASH_Lock();//上锁
}
//编程一个半字
void MyFLASH_ProgramHalfWord(uint32_t Addr, uint16_t Data)
{
	FLASH_Unlock();//解锁
	FLASH_ProgramHalfWord(Addr, Data);//编程一个半字数据
	FLASH_Lock();//上锁	
}

MyFALSH.h
#ifndef __MYFLASH_H__
#define __MYFLASH_H__
#include "stdint.h"

uint32_t MyFLASH_ReadWord(uint32_t Addr);		//读取32位字
uint16_t MyFLASH_ReadHalfWord(uint32_t Addr);	//读取16位半字
uint8_t MyFLASH_ReadByte(uint32_t Addr);		//读取8位字节
void MyFLASH_EraseAllPages(void);			//全擦除
void MyFLASH_ErasePage(uint32_t PageAddr);	//页擦除
void MyFLASH_ProgramWord(uint32_t Addr, uint32_t Data);		//编程一个字
void MyFLASH_ProgramHalfWord(uint32_t Addr, uint16_t Data);	//编程一个半字

#endif

Store.c
#include "stm32f10x.h"                  // Device header
#include "MyFLASH.h"

#define STORE_START_ADDR 0x0800FC00
#define STORE_COUNT 512

//功能:将数据存储在闪存的最后一页(起始地址0x0800FC00)
uint16_t Store_Data[STORE_COUNT];//定义一个SRAM数组

void Store_Init(void)
{
	if(MyFLASH_ReadHalfWord(STORE_START_ADDR) != 0x1234)//判断标志位
	{
		MyFLASH_ErasePage(STORE_START_ADDR);//擦除最后一页
		MyFLASH_ProgramHalfWord(STORE_START_ADDR, 0x1234);//置标志位
		//将SRAM数组中的内容放入这一页
		uint16_t i;
		for(i= 1; i < STORE_COUNT; i++)//由于第一个半字为标志位,故i从1开始
		{
			MyFLASH_ProgramHalfWord(STORE_START_ADDR + i * 2, 0x0000);//遍历写入0
		}
	}
	uint16_t i;
	for(i= 0; i < STORE_COUNT; i++)//读出数据放入数组中
	{
		Store_Data[i] = MyFLASH_ReadHalfWord(STORE_START_ADDR + i * 2);
	}
}

//将数组中的数据保存到FLASH中
void Store_Save(void)
{
	MyFLASH_ErasePage(STORE_START_ADDR);//擦除FLASH的最后一页
	uint16_t i;
	for(i= 0; i < STORE_COUNT; i++)//SRAM数组中的数据写入FALSH中
	{
		MyFLASH_ProgramHalfWord(STORE_START_ADDR + i * 2, Store_Data[i]);
	}
}

//清零
void Store_Clear(void)
{
	uint16_t i;
	for(i= 1; i < STORE_COUNT; i++)//由于第一个半字为标志位,故i从1开始
	{
		Store_Data[i] = 0x0000;
	}
	Store_Save();//保存更新
}

Store.h
#ifndef __STORE_H__
#define __STORE_H__
#include "stdint.h"

extern uint16_t Store_Data[];//定义一个SRAM数组

void Store_Init(void);
void Store_Save(void);//将数组中的数据保存到FLASH中
void Store_Clear(void);//清零

#endif

九、读取设备ID

  • 闪存容量寄存器:

    • 基地址:0x1FFF F7E0

    • 大小:16位

  • 产品唯一身份标识寄存器:

    • 基地址: 0x1FFF F7E8

    • 大小:96位

image-20250118172336086

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

int main(void)
{
    OLED_Init();
    OLED_ShowString(1,1,"F_Size:");
    OLED_ShowHexNum(1,8,*((__IO uint16_t *)(0x1FFFF7E0)),4);
	
    OLED_ShowString(2,1,"U_ID:");
    OLED_ShowHexNum(2,6,*((__IO uint16_t *)(0x1FFFF7E8)),4);
    OLED_ShowHexNum(2,11,*((__IO uint16_t *)(0x1FFFF7E8 + 0x02)),4);//加上地址偏移
    OLED_ShowHexNum(3,1,*((__IO uint32_t *)(0x1FFFF7E8 + 0x04)),8);
    OLED_ShowHexNum(4,1,*((__IO uint32_t *)(0x1FFFF7E8 + 0x08)),8);
    while(1)
    {
        
    }
}

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

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

相关文章

微信消息群发(定时群发)-UI自动化产品(基于.Net平台+C#)

整理 | 小耕家的喵大仙 出品 | CSDN&#xff08;ID&#xff1a;lichao19897314&#xff09; 关联源码及工具下载https://download.csdn.net/download/lichao19897314/90096681https://download.csdn.net/download/lichao19897314/90096681https://download.csdn.net/download/…

FPGA产业全景扫描

随着芯片种类日益丰富、功能日益强大&#xff0c;人们不禁好奇&#xff1a;一块FPGA是如何从最初的概念一步步呈现在我们面前的&#xff1f; FPGA设计、FPGA原型验证/仿真、FPGA板级调试和应用&#xff0c;是FPGA从概念到应用的必经之路。本文将围绕这几个核心环节&#xff0c…

SW - 钣金零件保存成DWG时,需要将折弯线去掉

文章目录 SW - 钣金零件保存成DWG时&#xff0c;需要将折弯线去掉概述笔记备注END SW - 钣金零件保存成DWG时&#xff0c;需要将折弯线去掉 概述 如果做需要弯折的切割件&#xff0c;最好做成钣金零件。 最近做了几个小钣金(将钣金展开&#xff0c;建立新草图&#xff0c;在2…

git系列之revert回滚

1. Git 使用cherry-pick“摘樱桃” step 1&#xff1a; 本地切到远程分支&#xff0c;对齐要对齐的base分支&#xff0c;举例子 localmap git pull git reset --hard localmap 对应的commit idstep 2&#xff1a; 执行cherry-pick命令 git cherry-pick abc123这样就会将远程…

Excel重新踩坑6:工作实战总结之根据筛选条件求平均成绩

一、前言&#xff1a; 这个博客的实战场景&#xff1a;给了一组学生数据&#xff0c;这些数据中&#xff0c;有全市20个社区&#xff0c;1-9年级的学生各科成绩。要求按照各社区统计1-9年级的所有学生各科平均值。下面首先介绍会用到的一些函数&#xff0c;然后再简单说明实战…

【数据分析】02- A/B 测试:玩转假设检验、t 检验与卡方检验

一、背景&#xff1a;当“审判”成为科学 1.1 虚拟场景——法庭审判 想象这样一个场景&#xff1a;有一天&#xff0c;你在王国里担任“首席审判官”。你面前站着一位嫌疑人&#xff0c;有人指控他说“偷了国王珍贵的金冠”。但究竟是他干的&#xff0c;还是他是被冤枉的&…

SpringMVC 实战指南:打造高效 Web 应用的秘籍

第一章&#xff1a;三层架构和MVC 三层架构&#xff1a; 开发服务器端&#xff0c;一般基于两种形式&#xff0c;一种 C/S 架构程序&#xff0c;一种 B/S 架构程序使用 Java 语言基本上都是开发 B/S 架构的程序&#xff0c;B/S 架构又分成了三层架构三层架构&#xff1a; 表现…

通过idea创建的springmvc工程需要的配置

在创建的spring mvc工程中&#xff0c;使用idea开发之前需要配置文件包括porm.xml、web.xml、springmvc.xml 1、porm.xml 工程以来的spring库&#xff0c;主要包括spring-aop、spring-web、spring-webmvc&#xff0c;示例配置如下&#xff1a; <project xmlns"http:/…

二、点灯基础实验

嵌入式基础实验第一个就是点灯&#xff0c;地位相当于编程界的hello world。 如下为LED原理图&#xff0c;要让相应LED发光&#xff0c;需要给I/O口设置输出引脚&#xff0c;低电平&#xff0c;二极管才会导通 2.1 打开初始工程&#xff0c;编写代码 以下会实现BLINKY常亮&…

搭建一个基于Spring Boot的数码分享网站

搭建一个基于Spring Boot的数码分享网站可以涵盖多个功能模块&#xff0c;例如用户管理、数码产品分享、评论、点赞、收藏、搜索等。以下是一个简化的步骤指南&#xff0c;帮助你快速搭建一个基础的数码分享平台。 — 1. 项目初始化 使用 Spring Initializr 生成一个Spring …

迅为RK3576开发板Android 多屏显示

迅为iTOP-3576开发板采用瑞芯微RK3576高性能、低功耗的应用处理芯片&#xff0c;集成了4个Cortex-A72和4个Cortex-A53核心&#xff0c;以及独立的NEON协处理器。它适用于ARM PC、边缘计算、个人移动互联网设备及其他多媒体产品。 1.1 Android 多屏同显 iTOP-RK3576 开发板支持…

gather算子的CUDA编程和算子测试

知乎介绍参考添加链接描述 完整测试框架参考本人仓库 添加链接描述 gather算子的onnx定义参考添加链接描述,该算子的主要变换参考下图: 这里我们不妨以input = [A, dimsize, D], indices = [B,C], axis = 1举例子,此时对应的output形状是[A,B,C,D],并且根据gather算子定…

深度学习 Pytorch 张量的线性代数运算

pytorch中并未设置单独的矩阵对象类型&#xff0c;因此pytorch中&#xff0c;二维张量就相当于矩阵对象&#xff0c;并且拥有一系列线性代数相关函数和方法。 在实际机器学习和深度学习建模过程中&#xff0c;矩阵或者高维张量都是基本对象类型&#xff0c;而矩阵所涉及到的线…

Linux下构建OpenEuler22.03+Nginx的Docker镜像

1. 制作OpenEuler22.03的Docker镜像 首先&#xff0c;下载OpenEuler20.03的镜像压缩包&#xff1a; 下载链接为&#xff1a; https://mirrors.aliyun.com/openeuler/openEuler-22.03-LTS/docker_img/x86_64/openEuler-docker.x86_64.tar.xz 这里我们可以顺便下载一下对应的…

Coder星球-测试用例设计

项目介绍 Coder星球是一个前后端分离的开源技术交流平台&#xff0c;包括管理后台和web前端&#xff0c;旨在打造一个互相交流技术并共同进步的平台。 项目功能结构图 测试用例 1.登录 2.注册 3.文章发布 4.点赞 5.评论

wow-agent---task2使用llama-index创建Agent

一&#xff1a;创造俩个函数&#xff0c;multiply和add作为fuction calling被LLM当做工具来使用&#xff0c;实现计算一个简单的计算题&#xff1a; from llama_index.llms.ollama import Ollama from llama_index.core.agent import ReActAgent from llama_index.core.tools …

React的应用级框架推荐——Next、Modern、Blitz等,快速搭建React项目

在 React 企业级应用开发中&#xff0c;Next.js、Modern.js 和 Blitz 是三个常见的框架&#xff0c;它们提供了不同的特性和功能&#xff0c;旨在简化开发流程并提高应用的性能和扩展性。以下是它们的详解与比较&#xff1a; Next、Modern、Blitz 1. Next.js Next.js 是由 Ve…

Git - 将指定文件夹或文件忽略(无论添加缓存区或提交都不会显示)

前言 有些时候&#xff0c;我们 不希望 项目有些文件夹被 Git “监控” 起来&#xff0c;而是与 Git 毫无关系。 第一步 注意&#xff1a;touch 与 . 之间有空格。 在 Gitbash 命令窗口中&#xff0c;输入以下命令&#xff1a; touch .gitignore此时&#xff0c;你的项目文件…

HTML5+Canvas实现的鼠标跟随自定义发光线条源码

源码介绍 HTML5Canvas实现的鼠标跟随自定义发光线条特效源码非常炫酷&#xff0c;在黑色的背景中&#xff0c;鼠标滑过即产生彩色变换的发光线条效果&#xff0c;且线条周围散发出火花飞射四溅的粒子光点特效。 效果预览 源码如下 <!DOCTYPE html PUBLIC "-//W3C//D…

C++:bfs解决多源最短路与拓扑排序问题习题

1. 多源最短路 其实就是将所有源头都加入队列&#xff0c; 01矩阵 LCR 107. 01 矩阵 - 力扣&#xff08;LeetCode&#xff09; 思路 求每个元素到离其最近0的距离如果我们将1当做源头加入队列的话&#xff0c;无法处理多个连续1的距离存储&#xff0c;我们反其道而行之&…