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

网站建设需要什么人才某一个网页打不开是什么原因

网站建设需要什么人才,某一个网页打不开是什么原因,保定 网站制作,营销策略有哪些方法SPISPI介绍SPI是串行外设接口(Serial Peripherallnterface)的缩写#xff0c;是一种高速的#xff0c;全双工#xff0c;同步的通信总线#xff0c;并且在芯片的管脚上只占用四根线#xff0c;节约了芯片的管脚#xff0c;同时为PCB的布局上节省空间#xff0c;提供方便…SPISPI介绍SPI是串行外设接口(Serial Peripherallnterface)的缩写是一种高速的全双工同步的通信总线并且在芯片的管脚上只占用四根线节约了芯片的管脚同时为PCB的布局上节省空间提供方便正是出于这种简单易用的特性越来越多的芯片集成了这种通信协议比如AT91RM9200。SPI物理架构SPI总线包含四条总线分别是SCK、MOSI、MISO、NSSCS。MISO主设备输入/从设备输出引脚。该引脚在从模式下发送数据在主模式下接收数据。MOSl主设备输出/从设备输入引脚。该引脚在主模式下发送数据在从模式下接收数据。SCK串口时钟作为主设备的输出从设备的输入。NSSCS 由主设备控制用来选择指定的从设备进行通信。当主设备想要读/写从设备时它首先拉低从设备对应的NSS线SPI工作原理SPI主从模式SPI分为主、从两种模式一个SPI通讯系统需要包含一个且只能是一个主设备一个或多个从设备。提供时钟的为主设备Master接收时钟的设备为从设备SlaveSPI接口的读写操作都是由主设备发起。当存在多个从设备时主设备通过从设备各自的片选信号NSS来选择从设备。SPI主、从设备通讯接线一个主设备和一个从设备一个主设备和多个从设备SPI数据传输SPI主设备和从设备都有一个移位寄存器主机可以通过向它的移位寄存器写入数据来发起一次SPI通讯。主设备拉低对应从设备的NSS信号线。选择从设备进行通信主设备发送时钟信号从设备接收时钟信号。告诉从设备开始进行SPI通讯数据交换主设备(Master)将要发送的数据传输到发送缓存区(Menory)当从设备收到主设备发送的时钟信号并且在MOSI引脚上出现第一个数据位时发送过程开始。余下的位被装进移位寄存器通过MOSI信号线将字节一位一位的发送给从设备。同时主设备通过MISO引脚将数据一位一位的接收到移位寄存器当数据接收完成时将数据传输到接收缓冲区。从设备同理将自己发送缓冲区的数据通过移位寄存器和MISO一位一位发送给主设备同时通过MOSI引脚将数据一位一位的接收到移位寄存器当数据接收完成时将数据传输到接收缓冲区。SPI只有主模式和从模式之分没有读和写的说法数据的写操作和读操作是同步完成的。如果只进行写操作主机只需忽略接收到的字节如果只进行读操作只需发送一个空字节来获取SPI通讯的一个字节。SPI工作模式时钟极性CPOL控制在没有数据传输时时钟线的空闲状态电平。0SCK在空闲状态保持低电平。1SCK在空闲状态保持高电平。时钟相位CPHA时钟线在第几个时钟边沿采样信号。0SCK的第一个奇数边沿进行数据位采样数据在第一个时钟边沿被锁存。1SCK的第二个偶数边沿进行数据位采样数据在第二个时钟边沿被锁存。SPI模式SPI模式CPOLCPHA空闲时SCK时钟采样时刻模式000低电平奇数边沿模式101低电平偶数边沿模式210高电平奇数边沿模式311高电平偶数边沿模式0常用CPOL 0CPHA 0空闲时SCK时钟为低电平采样时刻为第一个边沿即上升沿。如图所示黄线进行采样模式1CPOL 0CPHA 1空闲时SCK时钟为低电平采样时刻为第二个边沿即下降沿。如图所示黄线进行采样。模式2CPOL 1CPHA 0空闲时SCK时钟为高电平采样时刻为第一个边沿即下降沿。如图所示黄线进行采样。模式3常用CPOL 1CPHA 1空闲时SCK时钟为高电平采样时刻为第二个边沿即上升沿。如图所示黄线进行采样。W25Q128W25Q128介绍W25Q128是华邦公司推出的一款SPI接口的NOR FIash芯片其存储空间为128 Mbit相当于16M字节。Flash 是常用的用于储存数据的半导体器件它具有容量大可重复擦写、按”扇区/块”擦除、掉电后数据可继续保存的特性。Flash 是有一个物理特性只能写0不能写1靠擦除来写1。W25Q128存储架构一个W25Q128 256个块 256 * 16个扇区 256 * 16 *16个页 256 * 16 * 16 * 256个字节即16777216字节约16M字节即寻址范围为0x00 ~ 0xFFFFFF。16777216 -1 0xFFFFFF。对Flash擦除时一般按扇区4K 4096字节来进行擦除。W25Q128状态寄存器W25Q128一共有3个状态寄存器它们的作用时跟踪芯片的状态。其中状态寄存器1比较常用。BUSY位BUSY是状态寄存器中的只读位当设备执行页程序、四页程序、扇区擦除、块擦除、芯片擦除、写状态寄存器或擦除/程序安全寄存器指令时将其设置为1状态。 在此期间器件将忽略除读取状态寄存器和擦除/程序挂起指令之外的其他指令。 当编程、擦除或写入状态/安全寄存器指令完成时忙位将被清除为0状态表示设备已准备好接受进一步的指令。0空闲1忙WEL位WEL是状态寄存器(S1)中的只读位在执行写使能指令后被设置为1。 当设备被禁止写入时WEL状态位被清除为0。 在上电时或在下列任何指令之后发生写禁用状态写禁用、页程序、四页程序、扇区擦除、块擦除、芯片擦除、写状态寄存器、擦除安全寄存器和程序安全寄存器。1可以操作页、扇区、块0禁止写入W25Q128常用指令W25Q128有非常多的指令在这里介绍几个常用的指令。指令名称作用0x06写使能写使能指令将状态寄存器中的WEL位设置为10x05读SR1读取状态寄存器指令允许读取8位状态寄存器的值0x03读数据读取数据指令允许从存储器顺序读取一个或多个数据字节0x02页写页写指令允许在指定地址写入小于256字节的指定长度的数据在非0xFF处写入的数据会失败0x20扇区擦除扇区擦除指令将指定扇区4K字节内的所有数据都擦除为0xFF。0xC7芯片擦除芯片擦除指令将W25Q128的所有数据都擦除为0xFF。0x90读取芯片ID读取制造商/设备ID指令。写使能0x06写使能指令将状态寄存器中的WEL位设置为1。 必须在每个页写、扇区擦除、块擦除、芯片擦除和写状态寄存器指令之前进行写使能。操作拉低CS片选-发送指令0x06 -拉高CS片选读SR10x05读取状态寄存器指令允许读取8位状态寄存器的值。操作拉低CS片选 -发送指令0x05 -定义一个uint8_t数据接收SR1的返回值 -拉高CS片选读数据0x03读取数据指令允许从存储器顺序读取一个或多个数据字节。 操作拉低CS片选 - 发送指令0x03 - 发送24位地址 - 读取数据 - 拉高CS片选页写0x02页写指令允许在指定地址写入小于256字节的指定长度的数据在非0xFF处写入的数据会失败。操作写使能 - 拉低CS片选 - 发送指令0x02 - 发送24位地址 - 写入数据 - 拉高CS片选 - 等待写入结束即判断状态寄存器的BUSY位是否置0扇区擦除0x20扇区擦除指令将指定扇区4K字节内的所有数据都擦除为0xFF。操作写使能 - 等待空闲即判断状态寄存器的BUSY位是否置0 - 拉低CS片选 - 发送指令0x20 - 发送24位地址 - 拉高CS片选 - 等待扇区擦除完成即判断状态寄存器的BUSY位是否置0芯片擦除0xC7芯片擦除指令将W25Q128的所有数据都擦除为0xFF。操作写使能 - 等待空闲即判断状态寄存器的BUSY位是否置0 - 拉低CS片选 - 发送指令0xC7 - 拉高CS片选 - 等待芯片擦除完成即判断状态寄存器的BUSY位是否置0读取W25Q128的芯片ID0x90读取制造商/设备ID指令。操作拉低片选信号 - 发送24位地址地址为0xFFFFFF - 定义一个uint16_t数据接收芯片ID - 拉高片选信号SPI实验使用SPI通讯读写W25Q128模块STM32的hal库关于SPI的函数HAL_SPI_TransmitReceive()通过SPI以阻塞模式发送和接收数据。原型HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,uint32_t Timeout)参数SPI_HandleTypeDef *hspiSPI句柄uint8_t *pTxData发送的数据地址uint8_t *pRxData接收的数据地址uint16_t Size发送和接收的数据数量uint32_t Timeout超时时间超过这个时间不再发送和接收实例uint8_t spi1_read_write_byte(uint8_t data) { uint8_t rec_data 0; HAL_SPI_TransmitReceive(hspi1, data, rec_data, 1, 1000); return rec_data; }W25Q128与STM32F103C8T6板子接线在STM32F103C8T6的产品手册中找到板子上的SPI1的接口PA4作为SPI1的NSSPA5作为SPI1的CLKPA6作为SPI1的DOMISOPA7作为SPI1的DIMOSI。3.3V - VCCGND - GNDPA4 - CSPA5 - CLKPA6 - DOMISOPA7 - DIMOSISTM32CubeMX相关配置配置SYS配置RCC配置GPIO配置PA4为输出高电平用来作为SPI主机的片选信号线CS。配置串口信息UART1配置SPILSB全称为Least Significant Bit在二进制数中意为最低有效位一般来说MSB位于二进制数的最左侧LSB位于二进制数的最右侧。MSB全称为Most Significant Bit在二进制数中属于最高有效位MSB是最高加权位与十进制数字中最左边的一位类似。配置工程名称、工程路径选择固件库生成工程使用MicroLIB库main.c文件编写/* USER CODE BEGIN Header */ /********************************************************************************* file : main.c* brief : Main program body******************************************************************************* attention** Copyright (c) 2023 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include main.h #include spi.h #include usart.h #include gpio.h/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */#include stdio.h #include string.h #include w25q128.h/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */#define TEXT_SIZE 16 #define FLASH_WriteAddress 0x000000 //数据写入w25q128的地址地址范围为0x000000 ~ 0xFFFFFF #define FLASH_ReadAddress FLASH_WriteAddress/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 *///重写stdio.h文件中的prinft()里的fputc()函数 int fputc(int my_data,FILE *p) {unsigned char temp my_data;//改写后使用printf()函数会将数据通过串口一发送出去HAL_UART_Transmit(huart1,temp,1,0xffff); //0xfffff为最大超时时间return my_data; }/* USER CODE END 0 *//*** brief The application entry point.* retval int*/ int main(void) {/* USER CODE BEGIN 1 */uint8_t datatemp[TEXT_SIZE];/* 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_USART1_UART_Init();MX_SPI1_Init();/* USER CODE BEGIN 2 *//* w25q128初始化 */w25q128_init();/* 写入测试数据 */sprintf((char *)datatemp, hello jiangxiao);w25q128_write(datatemp, FLASH_WriteAddress, TEXT_SIZE);printf(数据写入完成\r\n);/* 读出测试数据 */memset(datatemp, 0, TEXT_SIZE);w25q128_read(datatemp, FLASH_ReadAddress, TEXT_SIZE);printf(读出数据%s\r\n, datatemp);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */ }/*** brief System Clock Configuration* retval None*/ void SystemClock_Config(void) {RCC_OscInitTypeDef RCC_OscInitStruct {0};RCC_ClkInitTypeDef RCC_ClkInitStruct {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL RCC_PLL_MUL9;if (HAL_RCC_OscConfig(RCC_OscInitStruct) ! HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_2) ! HAL_OK){Error_Handler();} }/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** brief This function is executed in case of error occurrence.* retval None*/ void Error_Handler(void) {/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */ }#ifdef USE_FULL_ASSERT /*** brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* param file: pointer to the source file name* param line: assert_param error line source number* retval None*/ void assert_failed(uint8_t *file, uint32_t line) {/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf(Wrong parameters value: file %s on line %d\r\n, file, line) *//* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ w25q128.c文件编写向工程添加w25q128.c文件。#include w25q128.h #include spi.h #include stdio.h//w25q128初始化 void w25q128_init(void) {uint16_t flash_type;spi1_read_write_byte(0xFF); /* 清除DR数据寄存器,写入一个0xFF */W25Q128_CS(1); //拉高片选信号不进行SPI通信flash_type w25q128_read_id(); /* 读取FLASH ID. */if (flash_type W25Q128){printf(检测到W25Q128芯片\r\n);} }//等待W25Q128空闲 static void w25q128_wait_busy(void) {while ((w25q128_rd_sr1() 0x01) 1); /* 等待状态寄存器的BUSY位清空 */ }//读取状态寄存器的值 uint8_t w25q128_rd_sr1(void) {uint8_t rec_data 0;W25Q128_CS(0);spi1_read_write_byte(FLASH_ReadStatusReg1); // 写入指令0x05读状态寄存器1rec_data spi1_read_write_byte(0xFF); //获取状态寄存器1的值W25Q128_CS(1);return rec_data; }//W25Q128写使能,即置位WEL为1 void w25q128_write_enable(void) {W25Q128_CS(0);spi1_read_write_byte(FLASH_WriteEnable); /* 发送指令0x06写使能 */W25Q128_CS(1); }//发送24位地址 static void w25q128_send_address(uint32_t address) /*address地址范围0~16777215字节即寻址范围为0x00 ~ 0xFFFFFF */ {spi1_read_write_byte((uint8_t)((address)16)); /* 发送 bit23 ~ bit16 地址 */spi1_read_write_byte((uint8_t)((address)8)); /* 发送 bit15 ~ bit8 地址 */spi1_read_write_byte((uint8_t)address); /* 发送 bit7 ~ bit0 地址 */ }//擦除整个芯片 void w25q128_erase_chip(void) {w25q128_write_enable(); /* 写使能 */w25q128_wait_busy(); /* 等待空闲 */W25Q128_CS(0);spi1_read_write_byte(FLASH_ChipErase); /* 发送指令0xC7擦除整个芯片 */ W25Q128_CS(1);w25q128_wait_busy(); /* 等待芯片擦除结束 */ }//擦除一个扇区 void w25q128_erase_sector(uint32_t saddr) /* saddr该参数是第几个扇区 */ {saddr * 4096; /* 一个扇区大小为4096字节 */w25q128_write_enable(); /* 写使能 */w25q128_wait_busy(); /* 等待空闲 */W25Q128_CS(0);spi1_read_write_byte(FLASH_SectorErase); /* 发送指令0x20擦除指定扇区 */w25q128_send_address(saddr); /* 发送擦除的扇区地址 */W25Q128_CS(1);w25q128_wait_busy(); /* 等待扇区擦除完成 */ }//读取w25q128芯片ID uint16_t w25q128_read_id(void) {uint16_t deviceid;W25Q128_CS(0); //拉低片选信号进行SPI通信spi1_read_write_byte(FLASH_ManufactDeviceID); /* 发送读取 ID 命令 *//* 发送3个0 *//*spi1_read_write_byte(0); spi1_read_write_byte(0);spi1_read_write_byte(0);*/w25q128_send_address(0x000000);deviceid spi1_read_write_byte(0xFF) 8; /* 读取高8位字节 */deviceid | spi1_read_write_byte(0xFF); /* 读取低8位字节 */W25Q128_CS(1);return deviceid; }/* 读取W25Q128的FLASH在指定地址开始读取指定长度的数据pubf需要读取的数据 addr指定的地址 datalen指定的数据大小 */ void w25q128_read(uint8_t *pbuf, uint32_t addr, uint16_t datalen) {uint16_t i;W25Q128_CS(0);spi1_read_write_byte(FLASH_ReadData); /* 发送指令0x03读取数据 */w25q128_send_address(addr); /* 发送需要读取的数据地址 */for(i0;idatalen;i){pbuf[i] spi1_read_write_byte(0XFF); /* 循环读取 */}W25Q128_CS(1); }/* 单页写在指定地址写入小于256字节的指定长度的数据在非0xFF处写入的数据会失败pubf需要写入的数据 addr指定的地址 datalen指定的数据大小 */ static void w25q128_write_page(uint8_t *pbuf, uint32_t addr, uint16_t datalen) {uint16_t i;w25q128_write_enable(); /* 写使能 */W25Q128_CS(0);spi1_read_write_byte(FLASH_PageProgram); /* 发送命令0x02页写 */w25q128_send_address(addr); /* 发送写入的页地址 */for(i0;idatalen;i){spi1_read_write_byte(pbuf[i]); /* 循环写入 */}W25Q128_CS(1);w25q128_wait_busy(); /* 等待写入结束 */ }/* 多页写在指定地址写入指定长度的数据在非0xFF处写入的数据会失败pubf需要写入的数据 addr指定的地址 datalen指定的数据大小 */ static void w25q128_write_nocheck(uint8_t *pbuf, uint32_t addr, uint16_t datalen) {uint16_t pageremain;pageremain 256 - addr % 256; /* 获取指定地址那页的剩余字节数 */if (datalen pageremain) /* 指定地址那页的剩余字节数能装下指定数据大小 */{pageremain datalen; }while (1){ /* 当指定地址那页的剩余字节数能装下指定数据大小时,一次性写完 *//* 当指定数据大小比指定地址那页的剩余字节数要大时, 先写完指定地址那页的剩余字节, 然后根据剩余数据大小进行不同处理 */w25q128_write_page(pbuf, addr, pageremain); //页写if (datalen pageremain) /* 写入结束了 */{break; }else /* datalen pageremain */{pbuf pageremain; /* pbuf指针地址偏移,前面已经写了pageremain字节 */addr pageremain; /* 写地址偏移,前面已经写了pageremain字节 */datalen - pageremain; /* 写入总长度减去已经写入了的字节数 */if (datalen 256) /* 剩余数据大小还大于一页 */{pageremain 256; /* 一次写入256个字节即一次写一页 */}else /* 剩余数据大小小于一页 */{pageremain datalen; /* 一次性写完 */}}} }/* //写入W25Q128的FLASH在指定地址开写入取指定长度的数据pubf需要写入的数据 addr指定的地址 datalen指定的数据大小 */ uint8_t g_w25q128_buf[4096]; /* 扇区缓存 */void w25q128_write(uint8_t *pbuf, uint32_t addr, uint16_t datalen) {uint32_t secpos;uint16_t secoff;uint16_t secremain;uint16_t i;uint8_t *w25q128_buf;w25q128_buf g_w25q128_buf;secpos addr / 4096; /* 获取指定地址在哪片扇区 */secoff addr % 4096; /* 指定数据在在扇区内的偏移数据大小 */secremain 4096 - secoff; /* 扇区剩余字节数 */if (datalen secremain) /* 指定地址那片扇区的剩余字节数能装下指定数据大小 */{secremain datalen; }while (1){w25q128_read(w25q128_buf, secpos * 4096, 4096); /* 读出指定地址那片扇区的全部内容 */for (i 0; i secremain; i) /* 校验数据防止数据出现非0xFF */{if (w25q128_buf[secoff i] ! 0xFF) //扇区数据有一个数据不是0xFF{break; /* 需要擦除, 直接退出for循环 */}}if (i secremain) /* 需要擦除 */{w25q128_erase_sector(secpos); /* 擦除这个扇区 */for (i 0; i secremain; i) /* 复制 */{w25q128_buf[i secoff] pbuf[i];}w25q128_write_nocheck(w25q128_buf, secpos * 4096, 4096); /* 写入整个扇区 */}else /* 写已经擦除了的,直接写入扇区剩余区间. */{w25q128_write_nocheck(pbuf, addr, secremain); /* 直接写扇区 */}if (datalen secremain){break; /* 写入结束了 */}else /* 写入未结束 */{secpos; /* 扇区地址增1新的一个扇区 */secoff 0; /* 偏移位置为0 */pbuf secremain; /* 指针偏移 */addr secremain; /* 写地址偏移 */datalen - secremain; /* 字节数递减 */if (datalen 4096){secremain 4096; /* 一次写入一个扇区 */}else{secremain datalen;/* 一次性写完 */}}} }w25q128.h文件编写向工程添加w25q128.h文件。#include stdint.h/* W25Q128片选引脚定义 */ #define W25Q128_CS_GPIO_PORT GPIOA #define W25Q128_CS_GPIO_PIN GPIO_PIN_4/* W25Q128片选信号 */ #define W25Q128_CS(x) do{ x ? \HAL_GPIO_WritePin(W25Q128_CS_GPIO_PORT, W25Q128_CS_GPIO_PIN, GPIO_PIN_SET) : \HAL_GPIO_WritePin(W25Q128_CS_GPIO_PORT, W25Q128_CS_GPIO_PIN, GPIO_PIN_RESET); \}while(0)/* FLASH芯片列表 */ #define W25Q128 0XEF17 /* W25Q128 芯片ID *//* 指令表 */ #define FLASH_WriteEnable 0x06 #define FLASH_ReadStatusReg1 0x05 #define FLASH_ReadData 0x03 #define FLASH_PageProgram 0x02 #define FLASH_SectorErase 0x20 #define FLASH_ChipErase 0xC7 #define FLASH_ManufactDeviceID 0x90 /* 静态函数 */ static void w25q128_wait_busy(void); //等待W25Q128空闲 static void w25q128_send_address(uint32_t address); //发送24位地址 static void w25q128_write_page(uint8_t *pbuf, uint32_t addr, uint16_t datalen); //单页写在指定地址写入小于256字节的指定长度的数据在非0xFF处写入的数据会失败 static void w25q128_write_nocheck(uint8_t *pbuf, uint32_t addr, uint16_t datalen); //多页写在指定地址写入指定长度的数据在非0xFF处写入的数据会失败/* 普通函数 */ void w25q128_init(void); //w25q128初始化 uint16_t w25q128_read_id(void); //读取w25q128芯片ID void w25q128_write_enable(void); //W25Q128写使能,即置位WEL为1 uint8_t w25q128_rd_sr1(void); //读取状态寄存器的值 void w25q128_erase_chip(void); //擦除整个芯片 void w25q128_erase_sector(uint32_t saddr); //擦除一个扇区 void w25q128_read(uint8_t *pbuf, uint32_t addr, uint16_t datalen); //读取W25Q128的FLASH在指定地址开始读取指定长度的数据 void w25q128_write(uint8_t *pbuf, uint32_t addr, uint16_t datalen); //写入W25Q128的FLASH在指定地址开写入取指定长度的数据spi.c文件编写/* USER CODE BEGIN Header */ /********************************************************************************* file spi.c* brief This file provides code for the configuration* of the SPI instances.******************************************************************************* attention** Copyright (c) 2023 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include spi.h/* USER CODE BEGIN 0 *//* USER CODE END 0 */SPI_HandleTypeDef hspi1;/* SPI1 init function */ void MX_SPI1_Init(void) {/* USER CODE BEGIN SPI1_Init 0 *//* USER CODE END SPI1_Init 0 *//* USER CODE BEGIN SPI1_Init 1 *//* USER CODE END SPI1_Init 1 */hspi1.Instance SPI1;hspi1.Init.Mode SPI_MODE_MASTER;hspi1.Init.Direction SPI_DIRECTION_2LINES;hspi1.Init.DataSize SPI_DATASIZE_8BIT;hspi1.Init.CLKPolarity SPI_POLARITY_LOW;hspi1.Init.CLKPhase SPI_PHASE_1EDGE;hspi1.Init.NSS SPI_NSS_SOFT;hspi1.Init.BaudRatePrescaler SPI_BAUDRATEPRESCALER_256;hspi1.Init.FirstBit SPI_FIRSTBIT_MSB;hspi1.Init.TIMode SPI_TIMODE_DISABLE;hspi1.Init.CRCCalculation SPI_CRCCALCULATION_DISABLE;hspi1.Init.CRCPolynomial 10;if (HAL_SPI_Init(hspi1) ! HAL_OK){Error_Handler();}/* USER CODE BEGIN SPI1_Init 2 *//* USER CODE END SPI1_Init 2 */}void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) {GPIO_InitTypeDef GPIO_InitStruct {0};if(spiHandle-InstanceSPI1){/* USER CODE BEGIN SPI1_MspInit 0 *//* USER CODE END SPI1_MspInit 0 *//* SPI1 clock enable */__HAL_RCC_SPI1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/**SPI1 GPIO ConfigurationPA5 ------ SPI1_SCKPA6 ------ SPI1_MISOPA7 ------ SPI1_MOSI*/GPIO_InitStruct.Pin GPIO_PIN_5|GPIO_PIN_7;GPIO_InitStruct.Mode GPIO_MODE_AF_PP;GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA, GPIO_InitStruct);GPIO_InitStruct.Pin GPIO_PIN_6;GPIO_InitStruct.Mode GPIO_MODE_INPUT;GPIO_InitStruct.Pull GPIO_NOPULL;HAL_GPIO_Init(GPIOA, GPIO_InitStruct);/* USER CODE BEGIN SPI1_MspInit 1 *//* USER CODE END SPI1_MspInit 1 */} }void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle) {if(spiHandle-InstanceSPI1){/* USER CODE BEGIN SPI1_MspDeInit 0 *//* USER CODE END SPI1_MspDeInit 0 *//* Peripheral clock disable */__HAL_RCC_SPI1_CLK_DISABLE();/**SPI1 GPIO ConfigurationPA5 ------ SPI1_SCKPA6 ------ SPI1_MISOPA7 ------ SPI1_MOSI*/HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);/* USER CODE BEGIN SPI1_MspDeInit 1 *//* USER CODE END SPI1_MspDeInit 1 */} }/* USER CODE BEGIN 1 *//*通过SPI1同时读写一个字节数据 主机只向从机进行写操作调用此函数时忽略返回值 主机只向从机进行读操作调用此函数时随便传入一个字符尽量是0xFF */ uint8_t spi1_read_write_byte(uint8_t data) {uint8_t rec_data 0;HAL_SPI_TransmitReceive(hspi1, data, rec_data, 1, 1000); //spi读写数据函数参数2存放用来发送的数据参数3存放用来接收的数据return rec_data; }/* USER CODE END 1 */ spi.h文件编写/* USER CODE BEGIN Header */ /********************************************************************************* file spi.h* brief This file contains all the function prototypes for* the spi.c file******************************************************************************* attention** Copyright (c) 2023 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/ /* USER CODE END Header */ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __SPI_H__ #define __SPI_H__#ifdef __cplusplus extern C { #endif/* Includes ------------------------------------------------------------------*/ #include main.h/* USER CODE BEGIN Includes *//* USER CODE END Includes */extern SPI_HandleTypeDef hspi1;/* USER CODE BEGIN Private defines *//* USER CODE END Private defines */void MX_SPI1_Init(void);/* USER CODE BEGIN Prototypes */uint8_t spi1_read_write_byte(uint8_t data);/* USER CODE END Prototypes */#ifdef __cplusplus } #endif#endif /* __SPI_H__ */向STM32工程添加.c和.h文件在创建好的STM32工程中找到Core的文件夹向文件夹里添加新的xxx.c文件或xxx.h文件在keil5中导入工程后将这两个文件添加到工程列表中
文章转载自:
http://www.morning.dlhxj.cn.gov.cn.dlhxj.cn
http://www.morning.bdwqy.cn.gov.cn.bdwqy.cn
http://www.morning.kldtf.cn.gov.cn.kldtf.cn
http://www.morning.tslfz.cn.gov.cn.tslfz.cn
http://www.morning.bssjp.cn.gov.cn.bssjp.cn
http://www.morning.trlhc.cn.gov.cn.trlhc.cn
http://www.morning.bsghk.cn.gov.cn.bsghk.cn
http://www.morning.tpnxr.cn.gov.cn.tpnxr.cn
http://www.morning.gywxq.cn.gov.cn.gywxq.cn
http://www.morning.zzgkk.cn.gov.cn.zzgkk.cn
http://www.morning.gwqcr.cn.gov.cn.gwqcr.cn
http://www.morning.lmbm.cn.gov.cn.lmbm.cn
http://www.morning.dwgcx.cn.gov.cn.dwgcx.cn
http://www.morning.frqtc.cn.gov.cn.frqtc.cn
http://www.morning.brld.cn.gov.cn.brld.cn
http://www.morning.drcnn.cn.gov.cn.drcnn.cn
http://www.morning.qrsrs.cn.gov.cn.qrsrs.cn
http://www.morning.rpljf.cn.gov.cn.rpljf.cn
http://www.morning.bpmtg.cn.gov.cn.bpmtg.cn
http://www.morning.rhwty.cn.gov.cn.rhwty.cn
http://www.morning.0dirty.cn.gov.cn.0dirty.cn
http://www.morning.pigcamp.com.gov.cn.pigcamp.com
http://www.morning.dbfj.cn.gov.cn.dbfj.cn
http://www.morning.rqsr.cn.gov.cn.rqsr.cn
http://www.morning.clfct.cn.gov.cn.clfct.cn
http://www.morning.swkpq.cn.gov.cn.swkpq.cn
http://www.morning.ztfzm.cn.gov.cn.ztfzm.cn
http://www.morning.qnjcx.cn.gov.cn.qnjcx.cn
http://www.morning.qhkx.cn.gov.cn.qhkx.cn
http://www.morning.tqgmd.cn.gov.cn.tqgmd.cn
http://www.morning.hjbrd.cn.gov.cn.hjbrd.cn
http://www.morning.mnqg.cn.gov.cn.mnqg.cn
http://www.morning.dpgdj.cn.gov.cn.dpgdj.cn
http://www.morning.hnhsym.cn.gov.cn.hnhsym.cn
http://www.morning.rtlrz.cn.gov.cn.rtlrz.cn
http://www.morning.jcxyq.cn.gov.cn.jcxyq.cn
http://www.morning.xnpml.cn.gov.cn.xnpml.cn
http://www.morning.zlsmx.cn.gov.cn.zlsmx.cn
http://www.morning.qkxnw.cn.gov.cn.qkxnw.cn
http://www.morning.rxwnc.cn.gov.cn.rxwnc.cn
http://www.morning.zhnpj.cn.gov.cn.zhnpj.cn
http://www.morning.ntyks.cn.gov.cn.ntyks.cn
http://www.morning.gjqgz.cn.gov.cn.gjqgz.cn
http://www.morning.rnjgh.cn.gov.cn.rnjgh.cn
http://www.morning.dspqc.cn.gov.cn.dspqc.cn
http://www.morning.gqwpl.cn.gov.cn.gqwpl.cn
http://www.morning.kqxng.cn.gov.cn.kqxng.cn
http://www.morning.rmrcc.cn.gov.cn.rmrcc.cn
http://www.morning.bwqr.cn.gov.cn.bwqr.cn
http://www.morning.vehna.com.gov.cn.vehna.com
http://www.morning.zfcfk.cn.gov.cn.zfcfk.cn
http://www.morning.fksxs.cn.gov.cn.fksxs.cn
http://www.morning.mszls.cn.gov.cn.mszls.cn
http://www.morning.flmxl.cn.gov.cn.flmxl.cn
http://www.morning.trplf.cn.gov.cn.trplf.cn
http://www.morning.plqsz.cn.gov.cn.plqsz.cn
http://www.morning.qmwzz.cn.gov.cn.qmwzz.cn
http://www.morning.qtyfb.cn.gov.cn.qtyfb.cn
http://www.morning.npxht.cn.gov.cn.npxht.cn
http://www.morning.pdynk.cn.gov.cn.pdynk.cn
http://www.morning.kgqww.cn.gov.cn.kgqww.cn
http://www.morning.ysmw.cn.gov.cn.ysmw.cn
http://www.morning.rtpw.cn.gov.cn.rtpw.cn
http://www.morning.nfbkz.cn.gov.cn.nfbkz.cn
http://www.morning.pcxgj.cn.gov.cn.pcxgj.cn
http://www.morning.nmwgd.cn.gov.cn.nmwgd.cn
http://www.morning.fmdvbsa.cn.gov.cn.fmdvbsa.cn
http://www.morning.qnjcx.cn.gov.cn.qnjcx.cn
http://www.morning.hbqfh.cn.gov.cn.hbqfh.cn
http://www.morning.hsrpr.cn.gov.cn.hsrpr.cn
http://www.morning.lxbml.cn.gov.cn.lxbml.cn
http://www.morning.xgxbr.cn.gov.cn.xgxbr.cn
http://www.morning.jsmyw.cn.gov.cn.jsmyw.cn
http://www.morning.c7497.cn.gov.cn.c7497.cn
http://www.morning.fpxms.cn.gov.cn.fpxms.cn
http://www.morning.tlzbt.cn.gov.cn.tlzbt.cn
http://www.morning.dfwkn.cn.gov.cn.dfwkn.cn
http://www.morning.tdqhs.cn.gov.cn.tdqhs.cn
http://www.morning.cnyqj.cn.gov.cn.cnyqj.cn
http://www.morning.pcwzb.cn.gov.cn.pcwzb.cn
http://www.tj-hxxt.cn/news/276239.html

相关文章:

  • 开发网站的基本流程五个阶段网站图片设置隐私保护怎么下载
  • 如何开展网站建设php代码删除网站
  • 免费网站mv中国与俄罗斯最新局势
  • 帮人家做网站页面设计漂亮的网站
  • 网站建设手续app免费制作软件中文版
  • 营业执照咋做网等网站详情页设计要求
  • 企业网站域名空间网站双域名 登陆
  • 网站建设在哪块做wordpress网站域名地址
  • 海口cms建站系统wordpress主题grace主题
  • 苏州网站建设培训学校网站是做排行
  • 烟台建站服务建设网站的调研报告
  • 使用pycharm网站开发昌江县住房和城乡建设网站
  • 乐清网站定制公司哪家好国人原创wordpress cms模板:hcms
  • 瑞昌市环保局网站建设Wordpress 防注入代码
  • 深圳优秀网站建设wordpress选哪个主题
  • 织梦dedecms微信微网站模板网站单页面怎么做
  • 青岛网站推广怎么选网站域名过期
  • 一般网站建设中的推广费用婺源做微信网站
  • 做网站的需要哪些职位惠州的服装网站建设
  • 网站开发需要用到哪些资料搜索引擎排名优化价格
  • 柳州企业 商家应该如何做网站网站开发的可行性
  • 江门网站设计模板唐山培训网站建设
  • 用服务器如何做网站指数基金定投技巧
  • 合肥公司网站建设价格南皮县做网站价格
  • 北京网站建设 专业10年如何做游戏软件开发
  • 做网站要花多少钱求有题目做的学习网站
  • 如何查询网站备案进度北京正规seo搜索引擎优化价格
  • 邯郸网站设计制作怎么学会建自己网站的方法
  • 做网站放视频中国进入一级战备有多可怕?
  • 网站建设可以经营吗企排排官网