C 用SPI向SD写入一个块,SD的奇怪响应

C 用SPI向SD写入一个块,SD的奇怪响应,c,embedded,sd-card,spi,C,Embedded,Sd Card,Spi,这是我将512字节的数据块写入SD卡的代码。代码工作正常,但当我检查一切正常时(通过SD读取响应),我读取了0xFF 该值应类似于(来自SD参考手册): 代码如下: uint8_t SdCard_SendBlock(uint32_t block, uint8_t * data) { switch (sd_write_blk_machine.fields.state) { case WRITE_START: //Enable Card GPIOC_PDOR &

这是我将512字节的数据块写入SD卡的代码。代码工作正常,但当我检查一切正常时(通过SD读取响应),我读取了
0xFF

该值应类似于(来自SD参考手册):

代码如下:

uint8_t SdCard_SendBlock(uint32_t block, uint8_t * data) 
{   


switch (sd_write_blk_machine.fields.state)
{

case WRITE_START:

    //Enable Card
    GPIOC_PDOR &= ~GPIO_PDOR_PDO(GPIO_PIN(10));

    sd_cmd_arg.sd_cmd_tot_argument = block << SD_BLOCK_SHIFT;
    sd_write_blk_machine.fields.state = WRITE_SEND_CMD24;

    /*INIZIALIZZO LE VARIABILI LOCALI*/
    write_send_data_counter = 0;
    sd_cmd_machine.sd_cmd_machine = 0;
    break;

case WRITE_SEND_CMD24:
    send_command_return = SdSendCmd(CMD24|0x40,ASPECTED_OK_RESPONSE);

        if( send_command_return == SDCARD_CMD_FAILS)
        {
            //Disable Card
            GPIOC_PDOR |= GPIO_PDOR_PDO(GPIO_PIN(10));
            sd_write_blk_machine.fields.complete = 1;
            system_error.flags.sdcard_error = SDCARD_WRITE_FAIL;
            return(SDCARD_WRITE_FAIL);      
        }
        sd_write_blk_machine.fields.state = WRITE_SEND_START_TOKEN;
    }
    break;

case WRITE_SEND_START_TOKEN:
    Spi_writeData(SPI0,SD_TOK_WRITE_SBLOCK); //SD_TOK_WRITE_SBLOCK = 0xFE , 

        spi_control_machine.spi_control_machine = 0;
        sd_write_blk_machine.fields.state = WRITE_SEND_DATA;

    break;

case WRITE_SEND_DATA:

    if (write_send_data_counter < SDCARD_BLOCK_SIZE) //SDCARD_BLOCK_SIZE = 512 byte
            {
                Spi_writeData(SPI0, data[write_send_data_counter]);
                {
                    spi_control_machine.spi_control_machine = 0;
                    write_send_data_counter++;
                }
            }
            else
                sd_write_blk_machine.fields.state = WRITE_SEND_IDLE_1;
            break;

case WRITE_SEND_IDLE_1:
    Spi_writeData(SPI0,0xFF); // 0xFF = SPI_IDLE



        sd_write_blk_machine.fields.state = WRITE_SEND_IDLE_2;


    break;

case WRITE_SEND_IDLE_2:
    Spi_writeData(SPI0,0xFF);   // 0xFF = SPI_IDLE


        sd_write_blk_machine.fields.state = WRITE_READ_RESPONSE_TOKEN;

    break;

case WRITE_READ_RESPONSE_TOKEN:
    /*Every data block written to the card will be acknowledged by a data response    token. It is one byte long
    and has the following format:
    x x x 0 Status 1
    The meaning of the status bits is defined as follows:
    010 - Data accepted.
    101 - Data rejected due to a CRC error.
    110 - Data Rejected due to a Write Error*/  



    spi_control_machine.spi_control_machine = 0;
    Spi_readData(SPI0, &write_read_response);   // HERE IS THE PROBLEM !!!! write_read_response = 0xFF

                    if ( (write_read_response & 0x0F) != SD_ACCEPTED_WRITE_DATA )
                    {
                        //disabilita carta
                        GPIOC_PDOR |= GPIO_PDOR_PDO(GPIO_PIN(10));
                        system_error.flags.sdcard_error = SDCARD_WRITE_FAIL;
                        sd_write_blk_machine.fields.complete = 1;
                        SendBlockReturn=0;
                        return (SDCARD_WRITE_FAIL);

                    }


                    sd_write_blk_machine.fields.complete = 1;
                    status.flags.sdwrite_wait_attemp = 1;
                    SendBlockReturn=1;
                    return (TERMINATE_OK);
               break;

    }
uint8\u t SD卡发送块(uint32\u t块,uint8\u t*数据)
{   
开关(sd_write_blk_machine.fields.state)
{
案例写入_开始:
//启用卡
GPIOC_-PDOR&=~GPIO_-PDOR_-PDO(GPIO_引脚(10));

sd_cmd_arg.sd_cmd_tot_argument=block在完成写入之前,卡似乎正在返回0xFF。根据:

只要卡在忙编程,就会向主机发送连续的忙令牌流(有效地保持数据输出线的低位)

也就是说,我不确定为什么卡没有首先返回
'010'已接受的
响应-可能是卡制造商没有遵守规范


您要做的是反复调用Spi_readData,直到返回的字节变为
0
'010'已被接受

如果您查看SD规范上的图表,繁忙的令牌出现在数据响应之后,您看到的是正常的,在发送最后一个字节后,您应该继续读取数据,直到您获得data响应令牌,然后卡将开始编程,在编程完成之前,您将获得忙令牌。卡编程时,您将读取0(数据线保持低位)。在您传输最后一个字节后,我认为规范没有说明数据线的状态,我也总是得到0xFF,但您不应该指望它,所以只需继续检查响应令牌,直到您得到它。

我假设卡初始化运行正常-所有返回均已检查等?是的,SD卡初始化工作正常,CMD24也工作正常…为了尝试,我制作了一个这样的数组:数组[0]=254=11111110//Start Block Token array[1-511]=要发送的随机字节,我尝试发送这个数组
Spi_readData()
是如何实现的?在我看来,您忘了发送另一个伪字节。
uint8_t SdCard_SendBlock(uint32_t block, uint8_t * data) 
{   


switch (sd_write_blk_machine.fields.state)
{

case WRITE_START:

    //Enable Card
    GPIOC_PDOR &= ~GPIO_PDOR_PDO(GPIO_PIN(10));

    sd_cmd_arg.sd_cmd_tot_argument = block << SD_BLOCK_SHIFT;
    sd_write_blk_machine.fields.state = WRITE_SEND_CMD24;

    /*INIZIALIZZO LE VARIABILI LOCALI*/
    write_send_data_counter = 0;
    sd_cmd_machine.sd_cmd_machine = 0;
    break;

case WRITE_SEND_CMD24:
    send_command_return = SdSendCmd(CMD24|0x40,ASPECTED_OK_RESPONSE);

        if( send_command_return == SDCARD_CMD_FAILS)
        {
            //Disable Card
            GPIOC_PDOR |= GPIO_PDOR_PDO(GPIO_PIN(10));
            sd_write_blk_machine.fields.complete = 1;
            system_error.flags.sdcard_error = SDCARD_WRITE_FAIL;
            return(SDCARD_WRITE_FAIL);      
        }
        sd_write_blk_machine.fields.state = WRITE_SEND_START_TOKEN;
    }
    break;

case WRITE_SEND_START_TOKEN:
    Spi_writeData(SPI0,SD_TOK_WRITE_SBLOCK); //SD_TOK_WRITE_SBLOCK = 0xFE , 

        spi_control_machine.spi_control_machine = 0;
        sd_write_blk_machine.fields.state = WRITE_SEND_DATA;

    break;

case WRITE_SEND_DATA:

    if (write_send_data_counter < SDCARD_BLOCK_SIZE) //SDCARD_BLOCK_SIZE = 512 byte
            {
                Spi_writeData(SPI0, data[write_send_data_counter]);
                {
                    spi_control_machine.spi_control_machine = 0;
                    write_send_data_counter++;
                }
            }
            else
                sd_write_blk_machine.fields.state = WRITE_SEND_IDLE_1;
            break;

case WRITE_SEND_IDLE_1:
    Spi_writeData(SPI0,0xFF); // 0xFF = SPI_IDLE



        sd_write_blk_machine.fields.state = WRITE_SEND_IDLE_2;


    break;

case WRITE_SEND_IDLE_2:
    Spi_writeData(SPI0,0xFF);   // 0xFF = SPI_IDLE


        sd_write_blk_machine.fields.state = WRITE_READ_RESPONSE_TOKEN;

    break;

case WRITE_READ_RESPONSE_TOKEN:
    /*Every data block written to the card will be acknowledged by a data response    token. It is one byte long
    and has the following format:
    x x x 0 Status 1
    The meaning of the status bits is defined as follows:
    010 - Data accepted.
    101 - Data rejected due to a CRC error.
    110 - Data Rejected due to a Write Error*/  



    spi_control_machine.spi_control_machine = 0;
    Spi_readData(SPI0, &write_read_response);   // HERE IS THE PROBLEM !!!! write_read_response = 0xFF

                    if ( (write_read_response & 0x0F) != SD_ACCEPTED_WRITE_DATA )
                    {
                        //disabilita carta
                        GPIOC_PDOR |= GPIO_PDOR_PDO(GPIO_PIN(10));
                        system_error.flags.sdcard_error = SDCARD_WRITE_FAIL;
                        sd_write_blk_machine.fields.complete = 1;
                        SendBlockReturn=0;
                        return (SDCARD_WRITE_FAIL);

                    }


                    sd_write_blk_machine.fields.complete = 1;
                    status.flags.sdwrite_wait_attemp = 1;
                    SendBlockReturn=1;
                    return (TERMINATE_OK);
               break;

    }