STM32_SPI读写Flash

推荐

分享一个大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到人工智能的队伍中来!http://www.captainbed.net/strongerhuang

 

我的网站:https://www.strongerhuang.com

我的知乎:https://www.zhihu.com/people/strongerHuang.com

 

 

今天讲解“STM32F103 SPI读写Flash”,其实这第一阶段主要是讲解STM32的SPI功能,所有今天的重点是SPI,关于FLASH我应该要在后面再次讲述。

今天的软件工程下载地址(360云盘):

https://yunpan.cn/cPzhMXjRPbWzc  访问密码

 

STM32F10x的资料可以在我360云盘下载:

https://yunpan.cn/crBUdUGdYKam2   访问密码 ca90

 

关于“STM32F103 SPI读写Flash” 我把重要的几点在下面分别讲述,若不明白,请关注微信公众号“EmbeddDeveloper”查阅或留言。

 

一、RCC时钟配置

 

该函数位于在bsp.c文件下面;

使能RCC时钟:RCC_APB2Periph_SPI1

 

二、引脚配置

 

该函数位于在spi.c文件下面;

这里是对SPI所使用引脚进行配置。

注意

SPI作为主机,我们使用硬件SPI时,通常只使用SCK, MOSI, MISO三个引脚,片选CS需要单独配置,所以这里配置CS需要和器件对应才行。

 

三、SPI配置

 

该函数位于在spi.c文件下面;

对SPI进行配置。

配置的每一条语句都有注释,请看源代码.

这里配置的都比较基础的,后续我会讲解复杂一点的配置(前期第一阶段定位在初级,所以,如果你想了解更高级的功能,请持续关注我的微信公众号)。

 

四、SPI读写字节

 

该函数位于在spi.c文件下面;

外设操作SPI时就需要调用这个函数。

 

五、主函数应用

 

该函数位于在main.c文件下面;

这里是通过SPI操作FLASH读写数据,但今天主要是测试SPI通信是否正常,所以关于FLASH的函数今天就不在这里讲解,感兴趣的朋友可以研究一下,经过我大量测试,sflash.c文件的接口可以正常使用。

可以看到现象:间隔500ms,LED变化,串口打印出读出flash的数据。

 

六、今天的重点提示

SPI的对应从机基本上都有片选信号,所以这里要对应起来;还有SPI可作为从机使用,后续我会讲解。

 

下载方式:长按网站 ->选择复制->打开

或者复制网站在电脑上下载也可。

 

我的网站:https://www.strongerhuang.com

我的微信公众号(ID:strongerHuang)还在分享STM8、STM32、Keil、IAR、FreeRTOS、UCOS、RT-Thread、CANOpen、Modbus…等更多精彩内容,如果想查看更多内容,可以关注我的微信公众号。

 

微信公众号

 

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
STM32中使用SPI读写flash的步骤如下: 1. 配置SPI模块,设置SPI的时钟极性、时钟相位、主从模式、数据位长度等参数。 2. 配置GPIO口,将SPI的SCK、MOSI、MISO和CS引脚设置为SPI模式。 3. 初始化flash芯片,发送命令以及地址等信息,使flash进入读或写模式。 4. 使用SPI发送或接收数据,读取或写入flash中的数据。 下面是一段示例代码,用于在STM32F4上使用SPI读取Winbond W25Q128FV SPI Flash的ID: ```c #include "stm32f4xx.h" #include <stdio.h> #define FLASH_CS_PIN GPIO_Pin_4 #define FLASH_CS_PORT GPIOE #define CMD_READ_ID 0x9F void SPI_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_SPI1); GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_SPI1); GPIO_SetBits(GPIOB, GPIO_Pin_6); SPI_I2S_DeInit(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_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; 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); } void SPI_WriteByte(uint8_t byte) { while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, byte); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); SPI_I2S_ReceiveData(SPI1); } uint8_t SPI_ReadByte(void) { while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, 0xFF); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); return SPI_I2S_ReceiveData(SPI1); } void Flash_CS_Enable(void) { GPIO_ResetBits(FLASH_CS_PORT, FLASH_CS_PIN); } void Flash_CS_Disable(void) { GPIO_SetBits(FLASH_CS_PORT, FLASH_CS_PIN); } void Flash_Init(void) { Flash_CS_Disable(); SPI_WriteByte(0x06); // Write Enable Flash_CS_Enable(); Flash_CS_Disable(); } uint32_t Flash_ReadID(void) { uint8_t id[3]; Flash_CS_Enable(); SPI_WriteByte(CMD_READ_ID); id[0] = SPI_ReadByte(); id[1] = SPI_ReadByte(); id[2] = SPI_ReadByte(); Flash_CS_Disable(); return ((uint32_t)id[0] << 16) | ((uint32_t)id[1] << 8) | (uint32_t)id[2]; } int main(void) { uint32_t id; SPI_Config(); Flash_Init(); id = Flash_ReadID(); printf("Flash ID: 0x%06X\r\n", id); while (1); } ``` 在这个例子中,我们先配置了SPI1的GPIO口和SPI模块,并且初始化了Flash芯片。然后,我们发送读取Flash ID的命令(0x9F),并读取3个字节的ID号。最后,我们将ID号打印到串口上。需要注意的是,在读写Flash之前,我们需要通过写使能命令(0x06)将Flash芯片的写使能位设置为1,以允许对Flash进行写操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

strongerHuang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值