STM32 SPI总线驱动CH376T实现U盘/TF卡读写全解析—SPI通信、命令集与文件操作(下) | 零基础入门STM32第七十五步

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

师从洋桃电子,杜洋老师


文章目录

    • 1. 引言
    • 2. 硬件连接
    • 3. 驱动程序分析
      • 3.1 SPI通信机制
    • 4. CH376命令集详解
      • 4.1 常用命令表
      • 4.2 命令使用示例
    • 5. 初始化程序解析
    • 6. 数据读写函数实现
      • 6.1 写数据到文件
      • 6.2 从文件读取数据
    • 7. 应用示例:U盘状态检测
    • 8. 扩展性建议
    • 9. 相关资源


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

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

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


1. 引言

CH376是一款集成USB主机/设备模式及SD卡控制的文件管理芯片,支持FAT文件系统。本文基于STM32平台,详解CH376的SPI驱动开发、命令集解析及文件操作实现。


2. 硬件连接

CH376与STM32通过SPI接口连接,典型接线如下:

存储模块
主控模块
PA4(NSS)
PA5(SCK)
PA7(MOSI)
PA6(MISO)
USB接口
TF卡槽
U盘
TF卡
CH376T\n(USB/TF卡控制器)
STM32F103\n(SPI主机)
CH376引脚 STM32引脚 功能
SCS SPI_NSS(PA4) 片选信号
SCK SPI_SCK (PA5) 时钟信号
SDI SPI_MOSI(PA7) 主机输出
SDO SPI_MISO(PA6) 主机输入
INT# PA8 中断信号

3. 驱动程序分析

3.1 SPI通信机制

CH376通过SPI接口接收命令和数据,关键函数如下:

// 发送命令
void xWriteCH376Cmd(u8 mCmd) {
    SPI_NSS_LOW();          // 片选使能
    SPI_SendByte(mCmd);     // 发送命令码
    delay_us(20);           // 等待命令处理
}

// 发送数据
void xWriteCH376Data(u8 mData) {
    SPI_SendByte(mData);    // 发送数据
    delay_us(10);           // 维持时序
}

// 接收数据
u8 xReadCH376Data() {
    return SPI_ReceiveByte(); // 读取返回数据
}

4. CH376命令集详解

4.1 常用命令表

命令代码 名称 功能描述
0x01 GET_IC_VER 获取芯片版本
0x06 CHECK_EXIST 测试通信接口
0x15 SET_USB_MODE 设置USB工作模式
0x2F SET_FILE_NAME 设置文件名
0x32 FILE_OPEN 打开文件/目录
0x3A BYTE_READ 按字节读取文件数据

4.2 命令使用示例

// 设置USB主机模式
void SetUSBHostMode() {
    xWriteCH376Cmd(CMD_SET_USB_MODE);
    xWriteCH376Data(0x06);  // 模式代码06:启用主机并自动生成SOF
    u8 status = xReadCH376Data();
    if (status == USB_INT_SUCCESS) {
        // 模式设置成功
    }
}

5. 初始化程序解析

u8 mInitCH376Host() {
    // 1. 测试通信接口
    xWriteCH376Cmd(CMD_CHECK_EXIST);
    xWriteCH376Data(0x55);
    u8 res = xReadCH376Data();
    if (res != 0xAA) return ERR_USB_UNKNOWN; // 通信异常

    // 2. 设置USB主机模式
    xWriteCH376Cmd(CMD_SET_USB_MODE);
    xWriteCH376Data(0x06);
    res = xReadCH376Data();
    return (res == CMD_RET_SUCCESS) ? USB_INT_SUCCESS : ERR_USB_UNKNOWN;
}

6. 数据读写函数实现

6.1 写数据到文件

void WriteFileData(u8* buffer, u16 len) {
    xWriteCH376Cmd(CMD_SET_FILE_NAME);
    xWriteCH376Data("TEST.TXT\0");  // 设置文件名
    xWriteCH376Cmd(CMD_BYTE_WRITE);
    xWriteCH376Data(len & 0xFF);    // 写入长度低字节
    xWriteCH376Data(len >> 8);      // 写入长度高字节
    for (u16 i=0; i<len; i++) {
        xWriteCH376Data(buffer[i]); // 逐字节写入数据
    }
}

6.2 从文件读取数据

u8 ReadFileData(u8* buffer, u16 max_len) {
    xWriteCH376Cmd(CMD_BYTE_READ);
    xWriteCH376Data(max_len & 0xFF); 
    xWriteCH376Data(max_len >> 8);
    u8 status = Query376Interrupt();
    if (status == USB_INT_DISK_READ) {
        u8 len = xReadCH376Data();  // 获取数据长度
        for (u8 i=0; i<len; i++) {
            buffer[i] = xReadCH376Data();
        }
        return len;
    }
    return 0;
}

7. 应用示例:U盘状态检测

int main() {
    // 初始化SPI、CH376等
    SPI2_Init();
    if (mInitCH376Host() == USB_INT_SUCCESS) {
        OLED_Display("CH376 Ready!");
    }

    while(1) {
        u8 status = CH376DiskConnect();
        if (status == USB_INT_SUCCESS) {
            OLED_Display("U盘已连接");
        } else {
            OLED_Display("等待U盘...");
        }
        delay_ms(500);
    }
}

8. 扩展性建议

  • 多级目录操作:结合CMD_DIR_CREATECMD_FILE_OPEN实现目录创建与遍历。
  • 长文件名支持:使用CMD_SET_FILE_NAME设置Unicode编码文件名。
  • 错误处理:增加对ERR_DISK_DISCON等错误码的检测与恢复机制。

9. 相关资源

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


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

下期预告:下一期将探讨文件系统程序分析重点课程,欢迎持续关注!

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

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

  • v1.0 初始版本(2025-03-17)

你可能感兴趣的:(STM32入门教程(100步),stm32,驱动开发,单片机,嵌入式硬件,物联网)