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

做网站超链接用什么软件深圳网站建制作

做网站超链接用什么软件,深圳网站建制作,网站建议反馈应该怎么做,wordpress手机端侧边工具栏STM32F7xx —— QSPI 目录 STM32F7xx —— QSPI 一、QSPI 二、几个重要的函数 三、几个重要的结构 四、QSPI接口设计#xff08;仅供参考#xff09; 五、QSPI驱动W25Q256 一、QSPI SPI 是 Queued SPI 的简写#xff0c;是 Motorola公司推出的 SPI 接口的扩展#xf…                                 STM32F7xx —— QSPI 目录 STM32F7xx —— QSPI 一、QSPI 二、几个重要的函数 三、几个重要的结构 四、QSPI接口设计仅供参考 五、QSPI驱动W25Q256 一、QSPI SPI 是 Queued SPI 的简写是 Motorola公司推出的 SPI 接口的扩展比 SPI 应用更加广泛。在 SPI 协议的基础上Motorola 公司对其功能进行了增强增加了队列传输机制推出了队列串行外围接口协议即 QSPI 协议使用该接口用户可以一次性传输包含多达16个8位或16位数据的传输队列。一旦传输启动直到传输结束都不需要CPU干预极大的提高了传输效率。该协议在ColdFire系列MCU得到广泛应用。与SPI相比QSPI的最大结构特点是以80字节的RAM代替了SPI的发送和接收寄存器。QSPI 是一种专用的通信接口连接单、双或四条数据线 SPI Flash 存储介质。 该接口可以在以下三种模式下工作 ① 间接模式使用 QSPI 寄存器执行全部操作 ② 状态轮询模式周期性读取外部 Flash 状态寄存器而且标志位置 1 时会产生中断如擦除或烧写完成会产生中断 ③ 内存映射模式外部 Flash 映射到微控制器地址空间从而系统将其视作内部存储器。 QSPI通过6根线与SPI芯片通信下图是内部框图 QSPI每条命令必须包含一个或多个阶段指令、地址、交替字节、空指令和数据。 QSPI发送命令等待QSPI空闲设置命令参数。 QSPI读数据设置数据传输长度设置QSPI工作模式并设置地址读取数据。 QSPI写数据设置数据传输长度设置QSPI工作模式并设置地址写数据。 二、几个重要的函数 HAL_StatusTypeDef HAL_QSPI_Init (QSPI_HandleTypeDef *hqspi); // 初始化HAL_StatusTypeDef HAL_QSPI_Command(QSPI_HandleTypeDef *hqspi, QSPI_CommandTypeDef *cmd, uint32_t Timeout); // 发送命令HAL_StatusTypeDef HAL_QSPI_Transmit (QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout); // 发送数据HAL_StatusTypeDef HAL_QSPI_Receive (QSPI_HandleTypeDef *hqspi, uint8_t *pData, uint32_t Timeout); // 接收数据 三、几个重要的结构 // QSPI操作句柄 typedef struct {QUADSPI_TypeDef *Instance; /* QSPI registers base address */QSPI_InitTypeDef Init; /* QSPI communication parameters */uint8_t *pTxBuffPtr; /* Pointer to QSPI Tx transfer Buffer */__IO uint16_t TxXferSize; /* QSPI Tx Transfer size */__IO uint16_t TxXferCount; /* QSPI Tx Transfer Counter */uint8_t *pRxBuffPtr; /* Pointer to QSPI Rx transfer Buffer */__IO uint16_t RxXferSize; /* QSPI Rx Transfer size */__IO uint16_t RxXferCount; /* QSPI Rx Transfer Counter */DMA_HandleTypeDef *hdma; /* QSPI Rx/Tx DMA Handle parameters */__IO HAL_LockTypeDef Lock; /* Locking object */__IO HAL_QSPI_StateTypeDef State; /* QSPI communication state */__IO uint32_t ErrorCode; /* QSPI Error code */uint32_t Timeout; /* Timeout for the QSPI memory access */ }QSPI_HandleTypeDef;// InstanceQSPI基地址 --- QUADSPI // Init设置QSPI参数 // pTxBuffPtr,TxXferSize,TxXferCount发送缓存指针 发送数据量 剩余数据量 // pRxBuffPtr,RxXferSize,RxXferCount接收缓存指针 发送数据量 剩余数据量 // hdma与DMA相关 其他为过程变量不需要关心 // 参数配置 时钟分频系数 FIFO阈值 采样移位 FLASH大小 片选高电平时间 时钟模式 闪存ID 双闪存模式设置 typedef struct {uint32_t ClockPrescaler; /* Specifies the prescaler factor for generating clock based on the AHB clock.This parameter can be a number between 0 and 255 */ uint32_t FifoThreshold; /* Specifies the threshold number of bytes in the FIFO (used only in indirect mode)This parameter can be a value between 1 and 32 */uint32_t SampleShifting; /* Specifies the Sample Shift. The data is sampled 1/2 clock cycle delay later to take in account external signal delays. (It should be QSPI_SAMPLE_SHIFTING_NONE in DDR mode)This parameter can be a value of ref QSPI_SampleShifting */uint32_t FlashSize; /* Specifies the Flash Size. FlashSize1 is effectively the number of address bits required to address the flash memory. The flash capacity can be up to 4GB (addressed using 32 bits) in indirect mode, but the addressable space in memory-mapped mode is limited to 256MBThis parameter can be a number between 0 and 31 */uint32_t ChipSelectHighTime; /* Specifies the Chip Select High Time. ChipSelectHighTime1 defines the minimum number of clock cycles which the chip select must remain high between commands.This parameter can be a value of ref QSPI_ChipSelectHighTime */ uint32_t ClockMode; /* Specifies the Clock Mode. It indicates the level that clock takes between commands.This parameter can be a value of ref QSPI_ClockMode */uint32_t FlashID; /* Specifies the Flash which will be used,This parameter can be a value of ref QSPI_Flash_Select */uint32_t DualFlash; /* Specifies the Dual Flash Mode StateThis parameter can be a value of ref QSPI_DualFlash_Mode */ }QSPI_InitTypeDef; // 采样移位 #define QSPI_SAMPLE_SHIFTING_NONE ((uint32_t)0x00000000U) /*!No clock cycle shift to sample data*/ #define QSPI_SAMPLE_SHIFTING_HALFCYCLE ((uint32_t)QUADSPI_CR_SSHIFT) /*!1/2 clock cycle shift to sample data*/四、QSPI接口设计仅供参考 #define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE();#define QSPI_BK1_NCS_PORT GPIOB #define QSPI_BK1_NCS_PIN GPIO_PIN_6 #define QSPI_BK1_NCS_AF GPIO_AF10_QUADSPI #define QSPI_BK1_NCS_CONFIG() GPIOConfigExt(QSPI_BK1_NCS_PORT, QSPI_BK1_NCS_PIN, GPIO_MODE_AF_PP, GPIO_PULLUP, QSPI_BK1_NCS_AF)#define QSPI_BK1_CLK_PORT GPIOB #define QSPI_BK1_CLK_PIN GPIO_PIN_2 #define QSPI_BK1_CLK_AF GPIO_AF9_QUADSPI #define QSPI_BK1_CLK_CONFIG() GPIOConfigExt(QSPI_BK1_CLK_PORT, QSPI_BK1_CLK_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, QSPI_BK1_CLK_AF)#define QSPI_BK1_IO0_PORT GPIOF #define QSPI_BK1_IO0_PIN GPIO_PIN_8 #define QSPI_BK1_IO0_AF GPIO_AF10_QUADSPI #define QSPI_BK1_IO0_CONFIG() GPIOConfigExt(QSPI_BK1_IO0_PORT, QSPI_BK1_IO0_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, QSPI_BK1_IO0_AF)#define QSPI_BK1_IO1_PORT GPIOF #define QSPI_BK1_IO1_PIN GPIO_PIN_9 #define QSPI_BK1_IO1_AF GPIO_AF10_QUADSPI #define QSPI_BK1_IO1_CONFIG() GPIOConfigExt(QSPI_BK1_IO1_PORT, QSPI_BK1_IO1_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, QSPI_BK1_IO1_AF)#define QSPI_BK1_IO2_PORT GPIOF #define QSPI_BK1_IO2_PIN GPIO_PIN_7 #define QSPI_BK1_IO2_AF GPIO_AF9_QUADSPI #define QSPI_BK1_IO2_CONFIG() GPIOConfigExt(QSPI_BK1_IO2_PORT, QSPI_BK1_IO2_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, QSPI_BK1_IO2_AF)#define QSPI_BK1_IO3_PORT GPIOF #define QSPI_BK1_IO3_PIN GPIO_PIN_6 #define QSPI_BK1_IO3_AF GPIO_AF9_QUADSPI #define QSPI_BK1_IO3_CONFIG() GPIOConfigExt(QSPI_BK1_IO3_PORT, QSPI_BK1_IO3_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL, QSPI_BK1_IO3_AF)// 封装几个必要的接口 static QSPI_HandleTypeDef qspi_handle;static void qspi_gpio_init(void) {QSPI_CLK_ENABLE();QSPI_BK1_NCS_CONFIG();QSPI_BK1_CLK_CONFIG();QSPI_BK1_IO0_CONFIG();QSPI_BK1_IO1_CONFIG();QSPI_BK1_IO2_CONFIG();QSPI_BK1_IO3_CONFIG(); }static void qspi_mode_init(void) {qspi_handle.Instance QUADSPI; // QSPIqspi_handle.Init.ClockPrescaler 2; // QPSI分频比W25Q256最大频率为104M 所以此处应该为2QSPI频率就为216/(21)72MHZqspi_handle.Init.FifoThreshold 4; // FIFO阈值为4个字节qspi_handle.Init.SampleShifting QSPI_SAMPLE_SHIFTING_HALFCYCLE; // 采样移位半个周期(DDR模式下,必须设置为0)qspi_handle.Init.FlashSize POSITION_VAL(0X2000000) - 1; // SPI FLASH大小W25Q256大小为32M字节qspi_handle.Init.ChipSelectHighTime QSPI_CS_HIGH_TIME_4_CYCLE; // 片选高电平时间为4个时钟(13.8*455.2ns),即手册里面的tSHSL参数qspi_handle.Init.ClockMode QSPI_CLOCK_MODE_0; // 模式0qspi_handle.Init.FlashID QSPI_FLASH_ID_1; // 第一片flashqspi_handle.Init.DualFlash QSPI_DUALFLASH_DISABLE; // 禁止双闪存模式HAL_QSPI_Init(qspi_handle); //QSPI初始化 }void QSPIInit(void) {qspi_gpio_init();qspi_mode_init(); }// QSPI发送命令 // instruction:要发送的指令 // address:发送到的目的地址 // dummyCycles:空指令周期数 // instructionMode:指令模式;QSPI_INSTRUCTION_NONE,QSPI_INSTRUCTION_1_LINE,QSPI_INSTRUCTION_2_LINE,QSPI_INSTRUCTION_4_LINE // addressMode:地址模式; QSPI_ADDRESS_NONE,QSPI_ADDRESS_1_LINE,QSPI_ADDRESS_2_LINE,QSPI_ADDRESS_4_LINE // addressSize:地址长度;QSPI_ADDRESS_8_BITS,QSPI_ADDRESS_16_BITS,QSPI_ADDRESS_24_BITS,QSPI_ADDRESS_32_BITS // dataMode:数据模式; QSPI_DATA_NONE,QSPI_DATA_1_LINE,QSPI_DATA_2_LINE,QSPI_DATA_4_LINE void QSPISendCMD(uint32_t instruction, uint32_t address, uint32_t dummyCycles, uint32_t instructionMode, uint32_t addressMode, uint32_t addressSize, uint32_t dataMode) {QSPI_CommandTypeDef Cmdhandler;Cmdhandler.Instruction instruction; // 指令Cmdhandler.Address address; // 地址Cmdhandler.DummyCycles dummyCycles; // 设置空指令周期数Cmdhandler.InstructionMode instructionMode; // 指令模式Cmdhandler.AddressMode addressMode; // 地址模式Cmdhandler.AddressSize addressSize; // 地址长度Cmdhandler.DataMode dataMode; // 数据模式Cmdhandler.SIOOMode QSPI_SIOO_INST_EVERY_CMD; // 每次都发送指令Cmdhandler.AlternateByteMode QSPI_ALTERNATE_BYTES_NONE; // 无交替字节Cmdhandler.DdrMode QSPI_DDR_MODE_DISABLE; // 关闭DDR模式Cmdhandler.DdrHoldHalfCycle QSPI_DDR_HHC_ANALOG_DELAY;HAL_QSPI_Command(qspi_handle, Cmdhandler, 5000); }// 接收指定长度数据 uint8_t QSPIReceive(uint8_t *buffer, uint32_t length) {qspi_handle.Instance-DLR length - 1;if(HAL_QSPI_Receive(qspi_handle, buffer, 5000) HAL_OK){return 0; //接收数据}else{return 1;} }// 发送指定长度数据 uint8_t QSPITransmit(uint8_t *buffer, uint32_t length) {qspi_handle.Instance-DLR length - 1;if(HAL_QSPI_Transmit(qspi_handle, buffer, 5000) HAL_OK){return 0; //发送数据}else{return 1;} } 五、QSPI驱动W25Q256 W25Q256:32M  512块每块16个扇区每个扇区4K。具体指令看手册。封装了如下接口初始化读写擦除等接口是以后移植文件系统的基础 #define W25QXX_WRITE_ENABLE 0x06 #define W25QXX_WRITE_DISABLE 0x04 #define W25QXX_READ_STATUS_REG1 0x05 #define W25QXX_READ_STATUS_REG2 0x35 #define W25QXX_READ_STATUS_REG3 0x15 #define W25QXX_WRITE_STATUS_REG1 0x01 #define W25QXX_WRITE_STATUS_REG2 0x31 #define W25QXX_WRITE_STATUS_REG3 0x11 #define W25QXX_READ_DATA 0x03 #define W25QXX_FAST_READ_DATA 0x0B #define W25QXX_FAST_READ_DUAL 0x3B #define W25QXX_PAGE_PROGRAM 0x02 #define W25QXX_BLOCK_ERASE 0xD8 #define W25QXX_SECTOR_ERASE 0x20 #define W25QXX_CHIP_ERASE 0xC7 #define W25QXX_DEVICEID 0xAB #define W25QXX_MANUFACT_DEVICEID 0x90 #define W25QXX_JEDEC_DEVICEID 0x9F #define W25QXX_EABLE_4BYTE_ADDR 0xB7 #define W25QXX_EXIT_4BYTE_ADDR 0xE9 #define W25QXX_SET_READ_PARAM 0xC0 #define W25QXX_ENTER_QPIMODE 0x38 #define W25QXX_EXIT_QPIMODE 0xFFuint8_t w25qxx_qpi_mode 0; // QSPI模式标志:0,SPI模式;1,QPI模式.// 读取W25QXX的状态寄存器W25QXX一共有3个状态寄存器 // 状态寄存器1 // BIT7 6 5 4 3 2 1 0 // SPR RV TB BP2 BP1 BP0 WEL BUSY // SPR:默认0,状态寄存器保护位,配合WP使用 // TB,BP2,BP1,BP0:FLASH区域写保护设置 // WEL:写使能锁定 // BUSY:忙标记位(1,忙;0,空闲) // 默认:0x00 // 状态寄存器2 // BIT7 6 5 4 3 2 1 0 // SUS CMP LB3 LB2 LB1 (R) QE SRP1 // 状态寄存器3 // BIT7 6 5 4 3 2 1 0 // HOLD/RST DRV1 DRV0 (R) (R) WPS ADP ADS // reg:状态寄存器号范:1~3 // 返回值:状态寄存器值 static uint8_t w25qxx_read_status(uint8_t reg) {uint8_t value 0, command 0;switch(reg){case 1:command W25QXX_READ_STATUS_REG1; // 读状态寄存器1指令break;case 2:command W25QXX_READ_STATUS_REG2; // 读状态寄存器2指令break;case 3:command W25QXX_READ_STATUS_REG3; // 读状态寄存器3指令break;default:command W25QXX_READ_STATUS_REG1;break;}if(w25qxx_qpi_mode){QSPISendCMD(command, 0, 0, QSPI_INSTRUCTION_4_LINES, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_4_LINES); //QPI,写command指令,地址为0,4线传数据_8位地址_无地址_4线传输指令,无空周期,1个字节数据}else{QSPISendCMD(command, 0, 0, QSPI_INSTRUCTION_1_LINE, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_1_LINE); //SPI,写command指令,地址为0,单线传数据_8位地址_无地址_单线传输指令,无空周期,1个字节数据}QSPIReceive(value, 1);return value; }// 写状态寄存器 static void w25qxx_write_status(uint8_t reg, uint8_t status) {uint8_t command 0;switch(reg){case 1:command W25QXX_WRITE_STATUS_REG1; //写状态寄存器1指令break;case 2:command W25QXX_WRITE_STATUS_REG2; //写状态寄存器2指令break;case 3:command W25QXX_WRITE_STATUS_REG3; //写状态寄存器3指令break;default:command W25QXX_WRITE_STATUS_REG1;break;}if(w25qxx_qpi_mode){QSPISendCMD(command, 0, 0, QSPI_INSTRUCTION_4_LINES, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_4_LINES); // QPI,写command指令,地址为0,4线传数据_8位地址_无地址_4线传输指令,无空周期,1个字节数据}else{QSPISendCMD(command, 0, 0, QSPI_INSTRUCTION_1_LINE, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_1_LINE); // SPI,写command指令,地址为0,单线传数据_8位地址_无地址_单线传输指令,无空周期,1个字节数据}QSPITransmit(status, sizeof(status)); }// 写使能 将S1寄存器的WEL置位 static void w25qxx_write_enable(void) {if(w25qxx_qpi_mode){QSPISendCMD(W25QXX_WRITE_ENABLE, 0, 0, QSPI_INSTRUCTION_4_LINES, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_NONE); // QPI,写使能指令,地址为0,无数据_8位地址_无地址_4线传输指令,无空周期,0个字节数据}else{QSPISendCMD(W25QXX_WRITE_ENABLE, 0, 0, QSPI_INSTRUCTION_1_LINE, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_NONE); // SPI,写使能指令,地址为0,无数据_8位地址_无地址_单线传输指令,无空周期,0个字节数据} }// 写失能 将WEL清零 void W25QXX_Write_Disable(void) {if(w25qxx_qpi_mode){QSPISendCMD(W25QXX_WRITE_DISABLE, 0, 0, QSPI_INSTRUCTION_4_LINES, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_NONE); // QPI,写禁止指令,地址为0,无数据_8位地址_无地址_4线传输指令,无空周期,0个字节数据}else{QSPISendCMD(W25QXX_WRITE_DISABLE, 0, 0, QSPI_INSTRUCTION_1_LINE, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_NONE); // SPI,写禁止指令,地址为0,无数据_8位地址_无地址_单线传输指令,无空周期,0个字节数据} }// 等待空闲 void w25qxx_wait_busy(void) {while((w25qxx_read_status(1) 0x01) 0x01); // 等待BUSY位清空 }// W25QXX进入QSPI模式 static void w25qxx_qspi_init(void) {uint8_t reg2;reg2 w25qxx_read_status(2); // 先读出状态寄存器2的原始值if((reg2 0X02) 0) // QE位未使能{w25qxx_write_enable(); // 写使能reg2 | 1 1; // 使能QE位w25qxx_write_status(2, reg2); // 写状态寄存器2}QSPISendCMD(W25QXX_ENTER_QPIMODE, 0, 0, QSPI_INSTRUCTION_1_LINE, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_NONE); // 写command指令,地址为0,无数据_8位地址_无地址_单线传输指令,无空周期,0个字节数据w25qxx_qpi_mode 1; // 标记QSPI模式 }// 0XEF13,表示芯片型号为W25Q80 // 0XEF14,表示芯片型号为W25Q16 // 0XEF15,表示芯片型号为W25Q32 // 0XEF16,表示芯片型号为W25Q64 // 0XEF17,表示芯片型号为W25Q128 // 0XEF18,表示芯片型号为W25Q256 static void w25qxx_id_get(void) {uint8_t temp[2];uint16_t device_id;if(w25qxx_qpi_mode){QSPISendCMD(W25QXX_MANUFACT_DEVICEID, 0, 0, QSPI_INSTRUCTION_4_LINES, QSPI_ADDRESS_4_LINES, QSPI_ADDRESS_24_BITS, QSPI_DATA_4_LINES); // QPI,读id,地址为0,4线传输数据_24位地址_4线传输地址_4线传输指令,无空周期,2个字节数据}else{QSPISendCMD(W25QXX_MANUFACT_DEVICEID, 0, 0, QSPI_INSTRUCTION_1_LINE, QSPI_ADDRESS_1_LINE, QSPI_ADDRESS_24_BITS, QSPI_DATA_1_LINE); // SPI,读id,地址为0,单线传输数据_24位地址_单线传输地址_单线传输指令,无空周期,2个字节数据}QSPIReceive(temp, 2);device_id (temp[0] 8) | temp[1];printf(QSPI Flash Device ID: %X\r\n, device_id); }void W25QXXInit(void) {uint8_t temp;QSPIInit();w25qxx_qspi_init(); // 使能QSPI模式w25qxx_id_get(); // 读取FLASH ID.temp w25qxx_read_status(3); // 读取状态寄存器3判断地址模式if((temp 0X01) 0) // 如果不是4字节地址模式,则进入4字节地址模式{w25qxx_write_enable(); // 写使能QSPISendCMD(W25QXX_EABLE_4BYTE_ADDR, 0, 0, QSPI_INSTRUCTION_4_LINES, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_NONE); // QPI,使能4字节地址指令,地址为0,无数据_8位地址_无地址_4线传输指令,无空周期,0个字节数据}w25qxx_write_enable(); // 写使能QSPISendCMD(W25QXX_SET_READ_PARAM, 0, 0, QSPI_INSTRUCTION_4_LINES, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_4_LINES); // QPI,设置读参数指令,地址为0,4线传数据_8位地址_无地址_4线传输指令,无空周期,1个字节数据temp 3 4; // 设置P4P511,8个dummy clocks,104MQSPITransmit(temp, 1); }// 擦除一块4096字节 最少需要150ms void W25QXXSectorErase(uint32_t addr) {//addr / 4096;addr * 4096;w25qxx_write_enable();w25qxx_wait_busy();QSPISendCMD(W25QXX_SECTOR_ERASE, addr, 0, QSPI_INSTRUCTION_4_LINES, QSPI_ADDRESS_4_LINES, QSPI_ADDRESS_32_BITS, QSPI_DATA_NONE); // QPI,写扇区擦除指令,地址为0,无数据_32位地址_4线传输地址_4线传输指令,无空周期,0个字节数据w25qxx_wait_busy(); }// 擦除整个芯片 void W25QXXChipErase(void) {w25qxx_write_enable(); //SET WELw25qxx_wait_busy();QSPISendCMD(W25QXX_CHIP_ERASE, 0, 0, QSPI_INSTRUCTION_4_LINES, QSPI_ADDRESS_NONE, QSPI_ADDRESS_8_BITS, QSPI_DATA_NONE); // QPI,写全片擦除指令,地址为0,无数据_8位地址_无地址_4线传输指令,无空周期,0个字节数据w25qxx_wait_busy(); //等待芯片擦除结束 }// 写最多256字节 void W25QXXWritePage(uint32_t addr, uint8_t *buffer, uint16_t length) {w25qxx_write_enable(); //写使能QSPISendCMD(W25QXX_PAGE_PROGRAM, addr, 0, QSPI_INSTRUCTION_4_LINES, QSPI_ADDRESS_4_LINES, QSPI_ADDRESS_32_BITS, QSPI_DATA_4_LINES); // QPI,页写指令,地址为WriteAddr,4线传输数据_32位地址_4线传输地址_4线传输指令,无空周期,NumByteToWrite个数据QSPITransmit(buffer, length);w25qxx_wait_busy(); //等待写入结束 }// 写最多65536字节 无擦除动作 void W25QXXWriteExt(uint32_t addr, uint8_t *buffer, uint16_t length) {uint16_t pageremain 256 - addr % 256; // 单页剩余的字节数if(addr length - 1 (32 * 1024 * 1024)){return;}if(length pageremain){pageremain length; // 不大于256个字节}while(1){// 分页写入W25QXXWritePage(addr, buffer, pageremain);if(length pageremain){break; //写入结束了}else{buffer pageremain;addr pageremain;length - pageremain; // 减去已经写入了的字节数if(length 256){pageremain 256; // 一次可以写入256个字节}else{pageremain length; // 不够256个字节了}}} }// 写最多65536字节 带擦除动作 static uint8_t W25QXX_BUFFER[4096]; void W25QXXWrite(uint32_t addr, uint8_t* buffer, uint16_t length) {uint32_t secpos;uint16_t secoff, secremain, i;uint8_t * w25q_buf;w25q_buf W25QXX_BUFFER;secpos addr / 4096; // 扇区地址secoff addr % 4096; // 在扇区内的偏移secremain 4096 - secoff; // 扇区剩余空间大小if(length secremain){secremain length; // 不大于4096个字节}while(1){WatchdogFeed();W25QXXRead(secpos * 4096, w25q_buf, 4096); // 读出整个扇区的内容for(i 0; i secremain; i){if(w25q_buf[secoff i] ! 0XFF){break; // 需要擦除}}if(i secremain) // 需要擦除{W25QXXSectorErase(secpos); // 擦除这个扇区for(i 0; i secremain; i){w25q_buf[i secoff] buffer[i];}W25QXXWriteExt(secpos * 4096, w25q_buf, 4096); // 写入整个扇区}else{W25QXXWriteExt(addr, buffer, secremain); // 写已经擦除了的,直接写入扇区剩余区间.}if(length secremain){break;}else{secpos;secoff 0;buffer secremain;addr secremain;length - secremain;if(length 4096){secremain 4096;}else{secremain length;}}}; }// 读取SPI FLASH,仅支持QPI模式 在指定地址开始读取指定长度的数据 65536 void W25QXXRead(uint32_t addr, uint8_t *buffer, uint16_t length) {QSPISendCMD(W25QXX_FAST_READ_DATA, addr, 8, QSPI_INSTRUCTION_4_LINES, QSPI_ADDRESS_4_LINES, QSPI_ADDRESS_32_BITS, QSPI_DATA_4_LINES); // QPI,快速读数据,地址为ReadAddr,4线传输数据_32位地址_4线传输地址_4线传输指令,8空周期,length个数据QSPIReceive(buffer, length); } 也可以使用SPI操作W25QXX。
http://www.yutouwan.com/news/433774/

相关文章:

  • 阿里巴巴的网站应该怎么做网站开发 培训 周末班
  • html5手机网站模板外包兼职做图的网站
  • 滕州网站开发vi设计流程
  • vs215开发python网站开发报价单模板电子版下载
  • 在自己的电脑做网站空间dw做的网站不显示
  • 网站开发文档需求撰写word合肥重点工程建设局
  • 三桥做网站建设工商联网站的意义
  • 重庆招生院校网站百度推广广告公司
  • 中国诚乡建设部网站寮步镇网站建设公司
  • 做影视网站赚钱零基础学wordpress教学PPT
  • 企业网站404页面设计做微信网站多少钱
  • 栏目手机版 企业网站公司概况简介
  • 合肥网站建设怎么样修改不能编辑的wordpress
  • 网站开发太简单了框架晋中北京网站建设
  • 网站建设与推广员岗位职责WordPress多人聊天插件
  • 一个网站一年的费用多少wordpress+v4.1
  • 网站关键词和网页关键词的样本vs 2010 网站建设
  • 医疗知识普及网站开发海珠网站建设报价
  • 购物网站建设推进表黄页网络的推广网站有哪些软件
  • 上海网站建设规划电子商务网站建设预算
  • 三门峡做网站推广四川公共资源交易信息网
  • 手机网站和电脑网站的区别免费高清无专码区
  • 北京网站建设 shwl装修设计网站排行榜
  • 北京模板网站建站网页制作公司设计理念
  • 如何做网站源码做网站时怎么裁切存图
  • 使用织梦系统建设网站教程seo技术最新黑帽
  • 即时设计网站带会员注册企业网站源码
  • 新城区网站建设wordpress主页与文章页
  • 旅游网站系统的设计与实现青海省住房建设厅网站
  • 唯品会 一家专门做特卖的网站手机版wordpress新奇插件