STM32入门开发 介绍SPI总线、读写W25Q64

作者 : admin 本文共3136个字,预计阅读时间需要8分钟 发布时间: 2024-06-17 共1人阅读

摘要

本文旨在为STM32微控制器的初学者提供一个关于SPI总线和W25Q64 Flash存储器的基础知识介绍,以及如何使用STM32硬件SPI来读写W25Q64。我们将从SPI总线的基本概念开始,逐步深入到W25Q64的特性、硬件连接、SPI配置、读写操作,并提供实际的代码示例。

1. SPI总线简介

SPI(Serial Peripheral Interface)是一种同步串行通信协议,用于微控制器和各种外围设备之间的通信。它是一种高速、全双工、主从模式的通信总线。

1.1 SPI通信特点
  • 主设备:控制通信的时钟信号和数据交换的开始与结束。
  • 从设备:响应主设备的通信请求。
  • 数据传输:以主设备产生的时钟信号同步。
1.2 SPI通信信号线
  • MOSI(Master Out Slave In):主设备数据输出,从设备数据输入。
  • MISO(Master In Slave Out):主设备数据输入,从设备数据输出。
  • SCK(Serial Clock):时钟信号,由主设备产生。
  • CS(Chip Select):片选信号,用于激活特定的从设备。

2. W25Q64 Flash存储器

W25Q64是一款8Mb(1M x 8位)的串行Flash存储器,适用于存储程序代码、数据等信息。

2.1 W25Q64特性
  • 容量:8Mb
  • 组织:1M字节,每页256字节
  • 擦除时间:毫秒级别
  • 读写周期:100万次

3. 硬件连接

将W25Q64连接到STM32开发板,确保以下引脚正确连接:

  • CS 连接到 STM32 GPIO(例如PA4)
  • SCK 连接到 STM32 SPI SCK(例如PA5)
  • MOSI 连接到 STM32 SPI MOSI(例如PA7)
  • MISO 连接到 STM32 SPI MISO(例如PA6)
  • VCC 连接到 3.3V
  • GND 连接到 GND

4. SPI配置

在STM32中配置SPI,需要设置SPI的模式、数据大小、时钟极性、时钟相位等参数。

4.1 SPI初始化代码
void SPI_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef SPI_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI1, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    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_16;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI1, &SPI_InitStructure);

    SPI_Cmd(SPI1, ENABLE);
}

5. W25Q64操作

5.1 初始化W25Q64
void W25Q64_Init(void) {
    SPI_CS_High(); // 确保CS是高电平开始
}
5.2 读取W25Q64 ID
uint16_t W25Q64_ReadID(void) {
    uint16_t id = 0;
    SPI_CS_Low();
    SPI_SendByte(0x90); // 读取ID指令
    id = SPI_ReceiveByte() << 8;
    id |= SPI_ReceiveByte();
    SPI_CS_High();
    return id;
}
5.3 写入W25Q64
void W25Q64_WriteByte(uint32_t addr, uint8_t data) {
    SPI_CS_Low();
    SPI_SendByte(0x02); // 写入指令
    SPI_SendByte((addr >> 16) & 0xFF);
    SPI_SendByte((addr >> 8) & 0xFF);
    SPI_SendByte(addr & 0xFF);
    SPI_SendByte(data);
    SPI_CS_High();
    // 等待写入完成...
}
5.4 从W25Q64读取数据
uint8_t W25Q64_ReadByte(uint32_t addr) {
    uint8_t data;
    SPI_CS_Low();
    SPI_SendByte(0x03); // 读取指令
    SPI_SendByte((addr >> 16) & 0xFF);
    SPI_SendByte((addr >> 8) & 0xFF);
    SPI_SendByte(addr & 0xFF);
    data = SPI_ReceiveByte();
    SPI_CS_High();
    return data;
}

6. 测试代码

以下是测试SPI通信和W25Q64读写操作的示例代码:

int main(void) {
    // 系统初始化
    SystemInit();

    // 初始化SPI和W25Q64
    SPI_Init();
    W25Q64_Init();

    // 读取W25Q64 ID
    uint16_t id = W25Q64_ReadID();
    printf("W25Q64 ID: 0x%X\r
", id);

    // 测试写入和读取
    uint8_t test_data = 0xAA;
    uint8_t read_data;
    W25Q64_WriteByte(0, test_data); // 写入测试数据
    read_data = W25Q64_ReadByte(0); // 读取数据
    if (test_data == read_data) {
        printf("Read/Write test passed.\r
");
    } else {
        printf("Read/Write test failed.\r
");
    }

    while(1) {
        // 这里可以添加其他测试或应用代码
    }
}

7. 结论

本文为STM32的入门开发者提供了SPI总线和W25Q64 Flash存储器的基础知识,以及如何使用STM32的硬件SPI进行读写操作。通过实际的代码示例,读者可以快速理解并应用SPI通信。在实际开发中,开发者可能需要根据具体的硬件配置和需求进行适当的调整和优化。

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进

❤欢迎关注我的知乎:对error视而不见

代码获取、问题探讨及文章转载可私信。

☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。

🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇

点击领取更多详细资料

本站无任何商业行为
个人在线分享 » STM32入门开发 介绍SPI总线、读写W25Q64
E-->