在STM32F303上使用SPI的SD卡初始化问题

时间:2016-11-25 03:31:21

标签: c microcontroller stm32 spi hal

当我发送CMD0命令(0x40 0x00 0x00 0x00 0x00 0x95)时,我试图在STM32F303上使用SPI初始化SDCard,我试着看一下示波器上来自MOSI的信号我看到了不同的信号如下所示。请注意,SPI速度为281.25kBits / s。任何帮助将不胜感激。

以下是我用来测试MOSI输出的部分代码

(function($){
    "use strict"
    jQuery(function(){
        var $job_types_select = $('<select class="job_types_select"></select>');
        var $job_types_ul = $('form.job_filters ul.job_types');
        var $job_type_hidden = $('<input type="hidden" name="filter_job_type[]"/>');
            $job_types_ul.find('li').each(function(){
                var $li = $(this);
                var label_text = $li.find('label').text();
                var value = $li.find('input:checkbox').val();
                var $option = $('<option></option>');
                $option.text(label_text);
                $option.attr({value: value});
                $job_types_select.append($option);
            });
                $job_types_select.change(function(){
                var value = $(this).val();
                $('input:hidden[name="filter_job_type[]"]').val(value);
                    var target = $(this).closest('div.job_listings');
                    target.triggerHandler('update_results', [ 1, false ]);
                });
        $job_types_ul.after($job_type_hidden);
        $job_types_ul.replaceWith($job_types_select);
    });
})(jQuery);

现在我正在发送正确的命令,我可以在范围内看到它。但是,我没有从SD卡(SanDisk Ultra 40MB / s ... 16GB)得到0x01响应(我一直得到0xff)我正在使用以下代码:

uint8_t cmd0[6]={0x40,0x00,0x00,0x00,0x00,0x95};
FATFS_CS_HIGH;
HAL_SPI_Transmit(&hspi1, (uint8_t*)0xff, 1, 10);
    for(int i=0;i<10;i++)
  {
    HAL_SPI_Transmit(&hspi1, (uint8_t*)0xff, 1, 10);
   }

  FATFS_CS_LOW;

while(1){

      HAL_SPI_Transmit(&hspi1, (uint8_t *)cmd0[0], 1, 10);

      HAL_SPI_Transmit(&hspi1, (uint8_t *)cmd0[1], 1, 10);
      HAL_SPI_Transmit(&hspi1, (uint8_t *)cmd0[2], 1, 10);
      HAL_SPI_Transmit(&hspi1, (uint8_t *)cmd0[3], 1,10);
      HAL_SPI_Transmit(&hspi1,(uint8_t *) cmd0[4], 1, 10);
      HAL_SPI_Transmit(&hspi1, (uint8_t *)cmd0[5], 1, 10);

    }

1 个答案:

答案 0 :(得分:5)

在启动下一个SPI传输之前,您不会等待SPI传输结束。您也不应该逐字节发送缓冲区,您可以在一次调用中发送整个缓冲区。

HAL_SPI_Transmit(&hspi1, cmd0, 6, 10);
while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);

除了在发送下一个字节之前你没有等待的问题之外,你的代码的这部分只是发送了垃圾:

HAL_SPI_Transmit(&hspi1, (uint8_t*)0xff, 1, 10);

for(int i=0;i<10;i++)
{
    HAL_SPI_Transmit(&hspi1, (uint8_t*)0xff, 1, 10);
}

第二个参数是指向数据缓冲区的指针。您的代码不会发送0xff,而是发送位于0xff内存地址的垃圾。

要发送0xff,请执行以下操作:

uint8_t value = 0xff
HAL_SPI_Transmit(&hspi1, &value, 1, 10);
while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);

<强>更新

还有这样的行:

HAL_SPI_Transmit(&hspi1, (uint8_t *)cmd0[0], 1, 10);

也发送垃圾数​​据。

cmd0[0]将返回数组的第一个元素(数据)0x40,然后将其转换为uint8_t*,并将其传递给HAL_SPI_Transmit作为指向数据缓冲区的指针。因此,将要发送的实际数据是0x40内存位置的一些随机值。

例如,数组中某个字节的地址为&cmd[0]。请注意返回地址的&运算符。正确的电话是:

HAL_SPI_Transmit(&hspi1, &cmd0[0], 1, 10);
while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);

所以我建议再次在一次调用中发送整个数组,如上所示。