[PIC32/SAM] 关于PIC24FJ256GB206读写sd卡的程序

[复制链接]
1327|11
 楼主| laocuo1142 发表于 2025-2-17 20:00 | 显示全部楼层 |阅读模式
有会mplab的吗,关于PIC24FJ256GB206读写sd卡的程序,网上没有找到教程,请问有会的吗
huahuagg 发表于 2025-2-21 18:14 | 显示全部楼层
  1. /*------------------------- 硬件配置 -------------------------*/
  2. #include <xc.h>
  3. #include <stdint.h>
  4. #pragma config FNOSC = FRCPLL      // 使用FRC振荡器+PLL

  5. // SPI引脚配置(使用RP引脚重映射)
  6. #define SD_CS     _LATB9           // CS: RB9
  7. #define SD_CS_TRIS _TRISB9
  8. #define SPI_MOSI  _RP10R = 0b0011  // SDO1映射到RP10
  9. #define SPI_MISO  11               // SDI1使用RP11
  10. #define SPI_SCK   _RP9R = 0b0011   // SCK1映射到RP9

  11. /*------------------------- SD驱动层 -------------------------*/
  12. #define CMD0  0x40
  13. #define CMD8  0x48
  14. #define ACMD41 0x69
  15. #define CMD16  0x50
  16. #define CMD17  0x51
  17. #define CMD24  0x58

  18. uint8_t SD_SendCmd(uint8_t cmd, uint32_t arg) {
  19.     SPI1_Transfer(cmd);
  20.     SPI1_Transfer(arg >> 24);
  21.     SPI1_Transfer(arg >> 16);
  22.     SPI1_Transfer(arg >> 8);
  23.     SPI1_Transfer(arg);
  24.     SPI1_Transfer((cmd == CMD0) ? 0x95 : (cmd == CMD8) ? 0x87 : 0x01);

  25.     for(uint8_t retry=0; retry<10; retry++) {
  26.         uint8_t res = SPI1_Transfer(0xFF);
  27.         if((res & 0x80) == 0) return res;
  28.     }
  29.     return 0xFF;
  30. }

  31. uint8_t SD_Init(void) {
  32.     SD_CS_TRIS = 0;        // 配置CS为输出
  33.     SD_CS = 1;             // CS置高
  34.    
  35.     // SPI初始化(主模式,8MHz)
  36.     SPI1CON1 = 0;
  37.     SPI1CON1bits.MSTEN = 1;        // 主模式
  38.     SPI1CON1bits.MODE16 = 0;       // 8位模式
  39.     SPI1CON1bits.PPRE = 3;         // 预分频 1:1
  40.     SPI1CON1bits.SPRE = 6;         // 主分频 1:2
  41.     SPI1STATbits.SPIEN = 1;        // 使能SPI
  42.    
  43.     // 发送至少74个时钟脉冲
  44.     for(uint8_t i=0; i<10; i++) SPI1_Transfer(0xFF);
  45.    
  46.     // CMD0复位
  47.     if(SD_SendCmd(CMD0, 0) != 0x01) return 1;
  48.    
  49.     // 初始化流程(支持SDv2)
  50.     uint8_t resp = SD_SendCmd(CMD8, 0x1AA);
  51.     if(resp == 0x01) {
  52.         for(uint8_t i=0; i<4; i++) SPI1_Transfer(0xFF); // 丢弃响应
  53.         do {
  54.             resp = SD_SendCmd(ACMD41, 0x40000000);
  55.         } while(resp != 0x00);
  56.     } else return 2;
  57.    
  58.     // 设置块长度(512字节)
  59.     if(SD_SendCmd(CMD16, 512) != 0x00) return 3;
  60.    
  61.     return 0;
  62. }

  63. /*------------------------- FatFs集成 ------------------------*/
  64. #include "ff.h"     // FatFs R0.15

  65. DSTATUS disk_initialize (BYTE pdrv) {
  66.     return (SD_Init() == 0) ? 0 : STA_NOINIT;
  67. }

  68. DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count) {
  69.     SD_CS = 0;
  70.     for(UINT i=0; i<count; i++) {
  71.         if(SD_SendCmd(CMD17, sector+i) != 0x00) {
  72.             SD_CS = 1;
  73.             return RES_ERROR;
  74.         }
  75.         while(SPI1_Transfer(0xFF) != 0xFE); // 等待数据令牌
  76.         for(uint16_t j=0; j<512; j++) buff[j] = SPI1_Transfer(0xFF);
  77.         SPI1_Transfer(0xFF); // 丢弃CRC
  78.         SPI1_Transfer(0xFF);
  79.     }
  80.     SD_CS = 1;
  81.     return RES_OK;
  82. }

  83. /*------------------------- 使用示例 ------------------------*/
  84. void main(void) {
  85.     FATFS fs;
  86.     FIL fil;
  87.    
  88.     if(f_mount(&fs, "", 1) == FR_OK) {
  89.         f_open(&fil, "test.txt", FA_WRITE | FA_CREATE_ALWAYS);
  90.         f_printf(&fil, "PIC24 SD Card Test @2025");
  91.         f_close(&fil);
  92.     }
  93.     while(1);
  94. }

  95. // SPI数据传输函数(必须内联优化)
  96. static inline uint8_t SPI1_Transfer(uint8_t data) {
  97.     SPI1BUF = data;
  98.     while(!SPI1STATbits.SPIRBF);
  99.     return SPI1BUF;
  100. }
花间一壶酒sd 发表于 2025-2-23 00:12 | 显示全部楼层
如果读写失败,检查初始化流程是否正确。
heisexingqisi 发表于 2025-2-24 11:20 | 显示全部楼层
先搞清楚这个读写卡的底层函数,一般网上有IO口模拟的,可以先试试
guijial511 发表于 2025-2-24 21:00 来自手机 | 显示全部楼层
SD卡不是SDIO接口吗?代码是用的SPI接口啊。
自动化陈稳 发表于 2025-4-27 01:12 | 显示全部楼层
SD卡通常使用 SPI 接口进行通信,因此你需要设置 SPI 和适当的文件系统(通常是 FAT16/32)来读写 SD 卡。
自动化陈稳 发表于 2025-4-27 01:15 | 显示全部楼层
FatFS 是一个开源库,支持在嵌入式系统中读取和写入 FAT 文件系统。
野玫瑰 发表于 2025-8-29 12:16 | 显示全部楼层
PIC24FJ256GB206 读写 SD 卡需配置 SPI 接口,初始化 SD 卡为 SPI 模式,发送 CMD 命令检测卡类型。读操作通过 CMD17 发送地址,接收数据块;写操作以 CMD24 发送地址和数据。需处理 CRC 校验,用中断或轮询循环检测状态,确保数据正确传输,可参考 Microchip 的 MPLAB Harmony 库示例。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1296

主题

6239

帖子

15

粉丝
快速回复 在线客服 返回列表 返回顶部