当前位置: 首页 > article >正文

# STM32F103 SD卡读写程序

下面是一个基于STM32F103系列微控制器的SD卡读写完整程序,使用标准外设库(StdPeriph)和FatFs文件系统。

硬件准备

  • STM32F103C8T6开发板(或其他F103系列)
  • SD卡模块(SPI接口)
  • 连接线缆

硬件连接

SD卡模块  STM32F103
CS   -> PA4 (SPI1_NSS)
SCK  -> PA5 (SPI1_SCK)
MISO -> PA6 (SPI1_MISO)
MOSI -> PA7 (SPI1_MOSI)
VCC  -> 3.3V
GND  -> GND

完整代码

1. 主程序 (main.c)

#include "stm32f10x.h"
#include "ff.h"
#include "diskio.h"
#include "spi_sd.h"
#include <stdio.h>
#include <string.h>FATFS fs;       /* FatFs文件系统对象 */
FIL fil;        /* 文件对象 */
FRESULT res;    /* FatFs函数返回结果 */
UINT bw;        /* 读写字节数 */void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART1_Init(void);int main(void)
{char buffer[128];/* 系统时钟配置 */RCC_Configuration();/* GPIO配置 */GPIO_Configuration();/* USART1初始化 */USART1_Init();printf("STM32F103 SD Card Test\r\n");/* 挂载文件系统 */if(f_mount(&fs, "0:", 1) != FR_OK){printf("Mount SD Card Failed!\r\n");while(1);}printf("SD Card Mounted Successfully!\r\n");/* 打开/创建文件 */res = f_open(&fil, "0:test.txt", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);if(res != FR_OK){printf("Open File Failed!\r\n");while(1);}/* 写入数据 */f_lseek(&fil, 0);f_printf(&fil, "Hello, STM32 SD Card!\r\n");f_printf(&fil, "This is a test file.\r\n");/* 读取数据 */f_lseek(&fil, 0);while(f_gets(buffer, sizeof(buffer), &fil)){printf("%s", buffer);}/* 关闭文件 */f_close(&fil);/* 卸载文件系统 */f_mount(NULL, "0:", 1);while(1){}
}void RCC_Configuration(void)
{/* 复位RCC时钟配置 */RCC_DeInit();/* 使能外部高速晶振 */RCC_HSEConfig(RCC_HSE_ON);/* 等待HSE就绪 */if(RCC_WaitForHSEStartUp() == SUCCESS){/* 设置HCLK = SYSCLK */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* 设置PCLK2 = HCLK */RCC_PCLK2Config(RCC_HCLK_Div1);/* 设置PCLK1 = HCLK/2 */RCC_PCLK1Config(RCC_HCLK_Div2);/* 设置FLASH延时 */FLASH_SetLatency(FLASH_Latency_2);FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/* 设置PLL时钟源为HSE, 9倍频 */RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);/* 使能PLL */RCC_PLLCmd(ENABLE);/* 等待PLL就绪 */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);/* 设置PLL为系统时钟源 */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* 等待系统时钟源切换完成 */while(RCC_GetSYSCLKSource() != 0x08);}/* 使能SPI1时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);/* 使能GPIOA时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);/* 使能USART1时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
}void GPIO_Configuration(void)
{GPIO_InitTypeDef GPIO_InitStructure;/* 配置SPI1引脚: SCK, MISO, MOSI */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);/* 配置SPI1 CS引脚 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA, GPIO_Pin_4);  // CS高电平/* 配置USART1 TX引脚 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);/* 配置USART1 RX引脚 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);
}void USART1_Init(void)
{USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = 115200;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);USART_Cmd(USART1, ENABLE);
}/* 重定向printf到USART1 */
int fputc(int ch, FILE *f)
{USART_SendData(USART1, (uint8_t)ch);while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);return ch;
}

2. SPI和SD卡驱动 (spi_sd.c)

#include "spi_sd.h"
#include "stm32f10x.h"
#include "delay.h"/* SPI1读写一个字节 */
uint8_t SPI1_ReadWriteByte(uint8_t TxData)
{/* 等待发送缓冲区空 */while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);/* 发送数据 */SPI_I2S_SendData(SPI1, TxData);/* 等待接收缓冲区非空 */while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);/* 返回接收到的数据 */return SPI_I2S_ReceiveData(SPI1);
}/* SPI1初始化 */
void SPI1_Init(void)
{SPI_InitTypeDef SPI_InitStructure;/* SPI1配置 */SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial = 7;SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE);/* CS高电平 */SD_CS_HIGH();
}/* SD卡初始化 */
uint8_t SD_Initialize(void)
{uint8_t retry = 0;uint8_t i;uint8_t buf[4];uint16_t count = 0;/* 初始化SPI */SPI1_Init();/* 延时至少74个时钟周期 */SD_CS_HIGH();for(i = 0; i < 10; i++){SPI1_ReadWriteByte(0xFF);}/* 发送CMD0进入空闲状态 */while(SD_SendCmd(CMD0, 0, 0x95) != 0x01){retry++;if(retry > 100){return 1; // 超时}}/* 发送CMD8检查SD卡版本 */if(SD_SendCmd(CMD8, 0x1AA, 0x87) == 0x01){/* SD卡v2.0 */for(i = 0; i < 4; i++){buf[i] = SPI1_ReadWriteByte(0xFF);}/* 初始化SD卡 */while(SD_SendCmd(ACMD41, 0x40000000, 0x01) != 0x00){count++;if(count > 0xFFFE){return 2; // 初始化失败}}/* 读取OCR寄存器 */if(SD_SendCmd(CMD58, 0, 0x01) != 0x00){return 3;}for(i = 0; i < 4; i++){buf[i] = SPI1_ReadWriteByte(0xFF);}/* 检查CCS位 */if(buf[0] & 0x40){CardType = SD_TYPE_V2HC; // SDHC/SDXC}else{CardType = SD_TYPE_V2;   // SDv2}}else{/* SD卡v1.x或MMC */if(SD_SendCmd(ACMD41, 0, 0x01) <= 1){/* SD卡v1.x */CardType = SD_TYPE_V1;count = 0;/* 等待初始化完成 */while(SD_SendCmd(ACMD41, 0, 0x01) != 0x00){count++;if(count > 0xFFFE){return 4; // 初始化失败}}}else{/* MMC卡 */CardType = SD_TYPE_MMC;count = 0;/* 等待初始化完成 */while(SD_SendCmd(CMD1, 0, 0x01) != 0x00){count++;if(count > 0xFFFE){return 5; // 初始化失败}}}}/* 设置SPI时钟为高速模式 */SPI1_SetSpeed(SPI_BaudRatePrescaler_4);return 0; // 初始化成功
}/* 发送SD卡命令 */
uint8_t SD_SendCmd(uint8_t cmd, uint32_t arg, uint8_t crc)
{uint8_t res;/* 等待SD卡准备就绪 */SD_WaitReady();/* 发送命令 */SD_CS_LOW();SPI1_ReadWriteByte(cmd | 0x40);SPI1_ReadWriteByte(arg >> 24);SPI1_ReadWriteByte(arg >> 16);SPI1_ReadWriteByte(arg >> 8);SPI1_ReadWriteByte(arg);SPI1_ReadWriteByte(crc);/* 等待响应 */if(cmd == CMD12){SPI1_ReadWriteByte(0xFF); // 跳过停止命令后的一个字节}/* 等待响应 */uint8_t retry = 0;do{res = SPI1_ReadWriteByte(0xFF);retry++;} while((res & 0x80) && (retry < 200));return res;
}/* 等待SD卡准备就绪 */
uint8_t SD_WaitReady(void)
{uint32_t timeout = 0;do{if(SPI1_ReadWriteByte(0xFF) == 0xFF){return 0;}timeout++;} while(timeout < 0xFFFFFF);return 1;
}/* 读取SD卡一个扇区 */
uint8_t SD_ReadDisk(uint8_t *buf, uint32_t sector, uint8_t cnt)
{uint8_t res;if(CardType == SD_TYPE_V2HC){sector *= 512; // SDHC/SDXC卡使用字节地址}if(cnt == 1){/* 读取单个块 */res = SD_SendCmd(CMD17, sector, 0x01);if(res == 0){/* 等待数据开始标记 */if(!SD_RecvData(buf, 512)){res = 1;}}}else{/* 读取多个块 */res = SD_SendCmd(CMD18, sector, 0x01);do{if(!SD_RecvData(buf, 512)){res = 1;break;}buf += 512;} while(--cnt);/* 发送停止传输命令 */SD_SendCmd(CMD12, 0, 0x01);}SD_CS_HIGH();SPI1_ReadWriteByte(0xFF);return res;
}/* 接收数据 */
uint8_t SD_RecvData(uint8_t *buf, uint16_t len)
{uint16_t i;uint8_t res;/* 等待数据开始标记 */uint16_t retry = 0;do{res = SPI1_ReadWriteByte(0xFF);retry++;} while((res == 0xFF) && (retry < 0xFFFF));if(res != 0xFE){return 1; // 数据开始标记错误}/* 接收数据 */for(i = 0; i < len; i++){buf[i] = SPI1_ReadWriteByte(0xFF);}/* 接收CRC */SPI1_ReadWriteByte(0xFF);SPI1_ReadWriteByte(0xFF);return 0;
}/* 写入SD卡一个扇区 */
uint8_t SD_WriteDisk(const uint8_t *buf, uint32_t sector, uint8_t cnt)
{uint8_t res;if(CardType == SD_TYPE_V2HC){sector *= 512; // SDHC/SDXC卡使用字节地址}if(cnt == 1){/* 写入单个块 */res = SD_SendCmd(CMD24, sector, 0x01);if(res == 0){/* 发送数据开始标记 */if(!SD_SendData(buf, 0xFE)){res = 1;}}}else{/* 写入多个块 */if(CardType != SD_TYPE_MMC){SD_SendCmd(CMD55, 0, 0x01);SD_SendCmd(CMD23, cnt, 0x01);}res = SD_SendCmd(CMD25, sector, 0x01);if(res == 0){do{if(!SD_SendData(buf, 0xFC)){res = 1;break;}buf += 512;} while(--cnt);/* 发送停止传输标记 */if(!SD_SendData(0, 0xFD)){res = 1;}}}SD_CS_HIGH();SPI1_ReadWriteByte(0xFF);return res;
}/* 发送数据 */
uint8_t SD_SendData(const uint8_t *buf, uint8_t token)
{uint16_t i;uint8_t res;/* 等待SD卡准备就绪 */SD_WaitReady();/* 发送数据开始标记 */SPI1_ReadWriteByte(token);/* 发送数据 */if(token != 0xFD){for(i = 0; i < 512; i++){SPI1_ReadWriteByte(buf[i]);}/* 发送CRC */SPI1_ReadWriteByte(0xFF);SPI1_ReadWriteByte(0xFF);/* 获取数据响应 */res = SPI1_ReadWriteByte(0xFF);if((res & 0x1F) != 0x05){return 1;}}/* 等待SD卡完成写入 */SD_WaitReady();return 0;
}/* 设置SPI速度 */
void SPI1_SetSpeed(uint16_t Speed)
{SPI_Cmd(SPI1, DISABLE);SPI_InitTypeDef SPI_InitStructure;SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = Speed;SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial = 7;SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE);
}

3. 头文件 (spi_sd.h)

#ifndef __SPI_SD_H
#define __SPI_SD_H#include "stm32f10x.h"/* SD卡类型定义 */
#define SD_TYPE_ERR     0x00
#define SD_TYPE_MMC     0x01
#define SD_TYPE_V1      0x02
#define SD_TYPE_V2      0x04
#define SD_TYPE_V2HC    0x06/* SD卡命令定义 */
#define CMD0    0       // 复位SD卡
#define CMD1    1
#define CMD8    8       // 发送接口条件
#define CMD9    9       // 读取CSD数据
#define CMD10   10      // 读取CID数据
#define CMD12   12      // 停止数据传输
#define CMD16   16      // 设置块大小
#define CMD17   17      // 读取单个块
#define CMD18   18      // 读取多个块
#define CMD23   23      // 设置预擦除块数
#define CMD24   24      // 写入单个块
#define CMD25   25      // 写入多个块
#define CMD41   41      // 发送主机容量支持信息
#define CMD55   55      // 应用特定命令
#define CMD58   58      // 读取OCR寄存器
#define CMD59   59      // 设置CRC开/关
#define ACMD41  0x41    // ACMD41/* SD卡片选控制 */
#define SD_CS_LOW()     GPIO_ResetBits(GPIOA, GPIO_Pin_4)
#define SD_CS_HIGH()    GPIO_SetBits(GPIOA, GPIO_Pin_4)/* 全局变量 */
extern uint8_t CardType;/* 函数声明 */
uint8_t SD_Initialize(void);
uint8_t SD_SendCmd(uint8_t cmd, uint32_t arg, uint8_t crc);
uint8_t SD_WaitReady(void);
uint8_t SD_ReadDisk(uint8_t *buf, uint32_t sector, uint8_t cnt);
uint8_t SD_WriteDisk(const uint8_t *buf, uint32_t sector, uint8_t cnt);
uint8_t SD_RecvData(uint8_t *buf, uint16_t len);
uint8_t SD_SendData(const uint8_t *buf, uint8_t token);
void SPI1_Init(void);
uint8_t SPI1_ReadWriteByte(uint8_t TxData);
void SPI1_SetSpeed(uint16_t Speed);#endif

4. FatFs磁盘接口 (diskio.c)

#include "diskio.h"
#include "spi_sd.h"/* 获取磁盘状态 */
DSTATUS disk_status(BYTE pdrv)
{return 0;
}/* 初始化磁盘 */
DSTATUS disk_initialize(BYTE pdrv)
{if(SD_Initialize() == 0){return 0;}return STA_NOINIT;
}/* 读取扇区 */
DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count)
{if(SD_ReadDisk(buff, sector, count) == 0){return RES_OK;}return RES_ERROR;
}/* 写入扇区 */
DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count)
{if(SD_WriteDisk(buff, sector, count) == 0){return RES_OK;}return RES_ERROR;
}/* 其他控制命令 */
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
{switch(cmd){case CTRL_SYNC:return RES_OK;case GET_SECTOR_COUNT:*(DWORD*)buff = 1024*1024; // 假设SD卡容量为512MBreturn RES_OK;case GET_SECTOR_SIZE:*(WORD*)buff = 512;return RES_OK;case GET_BLOCK_SIZE:*(DWORD*)buff = 8;return RES_OK;default:return RES_PARERR;}
}

5. 头文件 (diskio.h)

#ifndef _DISKIO
#define _DISKIO#include "integer.h"/* 状态码 */
#define STA_NOINIT      0x01    /* 驱动器未初始化 */
#define STA_NODISK      0x02    /* 无介质 */
#define STA_PROTECT     0x04    /* 写保护 *//* 命令码 */
#define CTRL_SYNC       0       /* 完成挂起的写入过程 */
#define GET_SECTOR_COUNT 1      /* 获取扇区数 */
#define GET_SECTOR_SIZE 2       /* 获取扇区大小 */
#define GET_BLOCK_SIZE  3       /* 获取擦除块大小 */
#define CTRL_POWER      4       /* 控制电源状态 */
#define CTRL_LOCK       5       /* 锁定/解锁介质移除 */
#define CTRL_EJECT      6       /* 弹出介质 */
#define MMC_GET_TYPE    10      /* 获取卡类型 */
#define MMC_GET_CSD     11      /* 读取CSD */
#define MMC_GET_CID     12      /* 读取CID */
#define MMC_GET_OCR     13      /* 读取OCR */
#define MMC_GET_SDSTAT  14      /* 读取SD状态 *//* 结果码 */
typedef enum {RES_OK = 0,         /* 成功 */RES_ERROR,          /* 读写错误 */RES_WRPRT,          /* 写保护 */RES_NOTRDY,         /* 设备未就绪 */RES_PARERR          /* 无效参数 */
} DRESULT;/* 函数声明 */
DSTATUS disk_initialize(BYTE pdrv);
DSTATUS disk_status(BYTE pdrv);
DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count);
DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count);
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff);#endif

使用说明

  1. 将上述代码分别保存到对应的文件中
  2. 创建一个新的STM32工程,添加这些文件
  3. 需要包含FatFs文件系统(可以从官网http://elm-chan.org/fsw/ff/00index_e.html下载)
  4. 编译并下载到STM32F103开发板
  5. 连接SD卡模块
  6. 通过串口调试工具(如Putty)查看输出结果

功能说明

这个程序实现了以下功能:

  1. 初始化SD卡(支持SDv1, SDv2和SDHC卡)
  2. 挂载FAT文件系统
  3. 创建/打开文件"test.txt"
  4. 向文件写入两行文本
  5. 从文件读取内容并通过串口输出
  6. 关闭文件并卸载文件系统

注意事项

  1. 确保SD卡已格式化为FAT16或FAT32文件系统
  2. 如果使用不同的SPI引脚,需要修改GPIO配置
  3. SD卡工作电压为3.3V,不要使用5V电压
  4. 如果读写失败,可以尝试降低SPI时钟速度

希望这个完整的SD卡读写程序对你有帮助!

相关文章:

# STM32F103 SD卡读写程序

下面是一个基于STM32F103系列微控制器的SD卡读写完整程序&#xff0c;使用标准外设库(StdPeriph)和FatFs文件系统。 硬件准备 STM32F103C8T6开发板(或其他F103系列)SD卡模块(SPI接口)连接线缆 硬件连接 SD卡模块 STM32F103 CS -> PA4 (SPI1_NSS) SCK -> PA5 (SPI…...

Spring中循环依赖问题的解决机制总结

一、解决机制 1. 什么是循环依赖 循环依赖是指两个或多个Bean之间相互依赖对方&#xff0c;形成一个闭环的依赖关系。最常见的情况是当Bean A依赖Bean B&#xff0c;而Bean B又依赖Bean A时&#xff0c;就形成了循环依赖。在Spring容器初始化过程中&#xff0c;如果不加以特殊…...

青少年编程与数学 01-011 系统软件简介 04 Linux操作系统

青少年编程与数学 01-011 系统软件简介 04 Linux操作系统 一、Linux 的发展历程&#xff08;一&#xff09;起源&#xff08;二&#xff09;早期发展&#xff08;三&#xff09;成熟与普及&#xff08;四&#xff09;移动与嵌入式领域的拓展 二、Linux 的内核与架构&#xff08…...

微软PowerBI考试 PL300-使用适用于 Power BI 的 Copilot 创建交互式报表

微软PowerBI考试 PL300-使用适用于 Power BI 的 Copilot 创建交互式报表 Microsoft Power BI 可帮助您通过交互式报表准备数据并对数据进行可视化。 如果您是 Power BI 的新用户&#xff0c;可能很难知道从哪里开始&#xff0c;并且创建报表可能很耗时。 通过适用于 Power BI …...

损坏的RAID5 第十六次CCF-CSP计算机软件能力认证

纯大模拟 提前打好板子 我只通过4个用例点 然后就超时了。 #include<iostream> #include<cstring> #include<algorithm> #include<unordered_map> #include<bits/stdc.h> using namespace std; int n, s, l; unordered_map<int, string>…...

Android USB 通信开发

Android USB 通信开发主要涉及两种模式&#xff1a;主机模式(Host Mode)和配件模式(Accessory Mode)。以下是开发USB通信应用的关键知识点和步骤。 1. 基本概念 主机模式(Host Mode) Android设备作为USB主机&#xff0c;控制连接的USB设备 需要设备支持USB主机功能(通常需要O…...

Prompt提示工程指南#Kontext图像到图像

重要提示&#xff1a;单个prompt的最大token数为512 # 核心能力 Kontext图像编辑系统能够&#xff1a; 理解图像上下文语义实现精准的局部修改保持原始图像风格一致性支持复杂的多步迭代编辑 # 基础对象修改 示例场景&#xff1a;改变汽车颜色 Prompt设计&#xff1a; Change …...

产品经理课程(十一)

&#xff08;一&#xff09;复习 1、用户需求不等于产品需求&#xff0c;挖掘用户的本质需求 2、功能设计的前提&#xff1a;不违背我们的产品的基础定位&#xff08;用一句话阐述我们的产品&#xff1a;工具&#xff1a;产品画布&#xff09; 3、判断设计好坏的标准&#xf…...

Moldflow充填分析设置

1. 如何选择注塑机&#xff1a; 注塑机初选按注射量来选择&#xff1a; 点网格统计;选择三角形, 三角形体积就是产品的体积 47.7304 cm^3 点网格统计;选择柱体, 柱体的体积就是浇注系统的体积2.69 cm^3 所以总体积产品体积浇注系统体积 47.732.69 cm^3 材料的熔体密度与固体…...

Imprompter: Tricking LLM Agents into Improper Tool Use

原文&#xff1a;Imprompter: Tricking LLM Agents into Improper Tool Use 代码&#xff1a;Reapor-Yurnero/imprompter: Codebase of https://arxiv.org/abs/2410.14923 实机演示&#xff1a;Imprompter 摘要&#xff1a; 新兴发展的Agent可以将LLM与外部资源工具相结合&a…...

python asyncio的作用

协程是可以暂停运行和恢复运行的函数。协程函数是用async定义的函数。它与普通的函数最大的区别是&#xff0c;当执行的时候不会真的执行里面的代码&#xff0c;而是返回一个协程对象&#xff0c;在执行协程对象时才执行里面真正的代码。 例如代码&#xff1a; async def cor…...

【大模型:知识图谱】--3.py2neo连接图数据库neo4j

【图数据库】--Neo4j 安装_neo4j安装-CSDN博客 需要打开图数据库Neo4j&#xff0c; neo4j console 目录 1.图数据库--连接 2.图数据库--操作 2.1.创建节点 2.2.删除节点 2.3.增改属性 2.4.建立关系 2.5.查询节点 2.6.查询关系 3.图数据库--实例 1.图数据库--连接 fr…...

如何理解机器人课程的技术壁垒~壁垒和赚钱是两件不同的事情

答疑&#xff1a; 有部分朋友私聊说博客内容&#xff0c;越来越不适合人类阅读习惯…… 可以做这种理解&#xff0c;我从23年之后&#xff0c;博客会不会就是写给机器看的。 或者说我在以黑盒方式测试AI推荐的风格。 主观-客观-主观螺旋式发展过程。 2015最早的一篇博客重…...

如何从零开始建设一个网站?

当你没有建站的基础和建站的知识&#xff0c;那么应该如何开展网站建设和网站管理。而今天的教程是不管你是为自己建站还是为他人建站都适合的。本教程会指导你如何进入建站&#xff0c;将建站的步骤给大家分解&#xff1a; 首先我们了解一下&#xff0c;建站需要那些步骤和流程…...

selinux firewalld

一、selinux 1.说明 SELinux 是 Security-Enhanced Linux 的缩写&#xff0c;意思是安全强化的 linux&#xff1b; SELinux 主要由美国国家安全局&#xff08;NSA&#xff09;开发&#xff0c;当初开发的目的是为了避免资源的误用 DAC&#xff08;Discretionary Access Cont…...

408第一季 - 数据结构 - 字符串和KMP算法

闲聊 这章属于难点但考频低 3个名词记一下&#xff1a;模式匹配&#xff0c;主串&#xff0c;字串&#xff08;模式串&#xff09; 举个例子 主串 aabaaaabaab 字串 aabaab 模式匹配 从主串找到字串 暴力解法 也是不多说 很暴力就是了 KMP算法 next数组 它只和字串有关 先…...

如何查看自己电脑安装的Java——JDK

开始->运行->然后输入cmd进入dos界面 &#xff08;快捷键windows->输入cmd&#xff09; 输入java -version&#xff0c;回车 出现了一下信息就是安装了jdk 输入java -verbose&#xff0c;回车 查看安装目录...

青少年编程与数学 01-011 系统软件简介 07 iOS操作系统

青少年编程与数学 01-011 系统软件简介 07 iOS操作系统 一、发展历程&#xff08;一&#xff09;诞生初期&#xff08;2007 - 2008年&#xff09;&#xff08;二&#xff09;功能拓展与升级&#xff08;2009 - 2013年&#xff09;&#xff08;三&#xff09;持续优化与创新&…...

电力系统时间同步系统之三

2.6 电力系统时间同步装置 时间同步装置主要完成时间信号和时间信息的同步传递&#xff0c;并提供相应的时间格式和物理接口。时间同步装置主要由三大部分组成&#xff1a;时间输入、内部时钟和时间输出&#xff0c;如图 2-25 所示。输入装置的时间信号和时间信息的精度必须不…...

火语言RPA--界面应用详解

新建一个界面应用后&#xff0c;软件将自动弹出一个界面设计器&#xff0c;本篇将介绍下流程设计器中各部分的功能。 UI控件列表 显示软件中自带的所有UI控件流程库 流程是颗粒组件的容器&#xff0c;可在建立的流程中添加颗粒组件编写成规则流程。 流程编辑好后再绑定UI控件…...

基于Spring Boot的云音乐平台设计与实现

基于Spring Boot的云音乐平台设计与实现——集成协同过滤推荐算法的全栈项目实战 &#x1f4d6; 文章目录 项目概述技术选型与架构设计数据库设计后端核心功能实现推荐算法设计与实现前端交互设计系统优化与性能提升项目部署与测试总结与展望 项目概述 &#x1f3af; 项目背…...

Neovim - 打造一款属于自己的编辑器(一)

文章目录 前言&#xff08;劝退&#xff09;neovim 安装neovim 配置配置文件位置第一个 hello world 代码拆分 neovim 配置正式配置 neovim基础配置自定义键位Lazy 插件管理器配置tokyonight 插件配置BufferLine 插件配置自动补全括号 / 引号 插件配置 前言&#xff08;劝退&am…...

RAG检索系统的两大核心利器——Embedding模型和Rerank模型

在RAG系统中&#xff0c;有两个非常重要的模型一个是Embedding模型&#xff0c;另一个则是Rerank模型&#xff1b;这两个模型在RAG中扮演着重要角色。 Embedding模型的作用是把数据向量化&#xff0c;通过降维的方式&#xff0c;使得可以通过欧式距离&#xff0c;余弦函数等计算…...

CLion社区免费后,使用CLion开发STM32相关工具资源汇总与入门教程

Clion下载与配置 Clion推出社区免费&#xff0c;就是需要注册一个账号使用&#xff0c;大家就不用去找破解版版本了&#xff0c;jetbrains家的IDEA用过的都说好&#xff0c;这里嵌入式领域也推荐使用。 CLion官网下载地址 安装没有什么特别&#xff0c;下一步就好。 启动登录…...

第21讲、Odoo 18 配置机制详解

Odoo 18 配置机制详解&#xff1a;res.config.settings 与 ir.config_parameter 原理与实战指南 在现代企业信息化系统中&#xff0c;灵活且可维护的系统参数配置是模块开发的核心能力之一。Odoo 作为一款高度模块化的企业管理软件&#xff0c;其参数配置机制主要依赖于两个关…...

LinkedList、Vector、Set

LinkedList 基本概念 LinkedList 是一个双向链表的实现类&#xff0c;它实现了 List、Deque、Queue 和 Cloneable 接口&#xff0c;底层使用双向链表结构&#xff0c;适合频繁插入和删除操作。 主要特点 有序&#xff0c;可重复。 查询速度较慢&#xff0c;插入/删除速度较…...

SQL 基础入门

SQL 基础入门 SQL&#xff08;全称 Structured Query Language&#xff0c;结构化查询语言&#xff09;是用于操作关系型数据库的标准语言&#xff0c;主要用于数据的查询、新增、修改和删除。本文面向初学者&#xff0c;介绍 SQL 的基础概念和核心操作。 1. 常见的 SQL 数据…...

GitHub 趋势日报 (2025年06月05日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 1472 onlook 991 HowToCook 752 ChinaTextbook 649 quarkdown 451 scrapy 324 age…...

基于Flask框架的前后端分离项目开发流程是怎样的?

基于Flask框架的前后端分离项目开发流程可分为需求分析、架构设计、并行开发、集成测试和部署上线五个阶段。以下是详细步骤和技术要点&#xff1a; 一、需求分析与规划 1. 明确项目边界 功能范围&#xff1a;确定核心功能&#xff08;如用户认证、数据管理、支付流程&#…...

Delphi SetFileSecurity 设置安全描述符

在Delphi中&#xff0c;使用Windows API函数SetFileSecurity来设置文件或目录的安全描述符时&#xff0c;你需要正确地构建一个安全描述符&#xff08;SECURITY_DESCRIPTOR结构&#xff09;。这个过程涉及到几个步骤&#xff0c;包括创建或修改安全描述符、设置访问控制列表&am…...