STM32 SPI总线驱动CH376T实现U盘/TF卡读写全解析—在U盘读写中的应用(中下) | 零基础入门STM32第七十四步

主题内容教学目的/扩展视频
CH376芯片重点课程电路原理,跳线设置,切换U盘和TF卡。手册分析。驱动程序。调用常用函数。会调用现有函数操作U盘即可。

师从洋桃电子,杜洋老师



回顾上期🔍STM32 SPI总线驱动CH376T实现U盘/TF卡读写全解析(上) | 零基础入门STM32第七十二步

回顾上期🔍STM32 SPI总线驱动CH376T实现U盘/TF卡读写全解析—CH376数据手册分析(中上) | 零基础入门STM32第七十三步


一、SPI总线通信原理

1. SPI总线基础

SPI(Serial Peripheral Interface)是一种全双工同步串行通信协议,常用于单片机与外围设备(如存储器、传感器)的高速通信。其核心特点包括:

  • 四线制:SCK(时钟)、MOSI(主机输出)、MISO(主机输入)、NSS(片选)。
  • 主从模式:主机控制时钟,从设备响应。
  • 灵活配置:支持多种时钟极性和相位组合。

2. SPI工作模式

SPI通过CPOL(时钟极性)和CPHA(时钟相位)定义数据传输时序,形成四种工作模式:

模式CPOLCPHA数据采样边沿
000SCK上升沿采样
101SCK下降沿采样
210SCK下降沿采样
311SCK上升沿采样

示例代码配置(模式3)

SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;  // CPOL=1
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; // CPHA=1

二、SPI驱动程序分析(以STM32为例)

1. SPI初始化关键步骤

void SPI2_Init(void) {
    // 1. 配置GPIO:MOSI/SCK为复用推挽,MISO为浮空输入
    GPIO_InitStructure.GPIO_Pin = SPI2_MOSI | SPI2_SCK;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(SPI2PORT, &GPIO_InitStructure);

    // 2. 设置SPI参数:模式、数据位、时钟分频等
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;       // 主机模式
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;  // 8位数据
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // MSB优先
    SPI_Init(SPI2, &SPI_InitStructure);

    // 3. 使能SPI
    SPI_Cmd(SPI2, ENABLE);
}

2. 数据传输函数

u8 SPI2_SendByte(u8 Byte) {
    while (!SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)); // 等待发送缓冲区空
    SPI_I2S_SendData(SPI2, Byte);                          // 发送数据
    while (!SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE));// 等待接收完成
    return SPI_I2S_ReceiveData(SPI2);                      // 返回接收数据
}

三、单片机与CH376芯片的通信过程

1. CH376初始化流程

if (mInitCH376Host() == USB_INT_SUCCESS) {
    OLED_DISPLAY_8x16_BUFFER(4, "   CH376 OK!    "); // 初始化成功提示
}

关键操作

  1. 发送SET_USB_MODE命令切换到主机模式。
  2. 检测U盘连接状态(CMD_DISK_CONNECT)。
  3. 初始化磁盘(CMD_DISK_MOUNT)。

2. U盘插拔状态检测

while (1) {
    s = CH376DiskConnect(); // 检测U盘状态
    if (s == USB_INT_SUCCESS) {
        OLED_DISPLAY_8x16_BUFFER(6, " U DISK Ready!  "); // U盘已连接
    } else {
        OLED_DISPLAY_8x16_BUFFER(6, "                "); // U盘未连接
    }
    delay_ms(500);
}

四、NSS接口控制方式

1. 硬件NSS vs 软件NSS

控制方式特点
硬件NSS自动控制片选信号,简化代码,但灵活性差
软件NSS手动控制GPIO引脚,适用于多从设备场景

2. 代码实现(软件NSS)

// 手动拉低NSS(开始传输)
GPIO_ResetBits(SPI2PORT, SPI2_NSS); 

// 发送数据
SPI2_SendByte(0x55); 

// 手动拉高NSS(结束传输)
GPIO_SetBits(SPI2PORT, SPI2_NSS); 

五、数据位顺序设置

SPI支持MSB(高位在前)LSB(低位在前)两种数据格式。CH376要求MSB优先,需在初始化时明确配置:

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // 设置为MSB优先

六、系统结构图

存储模块
主控模块
PA4(NSS)
PA5(SCK)
PA7(MOSI)
PA6(MISO)
USB接口
TF卡槽
U盘
TF卡
CH376T\n(USB/TF卡控制器)
STM32F103\n(SPI主机)
  • 单片机:STM32作为SPI主机,控制通信流程。
  • CH376芯片:负责USB协议解析和文件管理。
  • U盘/SD卡:存储介质,通过SPI与CH376交互。

七、优化与扩展建议

  1. 提升SPI通信速率

    // 修改预分频值(例如SPI_BaudRatePrescaler_8)
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; 
    

    CH376支持最高6MHz SPI时钟,合理设置分频可提升读写速度。

  2. 多设备SPI扩展

    • 通过多路NSS信号控制多个SPI从设备。
    • 使用GPIO切换片选,实现分时复用。
  3. 错误处理机制

    • 添加超时检测,避免SPI通信卡死。
    • 在CH376操作中检查返回值,确保命令执行成功。

八、相关资源

[1] 洋桃电子B站课程-STM32入门100步
[2] STM32官方文档手册
[3] STM32F103固件函数库用户手册(中文)
[4] CH376(U盘文件读写)
[5] U盘插拔测试程序


💬 技术讨论(请在评论区留言~)

📌 下期预告:下一期将探讨CH376驱动程序分析重点课程,欢迎持续关注!

点击查阅🔍往期【STM32专栏】文章

版权声明:本文采用[CC BY-NC-SA 4.0]协议,转载请注明来源
实测开发版:洋桃1号开发版(基于STM32F103C8T6)
更新日志

  • v1.0 初始版本(2025-03-17)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值