You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AVR128DB28与SD卡SPI通信异常问题求助

AVR128DB28与SD卡SPI通信CMD0响应异常问题

开发背景与问题现象

使用Microchip Studio以C语言开发AVR128DB28单片机与SD卡的SPI通信,通过MPLAB SNAP经UPDI完成编程。程序改编自SD卡SPI接口教程,核心异常点如下:

  • 发送CMD0(用于将SD卡切换至空闲状态)后,预期获得R1格式的0x01响应,实际返回0
  • 断电重启SD卡后,返回值为0b00010111,对应标志位包括:擦除序列错误、非法命令、擦除重置、处于空闲状态

完整代码

/*
 * AVR128_sdcardTEST.c
 *
 * Created: 15.04.2024 14:52:31
 * Author : Komputer_3
 */ 

#include <avr/io.h>
#include <avr/delay.h>
#include <stdint-gcc.h>

#define SPI_PORT    PORTA
#define MOSI        PIN4_bm
#define MISO        PIN5_bm
#define SCK         PIN6_bm
#define CS          PIN7_bm

#define CS_ENABLE()     SPI_PORT.OUTCLR = CS
#define CS_DISABLE()    SPI_PORT.OUTSET = CS

#define CMD0        0
#define CMD0_ARG    0x00000000
#define CMD0_CRC    0x94

uint8_t SPI_transfer(uint8_t data){
    SPI0.DATA = data;
    while (!(SPI0.INTFLAGS & SPI_IF_bm));
    return SPI0.DATA;
}

void SDC_powerUp(void){
    CS_DISABLE();
    _delay_ms(1);
    for(uint8_t i=0; i<10; i++){
        SPI_transfer(0xff);
    }
    CS_DISABLE();
    SPI_transfer(0xff);
}

void SDC_command(uint8_t cmd, uint32_t arg, uint8_t crc){
    SPI_transfer((cmd & 127) | 64); //0b01xxxxxx
    
    SPI_transfer((uint8_t)(arg >> 24));
    SPI_transfer((uint8_t)(arg >> 16));
    SPI_transfer((uint8_t)(arg >> 8));
    SPI_transfer((uint8_t)(arg));
    
    SPI_transfer(crc | 1);  //0bxxxxxxx1
}

uint8_t SDC_readRes1(){
    uint8_t i = 0, res1;
    // 轮询直到收到有效数据
    while((res1 = SPI_transfer(0xFF)) == 0xFF){ // 异常:返回0而非预期的1
        i++;

        // 若连续8字节无数据则退出
        if(i > 8) break;
    }

    return res1;
}

uint8_t SD_goIdle(){
    // 拉低CS前发送空字节
    SPI_transfer(0xFF);
    CS_ENABLE();
    SPI_transfer(0xFF);

    // 发送CMD0命令
    SDC_command(CMD0, CMD0_ARG, CMD0_CRC);

    // 读取响应
    uint8_t res1 = SDC_readRes1();

    // 释放CS后发送空字节
    SPI_transfer(0xFF);
    CS_DISABLE();
    SPI_transfer(0xFF);

    return res1;
}

int main(void)
{
    _PROTECTED_WRITE(CLKCTRL.OSCHFCTRLA,  (CLKCTRL.OSCHFCTRLA & (~CLKCTRL_FRQSEL_gm)) | CLKCTRL_FRQSEL_24M_gc);
    
    SPI_PORT.DIRSET = MOSI | SCK | CS;
    SPI_PORT.DIRCLR = MISO;
    
    PORTD.DIRSET = PIN1_bm | PIN2_bm | PIN3_bm | PIN4_bm | PIN5_bm;
    
    SPI0.CTRLA =    (1 << SPI_MASTER_bp)    |       // 主机模式
                    (0 << SPI_DORD_bp)      |       /* 数据发送方向: 0-MSB优先, 1-LSB优先 */
                    (1 << SPI_CLK2X_bp)     |       /* 双倍速度模式 */
                    SPI_PRESC_DIV4_gc       |       /* 预分频器配置 */
                    SPI_ENABLE_bm;                  /* 使能SPI模块 */
    SPI0.CTRLB = SPI_SSD_bm | SPI_MODE_0_gc;
    /* 配置Slave Disable引脚:非多主机模式下需设置此位,此时CS/SS引脚不受SPI寄存器自动控制,由手动引脚电平切换实现片选 */
    
    _delay_ms(500);
    
    SDC_powerUp();
    uint8_t res1 = SD_goIdle();
    if(res1 == 1){
        PORTD.OUTSET = PIN5_bm;
    }
    else{
        PORTD.OUTSET = res1 & 0b00001111;
        _delay_ms(1500);
        PORTD.OUTCLR = 0b00001111;
        PORTD.OUTSET = (res1 >> 4) & 0b00001111;
    }
    
    while (1) 
    {
    }
}

参考文档

AVR128DB28官方芯片数据手册


内容的提问来源于stack exchange,提问作者n0rmi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:47:06