狮城app更多网站重庆网站建设的价格低

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

狮城app更多网站,重庆网站建设的价格低,做网站视频下载,宜宾金农投资建设集团网站1、硬件电路 需要系统性的看一下W25Q256芯片手册 2、设置RCC#xff0c;选择高速外部时钟HSE,时钟设置为180MHz 3、配置SPI 4、生成工程配置 5、相关代码 #define sFLASH_ID 0XEF4019 // W25Q256#define SPI_FLASH_PageSize 256 #define SPI_FLASH_PerWritePageSize 256#def…1、硬件电路 需要系统性的看一下W25Q256芯片手册  2、设置RCC选择高速外部时钟HSE,时钟设置为180MHz 3、配置SPI 4、生成工程配置 5、相关代码 #define sFLASH_ID 0XEF4019 // W25Q256#define SPI_FLASH_PageSize 256 #define SPI_FLASH_PerWritePageSize 256#define W25Q256_WriteEnable 0x06 // 写使能指令 #define W25Q256_WriteDisable 0x04 // 写屏蔽指令 #define W25Q256_ReadStatusReg 0x05 // 读取状态寄存器1 #define W25Q256_WriteStatusReg 0x01 // 写入状态寄存器1 //#define W25Q256_ReadData 0x03 // 3字节模式读取数据指令 #define W25Q256_ReadData 0x13 // 4字节模式读取数据指令 #define W25Q256_FastReadData 0x0B // #define W25Q256_FastReadDual 0x3B #define W25Q256_PageProgram 0x02 // 页写入指令 #define W25Q256_BlockErase 0xD8 #define W25Q256_SectorErase 0x20 #define W25Q256_ChipErase 0xC7 #define W25Q256_PowerDown 0xB9 #define W25Q256_ReleasePowerDown 0xAB #define W25Q256_DeviceID 0xAB #define W25Q256_ManufactDeviceID 0x90 #define W25Q256_JedecDeviceID 0x9F #define W25Q256_Enter4ByteMode 0xB7 // 4字节地址模式指令 #define W25Q256_ReadStatusRegister3 0x15 #define W25Q256_WriteStatusRegister3 0x11 //写状态寄存器3指令 #define WIP_Flag 0x01 #define Dummy_Byte 0xFF#define FLASH_WriteAddress 0x00000 #define FLASH_ReadAddress FLASH_WriteAddress #define FLASH_SectorToErase FLASH_WriteAddress/* 获取缓冲区的长度 / #define TxBufferSize1 (countof(TxBuffer1) - 1) #define RxBufferSize1 (countof(TxBuffer1) - 1) #define countof(a) (sizeof(a) / sizeof((a))) #define BufferSize (countof(Tx_Buffer) - 1)#define FLASH_WriteAddress 0x00000 #define FLASH_ReadAddress FLASH_WriteAddress #define FLASH_SectorToErase FLASH_WriteAddress/* 发送缓冲区初始化 / extern uint8_t ReadBuff[4096]; extern uint8_t WriteBuff[4096]; /** brief 拉低片选线* param 无* retval 无/ void SPI_FLASH_NSS_LOW(void) {HAL_GPIO_WritePin(SPI5_NSS_GPIO_Port, SPI5_NSS_Pin, GPIO_PIN_RESET); }/** brief 拉高片选线* param 无* retval 无/ void SPI_FLASH_NSS_HIGH(void) {HAL_GPIO_WritePin(SPI5_NSS_GPIO_Port, SPI5_NSS_Pin, GPIO_PIN_SET); }/** brief 获取 FLASH ID* param 无* retval FLASH ID/ uint32_t SPI_FLASH_ReadID(void) {uint32_t temp 0;uint32_t temp0 0;uint32_t temp1 0;uint32_t temp2 0;// 拉低片选线开始通信SPI_FLASH_NSS_LOW();// 发送获取W25Q256芯片ID指令SPI_FLASH_SendByte(W25Q256_JedecDeviceID);// 接收数据temp0 SPI_FLASH_ReadByte();temp1 SPI_FLASH_ReadByte();temp2 SPI_FLASH_ReadByte();// 拉高片选线结束通信SPI_FLASH_NSS_HIGH();temp temp0 16 | temp1 8 | temp2;return temp; }/** brief 发送一个字节* param 无* retval 无/ void SPI_FLASH_SendByte(uint8_t ch) {HAL_SPI_Transmit(hspi5, ch, 1, 500); }/** brief 发送n个字节* param pData发送数据首地址* param data_number发送数据个数以字节为单位* retval 无*/ void SPI_FLASH_SendnByte(uint8_t pData, uint32_t data_number) {HAL_SPI_Transmit(hspi5, pData, data_number, 500); }/** brief 接收一个字节* param 无* retval 接收的数据/ uint8_t SPI_FLASH_ReadByte(void) {uint8_t rxData 0;HAL_SPI_Receive(hspi5, rxData, 1, 500);return rxData; }/** brief 接收n个字节* param pData接收数据首地址* param data_number接收数据个数以字节为单位* retval 无*/ void SPI_FLASH_ReadnByte(uint8_t pData, uint32_t data_number) {HAL_SPI_Receive(hspi5, pData, data_number, 500); }/** brief 使能写命令* param 无* param 无* retval 无/ void SPI_FLASH_WriteEnable(void) {// 拉低片选线开始通信SPI_FLASH_NSS_LOW();// 发送写使能指令SPI_FLASH_SendByte(W25Q256_WriteEnable);// 拉高片选线结束通信SPI_FLASH_NSS_HIGH(); }/** brief 等待写入、擦除等操作完成* param 无* param 无* retval 无/ void SPI_FLASH_WaitForWriteEnd(void) {uint8_t FLASH_Status 0;// 拉低片选线开始通信SPI_FLASH_NSS_LOW();// 发送写状态寄存器1指令SPI_FLASH_SendByte(W25Q256_ReadStatusReg);do{// 获取写状态寄存器1的值并做判断。0空闲、1忙碌FLASH_Status SPI_FLASH_ReadByte();} while (SET (FLASH_Status WIP_Flag));// 拉高片选线结束通信SPI_FLASH_NSS_HIGH(); }/** brief 擦除扇区* param SectorAddr擦除扇区首地址* retval 无/ void SPI_FLASH_SectorErase(uint32_t SectorAddr) {// uint8_t ADDR[4] {0x00,0x00,0x00,0x00};// 使能写命令SPI_FLASH_WriteEnable();// 拉低片选线开始通信SPI_FLASH_NSS_LOW();// 发送擦除扇区命令SPI_FLASH_SendByte(W25Q256_SectorErase);// 发送擦除地址24 ~ 31bitSPI_FLASH_SendByte((SectorAddr 0xFF000000) 24);// 发送擦除地址16 ~ 23bitSPI_FLASH_SendByte((SectorAddr 0xFF0000) 16);// 发送擦除地址8 ~ 15bitSPI_FLASH_SendByte((SectorAddr 0xFF00) 8);// 发送擦除地址0 ~ 7bitSPI_FLASH_SendByte(SectorAddr 0xFF);// 拉高片选线结束通信SPI_FLASH_NSS_HIGH();// HAL_Delay(3000);// 等待擦除操作结束SPI_FLASH_WaitForOperaEnd(); }/** brief 配置4字节模式* param 无* retval 无/ void SPI_FLASH_FOUR_MODE(void) {uint8_t temp 0;// 使能写命令SPI_FLASH_WriteEnable();// 拉低片选线开始通信SPI_FLASH_NSS_LOW();// 发送写状态寄存器3命令SPI_FLASH_SendByte(W25Q256_WriteStatusRegister3);// 发送要写的数据SPI_FLASH_SendByte(0x02);// 拉高片选线结束通信SPI_FLASH_NSS_HIGH();// 拉低片选线开始通信SPI_FLASH_NSS_LOW();// 发送读状态寄存器3命令SPI_FLASH_SendByte(W25Q256_ReadStatusRegister3);// 读取数据temp SPI_FLASH_ReadByte();// 拉高片选线结束通信SPI_FLASH_NSS_HIGH();if (1 (0x02 temp)){// 拉低片选线开始通信SPI_FLASH_NSS_LOW();// 发送配置四字节模式指令SPI_FLASH_SendByte(W25Q256_Enter4ByteMode);// 拉高片选线结束通信SPI_FLASH_NSS_HIGH();}SPI_FLASH_WaitForOperaEnd(); }/** brief 对 FLASH 按页写入数据调用本函数写入数据前需要先擦除扇区* param pBuffer要写入数据的指针* param WriteAddr写入数据地址* param NumByteToWrite写入数据长度。必须小于等于SPI_FLASH_PerWritePageSize* retval 无*/ void SPI_FLASH_PageWrite(uint8_t pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) {// 使能写命令SPI_FLASH_WriteEnable();// 拉低片选线开始通信SPI_FLASH_NSS_LOW();// 发送页写入指令SPI_FLASH_SendByte(W25Q256_PageProgram);// 发送写入地址[24,31]bitSPI_FLASH_SendByte((WriteAddr 0xFF000000) 24);// 发送写入地址[16,23]bitSPI_FLASH_SendByte((WriteAddr 0xFF0000) 16);// 发送写入地址[8,15]bitSPI_FLASH_SendByte((WriteAddr 0xFF00) 8);// 发送写入地址[0,7]bitSPI_FLASH_SendByte(WriteAddr 0xFF);if (NumByteToWrite SPI_FLASH_PerWritePageSize){NumByteToWrite SPI_FLASH_PerWritePageSize;printf(256\r\n);}for (int i 0; i NumByteToWrite; i){SPI_FLASH_SendByte(pBuffer[i]);}// 拉高片选线结束通信SPI_FLASH_NSS_HIGH(); }/** brief FALSH不定量数据写入函数调用本函数写入数据前需要先擦除扇区* param pBuffer要写入数据的指针* param WriteAddr写入数据地址* param NumByteToWrite写入数据长度* retval 无*/ void SPI_FLASH_BufferWrite(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) {uint8_t NumOfPage 0;uint8_t NumOfSingle 0;uint8_t Addr 0;uint8_t count 0;uint8_t temp 0;/mod 运算求余若 writeAddr 是 SPI_FLASH_PageSize 整数倍运算结果 Addr 值为0/Addr WriteAddr % SPI_FLASH_PageSize;/* 差 count 个数据值刚好可以对齐到页地址 /count SPI_FLASH_PageSize - Addr;/ 计算出要写多少整数页 */NumOfPage NumByteToWrite / SPI_FLASH_PageSize;/*mod 运算求余计算出剩余不满一页的字节数 /NumOfSingle NumByteToWrite % SPI_FLASH_PageSize;/ Addr0, 则 WriteAddr 刚好按页对齐 aligned */if (0 Addr){/NumByteToWrite SPI_FLASH_PageSize/if (0 NumOfPage){SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成}else{/* 先把整数页都写了 /for (int i 0; i NumOfPage; i){SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成WriteAddr SPI_FLASH_PageSize;pBuffer SPI_FLASH_PageSize;}/ 若有多余的不满一页的数据把它写完 /SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成}}else / 若地址与 SPI_FLASH_PageSize 不对齐 */{/NumByteToWrite SPI_FLASH_PageSize/if (0 NumOfPage){/* 当前页剩余的 count 个位置比 NumOfSingle 小写不完 /if (NumOfSingle count){temp NumOfSingle - count;/ 先写满当前页 /SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成WriteAddr count;pBuffer count;/ 再写剩余的数据 /SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成}else / 当前页剩余的 count 个位置能写完 NumOfSingle 个数据 */{SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成}}else /NumByteToWrite SPI_FLASH_PageSize/{/先把距离页地址的count个数据减去计算需要写的页数和NumOfSingle然后写数据时先把原来减去的count个数据写入写满当前页//再写剩余数据即计算好的NumOfPage和NumOfSingle/NumByteToWrite - count;NumOfPage NumByteToWrite / SPI_FLASH_PageSize;NumOfSingle NumByteToWrite % SPI_FLASH_PageSize;SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成WriteAddr count;pBuffer count;/* 把整数页都写了 /for (int i 0; i NumOfPage; i){SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成WriteAddr SPI_FLASH_PageSize;pBuffer SPI_FLASH_PageSize;}if (0 ! NumOfSingle){SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成}}} }/** brief 读取FLASH数据* param pBuffer存储读出数据的指针* param WriteAddr读取地址* param NumByteToRead读取数据长度* retval 无*/ void SPI_FLASH_BufferRead(uint8_t pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead) {// 拉低片选线开始通信SPI_FLASH_NSS_LOW();// 发送读取数据指令SPI_FLASH_SendByte(W25Q256_ReadData);// 发送读取地址[24,31]bitSPI_FLASH_SendByte((ReadAddr 0xFF000000) 24);// 发送读取地址[16,23]bitSPI_FLASH_SendByte((ReadAddr 0xFF0000) 16);// 发送读取地址[8,15]bitSPI_FLASH_SendByte((ReadAddr 0xFF00) 8);// 发送读取地址[0,7]bitSPI_FLASH_SendByte(ReadAddr 0xFF);// 读取数据for (int i 0; i NumByteToRead; i){// 读取一个字节数据pBuffer[i] SPI_FLASH_ReadByte();}// 拉高片选线结束通信SPI_FLASH_NSS_HIGH();SPI_FLASH_WaitForOperaEnd(); // 等待操作完成 }/** brief 等待写入、擦除等操作结束* param none* param none* param none* retval none/ void SPI_FLASH_WaitForOperaEnd(void) {uint8_t FLASH_Status 0;// 拉低片选线开始通信SPI_FLASH_NSS_LOW();// 发送读状态寄存器1指令SPI_FLASH_SendByte(W25Q256_ReadStatusReg);do{// 接收读取状态寄存器1寄存器内容FLASH_Status SPI_FLASH_ReadByte();} while (SET (FLASH_Status WIP_Flag));// 拉高片选线结束通信SPI_FLASH_NSS_HIGH(); } int main(void) {/ USER CODE BEGIN 1 // USER CODE END 1 // MCU Configuration——————————————————–// Reset of all peripherals, Initializes the Flash interface and the Systick. /HAL_Init();/ USER CODE BEGIN Init // USER CODE END Init // Configure the system clock /SystemClock_Config();/ USER CODE BEGIN SysInit // USER CODE END SysInit // Initialize all configured peripherals /MX_GPIO_Init();MX_SPI5_Init();MX_USART1_UART_Init();/ USER CODE BEGIN 2 */// 进入4字节地址模式SPI_FLASH_FOUR_MODE();printf(W25Q256 SPI readwrite test!!!\r\n);device_ID SPI_FLASH_ReadID();printf(device_ID 0x%x\r\n, device_ID);SPI_FLASH_SectorErase(0x00); // 擦除扇区数据// 读取擦除后的数据SPI_FLASH_BufferRead(ReadBuff, 0x00, 4096);printf(**************读取擦出后的数据***********\r\n);for (int i 0; i 4096; i){printf(ReadBuff[%d] 0x%02x\t, i, ReadBuff[i]);if (0 (i 1) % 8 (i 1) 8){printf(\r\n);}}for (int i 0; i 256; i){WriteBuff[i] i;}SPI_FLASH_BufferWrite(WriteBuff, 0xFF, 256);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成// 读数据SPI_FLASH_BufferRead(ReadBuff, 0xFF, 256);SPI_FLASH_WaitForOperaEnd(); // 等待操作完成printf(***********读取写入后的数据*************\r\n);for (int i 0; i 256; i){printf(ReadBuff[%d] 0x%02x\t, i, ReadBuff[i]);if (0 (i 1) % 8 (i 1) 8){printf(\r\n);}}/ USER CODE END 2 // Infinite loop // USER CODE BEGIN WHILE /while (1){/ USER CODE END WHILE // USER CODE BEGIN 3 /LED_TIME();}/ USER CODE END 3 */ } 6、实验现象