FSInit()-“CE_BAD_PARTITION”

电器工程 图片 spi sd 胖的
2022-01-13 16:21:48

我正在使用 PIC18F26K80 和 XC8 编译器。我正在尝试初始化 SD 卡并创建文件。我只是在 Windows 上将 SD 卡格式化为“FAT32”文件系统和 512 字节的“分配单元大小”。SD卡的容量为2GB。我正在使用 MLA Legacy 版本的 MDD 库。我的主要内容如下:

FSFILE * file;
char sendBuffer[22] = "This is test string 1";

//**************************************************
// main function
//**************************************************

int main()
{
    initIO();
    LATBbits.LATB0 = 0;

    // Initialise SPI and SD-card
    while ( !MDD_MediaDetect() );

    // Initialize the device
    while ( !FSInit() );

    // Initialize 
#ifdef ALLOW_WRITES

    // Create a new file
    file = FSfopenpgm ( "FILE.TXT", "w" );
    if ( file == NULL )
        while(1);

    // Write 21 1-byte objects from sendBuffer into the file
    if ( FSfwrite ( (void *) sendBuffer, 1, 21, file ) != 21 )
        while(1);

    // Close the file
    if ( FSfclose ( file ) )
        while(1);

#endif

    LATBbits.LATB0 = 1;         //LED

    while(1) {}

    return (0);
} 

程序卡在函数“FSInit()”中,我从函数中得到的错误是“CE_BAD_PARTITION”,意思是“引导记录错误”。

“initIO()”函数如下:

//==============================================================================
// void initIO( void );
//==============================================================================
// Sets the pins on the PIC to input or output and determines the speed of the
// internal oscilaltor
// input: none
// return: none
//==============================================================================
void initIO()
{
    OSCCON = 0x75;                  // Clock speed = 32MHz (4x8Mhz)

    TRISA = 0;
    TRISB = 0;
    TRISC = 0;

    TRISBbits.TRISB0 = 0;           //LED

    TRISCbits.TRISC3 = 0;           // set SCL pin as output
    TRISCbits.TRISC4 = 1;           // set RC4 pin as input
    TRISCbits.TRISC5 = 0;
    TRISAbits.TRISA5 = 0;
}

扇区 0 的最后两个字节是引导签名,它们应该是 0x55 和 0xAA,我包含的图片证实了这一点。但是,在“LoadMBR”函数内部进行了以下检查:

if((Partition->Signature0 != FAT_GOOD_SIGN_0) || (Partition->Signature1 != FAT_GOOD_SIGN_1))
{
    FSerrno = CE_BAD_PARTITION;
    error = CE_BAD_PARTITION;
}
else
{
    ...
}

尽管字节相同,但满足第一个条件并返回“CE_BAD_PARTITION”错误。

3个回答

您没有提供足够的代码来帮助调试它,但谷歌搜索您发布的片段显示它来自 FAT16 库的一部分。

查看您发布的分区表

000001c0 03 00 0b e7 39 ee 80 00 00 00 00 90 3a 00 00 00 |....9.......:...|
000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |......|

这是标志 0x00、CHS 0/3/0 - CHS 238/231/57 LBA 128 - 3837952 和类型 0xb

类型 0xb 表示 FAT32 分区,所以我的猜测是

1)您的代码拒绝查看它,因为它的分区类型错误,或者

2)不太可能,您的代码对 CHS 值与 LBA 值不匹配感到不安。

尝试将该分区类型设置为 0x6 (FAT16),用正常的 CHS 值(或虚拟 CHS 值)重写分区表,并将分区格式化为 FAT16。

前段时间我尝试过这样的事情,发现 Microchip 的库很困难。有一个名为PetitFAT的 FOSS FAT 系统,我发现它很容易上手。(他的 printf 库也非常适合小型嵌入式平台。)希望对您有所帮助。

首先,不要在 FSInit() 周围做 while()。那只是懒惰。调用它并检查结果并相应地处理它,这样您的程序就不会陷入无限的未知循环。

其次,您是否查看了 'FAT_GOOD_SIGN_0' 和 'FAT_GOOD_SIGN_1' 的定义,以确保它们期待 0x55 和 0xAA?

第三,你检查过签名字节的顺序吗?FAT-32 正在寻找 0xAA55,而不是 0x55AA。