完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1.软件设计流程
SPI读写Flash流程:
其头文件如图: 根据定义的头文件可以写如下初始化程序,初始化SPI、端口时钟,引脚;配置SPI模式。 //SPI_FLASH_Init函数 void SPI_FLASH_Init(void) { SPI_InitTypeDef SPI_initStructure; GPIO_InitTypeDef GPIO_InitStructure;//SPI、GPIO结构体定义 FLASH_SPI_APBxClock_FUN(FLASH_SPI_CLK,ENABLE); FLASH_SPI_CS_APBxClock_FUN(FLASH_SPI_CS_CLK|FLASH_SPI_SCK_CLK|FLASH_SPI_MISO_CLK|FLASH_SPI_MOSI_CLK,ENABLE); //配置SPI的GPIO引脚 GPIO_InitStructure.GPIO_Pin = FLASH_SPI_CS_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(FLASH_SPI_CS_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = FLASH_SPI_SCK_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(FLASH_SPI_SCK_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MISO_PIN; GPIO_Init(FLASH_SPI_MISO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MOSI_PIN; GPIO_Init(FLASH_SPI_MOSI_PORT, &GPIO_InitStructure); FLASH_SPI_CS_HIGH();//片选FLASH_CS为高电平 /*SPI模式配置********************************/ SPI_InitTypeDef SPI_InitStructure; // FLASH 芯片 支持 SPI 模式 0 及模式 3,据此设置 CPOL CPHA 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_4; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(FLASH_SPIx, &SPI_InitStructure); /* 使能 SPI */ SPI_Cmd(FLASH_SPIx, ENABLE); } 3.SPI发送接收一字节函数编写 接下来编写SPI发送和接受一个字节数据的函数,如下: #define Dummy_Byte 0xFF u8 SPI_FLASH_SendByte(u8 byte) { SPITimeout = SPIT_FLAG_TIMEOUT; //等待发送缓冲区为空,及TXE事件发生 while(SPI_I2S_GetFlagStatus(FLASH_SPIx,SPI_I2S_FLAG_TXE) == RESET) { if((SPITimeout--)==0) return SPI_TIMEOUT_UserCallback(0); } //把数据写入发送缓冲区 SPI_I2S_SendData(FLASH_SPIx,byte); SPITimeout = SPIT_FLAG_TIMEOUT; //等待接受缓冲区为非空,及RXNE事件发生 while(SPI_I2S_GetFlagStatus(FLASH_SPIx,SPI_I2S_FLAG_RXNE) == RESET) { if((SPITimeout--)==0) return SPI_TIMEOUT_UserCallback(1); } return SPI_I2S_ReceiveData(FLASH_SPIx); //获取接受缓冲区数据 } 然后使用SPI读取一个字节数据 u8 SPI_FLASH_ReadByte(void) { return (SPI_FLASH_SendByte(Dummy_Byte)); } 由于SPI通讯模式配置为全双工模式,即收发是同步进行的。发送数据通过向发送缓冲区写数据即可;接收数据即调用发送数据函数,发送任意值,再返回收到的数据即可。 4.FLASH控制指令介绍 stm32作为主机,通过SPI向FLASH发送的数据过去,FLASH会将这些数据理解成不同指令,然后执行不同操作。 通过SPI依据指令表次序规律发送数据,即可完成相应操作。其中“A0~A23”指 FLASH 芯片内部存储器组织的地址;“M0~M7”为厂商号(MANUFACTURER ID);“ID0-ID15”为 FLASH 芯片的ID;“dummy”指该处可为任意数据;“D0~D7”为 FLASH 内部存储矩阵的内容。 通过指令“9F h”可以获得设备的生产厂商,存储器类型,容量。其通讯时序如下图: 本系列笔记内容和图片基于《【野火®】零死角玩转STM32—F103-MINI》 |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2955 浏览 16 评论
3455 浏览 1 评论
8987 浏览 16 评论
4050 浏览 18 评论
1102浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 07:43 , Processed in 1.209326 second(s), Total 79, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号