1

我正在尝试使用 FatFS ( http://elm-chan.org/fsw/ff/00index_e.html ) 作为使用 SPI 与 SD 卡进行通信的一种方式。

FatFS 网站有许多示例,但我发现它们并不容易理解或遵循。可下载的 zip 中有两个示例适用于我,一个用于“通用”微控制器,另一个用于 PIC24。虽然 PIC24 看起来与我的 dsPIC33F 非常相似,但代码非常难以理解,具有我不关心的特定应用程序。

通用代码更容易理解,并且执行一个非常简单的应用程序:创建一个 txt 文件,写入它,然后关闭它。但是,我很难更改代码以使用我的 PIC。

我有 dsPIC33FJ128GP802。我在通用示例中添加了代码来重新映射 SPI 引脚、设置内部振荡器以及设置和启动 SPI 模块:

// Configure Oscillator to operate the device at 40Mhz
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 8M*40/(2*2)=80Mhz for 8M input clock
PLLFBD = 38; // M=40
CLKDIVbits.PLLPOST = 0; // N1=2
CLKDIVbits.PLLPRE = 0;  // N2=2
OSCTUN = 0;             // Tune FRC oscillator, if FRC is used

// Unlocks PPS, make change, and locks again.
__builtin_write_OSCCONL(OSCCONL & ~(1 << 6));

// OUTPUT
RPOR6bits.RP12R = 7; // RP12 = SDO1 which is SPI1 DATA OUTPUT.
RPOR7bits.RP15R = 8; // RP15 = SCK1OUT which is SPI1 CLOCK OUTPUT.

// INPUT
RPINR21bits.SS1R = 13; // RP13 = SS1R which is SPI1 SLAVE/CHIP SELECT.
RPINR20bits.SDI1R = 14; // RP14 = SDI1R which is SPI DATA INTPUT.

__builtin_write_OSCCONL(OSCCONL | (1 << 6));

SPI1STAT = 0;
SPI1STATbits.SPIEN = 0; // Disable SPI module.
SPI1STATbits.SPISIDL = 0; // Continue in idle mode.
SPI1STATbits.SPIROV = 0; // No overflow.
SPI1STATbits.SPITBF = 0; // Transmit started, SPIxTXB is empty.
SPI1STATbits.SPIRBF = 0; // Receive is not complete, SPIxRXB is empty.

SPI1CON1 = 0;
SPI1CON1bits.DISSCK = 0; // Internal clock enabled.
SPI1CON1bits.DISSDO = 0; // SD0 controlled by the module.
SPI1CON1bits.MODE16 = 0; // 8 bit mode.
SPI1CON1bits.SMP = 0; // Input data sampled at middle of data output time.
SPI1CON1bits.CKE = 1; // Serial output data changes on transition from idle.
SPI1CON1bits.SSEN = 0; // Slave select is not used by the module. 
SPI1CON1bits.CKP = 0; // Idle state for clock is low.
SPI1CON1bits.MSTEN = 1; // Master mode enabled.
SPI1CON1bits.SPRE = 0b000; // Secondary prescale 8:1
SPI1CON1bits.PPRE = 0b01; // Primary prescale 16:1.

SPI1CON2 = 0;
SPI1CON2bits.FRMEN = 0; // Framed SPI disabled.
SPI1CON2bits.SPIFSD = 0; // Framed sync pulse output.(N/A)
SPI1CON2bits.FRMPOL = 0; // Framed sync pulse is active-low.(N/A)
SPI1CON2bits.FRMDLY = 0; // Framed sync pulse precedes first bit clock.(N/A)

SPI1STATbits.SPIEN = 1; // Enable SPI module.

PIC到SD卡是:

  • RP15,SPI时钟输出,到SCK
  • RP14,SPI 数据输入,到 DO(数据输出)。
  • RP13,SPI 从机选择,至 CS。
  • RP12,SPI数据输出,到DI(数据输入)。
  • SD 卡 CD 未连接。

有FatFS经验的人可以帮我做必要的改动。到目前为止,运行代码一直到 f_open,它返回错误 FR_NOT_READY。

现在我不想做任何花哨的事情,只是创建一个文件并写入它。我见过许多使用外部晶体振荡器的应用程序,而我没有。这是SPI的必需品吗?我是 SPI 新手,在此之前一直在使用 I2C。

在通用示例的 mmcbb.c 文件中,我必须进行一些更改以消除我遇到的一些错误,我用我自己的函数替换了他们的延迟函数,以创建与引发错误的时间相似的延迟,我还删除了出现在 disk_initialize(BYTE pdrv) 中的 INIT_PORT(),因为它引发了错误,并且我在进入任何 FatFS 代码之前初始化了端口,就在 main 的开头。在 mmcbb.c 的顶部有 #define 需要将相应的端口添加到我设置 SPI 的方式中,我这样做了(RBx 引脚与我在上面设置的 RPx 相同):

#define CS_H()      PORTBbits.RB13 |= 0x01  /* Set MMC CS "high" */
#define CS_L()      PORTBbits.RB13 &= 0xFE  /* Set MMC CS "low" */
#define CK_H()      PORTBbits.RB15 |= 0x02  /* Set MMC SCLK "high" */
#define CK_L()      PORTBbits.RB15 &= 0xFD  /* Set MMC SCLK "low" */
#define DI_H()      PORTBbits.RB14 |= 0x04  /* Set MMC DI "high" */
#define DI_L()      PORTBbits.RB14 &= 0xFB  /* Set MMC DI "low" */
#define DO      (PORTBbits.RB12 & 0x08) /* Test for MMC DO ('H':true, 'L':false) */

位运算符已经存在,我只是添加了 PORTBbits.RBxx。

这就是我所做的所有更改,但我发现在线查找有关使用任何库进行 SD 卡操作的信息特别困难(FatFS 和 MDDFS)。任何帮助将不胜感激!

4

1 回答 1

1

排序。很多东西都发生了变化,所以请注意这个空间,我很快就会上传代码和一些信息,希望它能在这种情况下帮助其他人。

于 2013-05-17T15:09:01.443 回答