zoukankan      html  css  js  c++  java
  • [笔记].菜农M0助学板之读SD卡块内容小练(库操作方式)

    已发贴至:http://bbs.21ic.com/icview-231086-1-1.html

    之前是移植到Nios II上,而且是用得IO模拟的,现在使用nuc1xx的spi核做的,不过还是参考了新唐的例程。关于sd的一些笔记,我贴在博客了。今天在此就不赘述了。http://www.cnblogs.com/yuphone/category/272287.html

    上代码先。

    main.h

    #ifndef __MAIN_H__
    #define __MAIN_H__
    
    #include <stdio.h>
    
    /*********************************************************
    * 系统寄存器映射及库头文件
    *********************************************************/
    #include "NUC1xx.h" // 系统寄存器映射
    #include "DrvSYS.h"
    #include "DrvGPIO.h"
    #include "DrvUART.h"
    #include "DrvSPI.h"
    #include "sd_card.h"
    /**********************************************************
    * 自定义宏
    **********************************************************/
    #define APP_DEBUG
    
    #ifdef APP_DEBUG
        #define DEBUG printf
    #else
        #define DEBUG(...) 
    #endif
    
    typedef enum{NO=0, YES=!NO}bool;
    
    #endif /* __MAIN_H__ */

    main.c

    #include "main.h"
    /**********************************************************
    * 变量申明
    **********************************************************/
    volatile bool g_tmr0_5ms = NO;
    /**********************************************************
    * 函数申明
    **********************************************************/
    extern char GetChar(void);
    extern void PFN_UART_CALLBACK(void);
    /**********************************************************
    * 系统上电初始化
    **********************************************************/
    void MAIN_INIT(void)
    {
        UNLOCKREG();
        {   /* 配置系统时钟 */
            SYSCLK->PWRCON.XTL12M_EN = 1; //  设定12M外部晶振
            DrvSYS_Delay(5000); // 等待时钟就绪
            DrvSYS_SelectPLLSource(E_SYS_EXTERNAL_12M); // 选择12MHz为PLL输入
            DrvSYS_Open(50000000); // 打开50MHz
        }      
        {   /* 配置串口 */
            STR_UART_T param;
            
            DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC, 0); //使能UART时钟
            DrvGPIO_InitFunction(E_FUNC_UART0);    // 复用功能引脚设置
                                                             
            param.u32BaudRate        = 115200;    // 波特率
            param.u8cDataBits        = DRVUART_DATABITS_8;  // 数据位
            param.u8cStopBits        = DRVUART_STOPBITS_1;  // 停止位
            param.u8cParity          = DRVUART_PARITY_NONE;    // 校验位
            param.u8cRxTriggerLevel  = DRVUART_FIFO_1BYTES;    // FIFO存储深度1字节
            param.u8TimeOut             = 0; // FIFO超时设定
            DrvUART_Open(UART_PORT0, &param); // 串口开启、结构体整体赋值
            
            // 串口的中断类型比较丰富,此处仅打开接收中断
            DrvUART_EnableInt(UART_PORT0, DRVUART_RDAINT, (PFN_DRVUART_CALLBACK*)PFN_UART_CALLBACK);
            DrvUART_ClearIntFlag(UART_PORT0, DRVUART_RDAINT);
        }
        {   /* 配置GPIO */
            NVIC_DisableIRQ(GPAB_IRQn);
            NVIC_DisableIRQ(GPCDE_IRQn);
            DrvGPIO_Open(E_GPB, 10, E_IO_OUTPUT); // 蜂鸣器 
            DrvGPIO_ClrBit(E_GPB, 10); // 关蜂鸣器
        }
        {   /* 配置TMR0 */
            NVIC_DisableIRQ(TMR0_IRQn);
            // 第一步 使能和选择定时器时钟源及使能定时器模块          
            SYSCLK->CLKSEL1.TMR0_S = 0; // 选择12Mhz作为定时器时钟源 
            SYSCLK->APBCLK.TMR0_EN =1;  // 使能定时器0
            TIMER0->TCSR.CEN = 1;       // 使能定时器模块
            // 第二步 选择操作模式    
            TIMER0->TCSR.MODE = 1; // 选择周期模式
            TIMER0->TCSR.CRST = 1; // 清加1计数器    
            // 第三步 输出时钟周期 = 定时器时钟源周期*(8位预分频因子 + 1) * (24位比较因子TCMP)
            TIMER0->TCSR.PRESCALE = 11; // 12分频
            TIMER0->TCMPR = 5000; // 12M/12/5000=200Hz, 5ms
            // 第四步 使能中断
            TIMER0->TISR.TIF = 1; // 清中断  
            TIMER0->TCSR.IE = 1; // 使能中断 
            NVIC_EnableIRQ(TMR0_IRQn);  // 使能TMR0中断
            // 第五步 使能定时器模块
            TIMER0->TCSR.CRST = 1; // 复位向上计数器
            TIMER0->TCSR.CEN = 1; // 使能TMR0
            //TIMER0->TCSR.TDR_EN=1; // 无需读取加1计数器值
        }
    //    {   /* 配置SPI0主机模式 */
    //        NVIC_DisableIRQ(SPI0_IRQn);
    //        // 第一步 使能SPI0核
    //        SYSCLK->APBCLK.SPI0_EN        =1;
    //        SYS->IPRSTC2.SPI0_RST         =1;
    //        SYS->IPRSTC2.SPI0_RST         =0;
    //        // 第二步 设置除GPIO外的第一功能
    //        SYS->GPCMFP.SPI0_SS0_I2SLRCLK =1;
    //        SYS->GPCMFP.SPI0_CLK_I2SBCLK  =1;        
    //        SYS->GPCMFP.SPI0_MISO0_I2SDI  =1;    
    //        SYS->GPCMFP.SPI0_MOSI0_I2SDO  =1;
    //        SYS->GPBMFP.TM2_SS01          =1;
    //        // 第三步 设置除GPIO外的第二功能
    //        SYS->ALTMFP.PC0_I2SLRCLK      =0;
    //        SYS->ALTMFP.PC1_I2SBCLK       =0;
    //        SYS->ALTMFP.PC2_I2SDI         =0;
    //        SYS->ALTMFP.PC3_I2SDO         =0;
    //        SYS->ALTMFP.PB10_S01          =1;
    //        // 第四步 配置SPI0模式
    //        SPI0->CNTRL.SLAVE = 0; // 0 主机模式;1 从机模式
    //        SPI0->CNTRL.CLKP = 0; // 0 SCLK低电平闲置;1 SCLK高电平闲置
    //        SPI0->CNTRL.TX_NEG = 0; // 0 上升沿传输;1 下降沿传输
    //        SPI0->CNTRL.TX_BIT_LEN = 8; // [0 31] 一次传输8位
    //        SPI0->CNTRL.TX_NUM = 0; // 0 每次传输完成一次收/发;1 每次传输完成两次收/发
    //        SPI0->CNTRL.LSB = 0; // 0 优先发送MSB;1 优先发送LSB
    //        // 第六步 配置从机选择
    //        SPI0->SSR.AUTOSS = 1; // 0 设置或清除SSR.SSR来决定是否产生从机选择信号
    //                              // 1 CNTRL.GO_BUSY设置后,SSR.SSR会由SPI核自动产生,只要一次收/发完成后结束
    //        SPI0->SSR.SS_LVL = 0; // 0 高电平/上升沿有效;1 低电平/下降沿有效
    //        // 第五步 设置时钟输出频率
    //        // 设置SPI0的时钟分频器
    //        SPI0->DIVIDER.DIVIDER = (uint16_t)((((DrvSYS_GetHCLKFreq()/2000000) + 1) >> 1) - 1); // 2MHz 
    //        // 设置SPI0的第二个时钟分频器
    //        // SPI0->DIVIDER.DIVIDER2 = (uint16_t)((((DrvSYS_GetHCLKFreq()/10000) + 1) >> 1) - 1); // 10kHz
    //        SPI0->DIVIDER.DIVIDER2 = 0;
    //        // 第六步
    //        SPI0->TX[0] = 0; // 清TX[0]
    //        // SPI0->TX[1] = 0; // 清TX[1]
    //        SPI0->CNTRL.GO_BUSY = 1; // 触发一次SPI传输
    //        // 第七步 设置中断
    //        //SPI0->CNTRL.IE = 0; // 0 失能中断;1 使能中断
    //        //SPI0->CNTRL.IE = 1; // 写1清中断标志
    //        //NVIC_EnableIRQ(SPI0_IRQn);
    //        
    //    }
        LOCKREG();
    }
    /**********************************************************
    * TMR0 ISR
    **********************************************************/
    void TMR0_IRQHandler(void) __irq
    {   // 注意:ISR内必须清中断
        TIMER0->TISR.TIF = 1; // 清中断  
    
        g_tmr0_5ms = YES;   
    }
    /**********************************************************
    * UART0 回调函数
    **********************************************************/
    void PFN_UART_CALLBACK(void)
    {   // 注意:回调函数内无须清中断
        switch(GetChar()) {        
            default: 
                DEBUG("test");
                break;        
        }            
    }
    /**********************************************************
    * 主函数
    **********************************************************/
    int main(void)
    {
        MAIN_INIT(); // 上电初始化系统
        SD_CARD_Open();
        SD_CARD_DEMO();  
        
        while(1) {
            if(g_tmr0_5ms != NO) {
                g_tmr0_5ms = NO;
            }
    
            if(0) break; // 跳出大循环
        }
        
        SD_CARD_Close();
        DrvUART_Close(UART_PORT0);
        return 0;
    }
    

    sd_card.h

    #ifndef SD_CARD_H_
    #define SD_CARD_H_
    
    #include "main.h"
    
    #define ENABLE_SD_CARD_DEBUG // 打开调试信息
    // debug switch
    #ifdef ENABLE_SD_CARD_DEBUG
        #define SD_CARD_DEBUG    DEBUG
    #else
        #define SD_CARD_DEBUG(...)
    #endif
    
    
    uint8_t SD_CARD_SPI_Transfer(uint8_t byte);
    uint8_t SD_CARD_Init(void);
    //
    void SD_CARD_Open(void);
    void SD_CARD_Close(void);
    uint8_t SD_CARD_Write_Sector(uint32_t addr,uint8_t *buf);
    uint8_t SD_CARD_Read_Sector(uint8_t *CMD,uint8_t *buf,uint16_t n_bytes);
    uint8_t SD_CARD_Read_Sector_Start(uint32_t sector);
    static void SD_CARD_Read_Data(uint16_t n_bytes,uint8_t *buf);
    void SD_CARD_Read_Data_LBA(uint32_t LBA,uint16_t n_bytes,uint8_t *buf);
    void SD_CARD_Read_Sector_End(void);
    static uint8_t SD_CARD_Read_CSD(uint8_t *buf);
    static uint8_t SD_CARD_Read_CID(uint8_t *buf);
    void SD_CARD_Get_Info(void);
    void SD_CARD_DEMO(void);
    
    
    #endif /* SD_CARD_H_ */
    

    sd_card.c

    #include "sd_card.h"
    
    // 错误宏定义
    #define INIT_CMD0_ERROR     0x01
    #define INIT_CMD1_ERROR     0x02
    #define WRITE_BLOCK_ERROR   0x03
    #define READ_BLOCK_ERROR    0x04
    
    #define Delay_Us DrvSYS_Delay // us级延时
    #define SD_CARD_Set_nCS DrvSPI_ClrSS(eDRVSPI_PORT1, eDRVSPI_SS0) // nCS = 1
    #define SD_CARD_Clr_nCS DrvSPI_SetSS(eDRVSPI_PORT1, eDRVSPI_SS0) // nCS = 0
    
    typedef union{
        uint8_t data[16];
        struct{
            uint8_t MID;    // Manufacture ID; Binary
            uint8_t OLD[2]; // OEM/Application ID; ASCII
            uint8_t PNM[5]; // Product Name; ASCII
            uint8_t PRV;    // Product Revision; BCD
            uint8_t PSN[4]; // Serial Number; Binary
            uint8_t MDT[2]; // Manufacture Data Code; BCD; upper 4 bits of first byte are reserved
            uint8_t CRC;    // CRC7_checksum; Binary; LSB are reserved
        }CID;
    }CID_Info_STR;
    
    typedef struct{
        uint8_t data[16];
        uint32_t capacity_MB;
        uint8_t READ_BL_LEN;
        uint16_t C_SIZE;
        uint8_t C_SIZE_MULT;
    }CSD_Info_STR;
    
    uint16_t gByteOffset=0; // 某字节在扇区内的偏移地址
    uint16_t gSectorOffset=0; // 扇区在SD卡内的偏移地址
    uint8_t gSectorOpened = 0; // 0 关闭扇区;1 打开扇区
    
    // 打开SD卡
    void SD_CARD_Open(void)
    {
        DrvSYS_SetIPClock(E_SYS_SPI1_CLK,1);
        DrvGPIO_InitFunction(E_FUNC_SPI1); // enable SPI funztion and pin 
        
        DrvSPI_Open(eDRVSPI_PORT1,eDRVSPI_MASTER,eDRVSPI_TYPE1,8, FALSE);
        DrvSPI_DisableAutoSS(eDRVSPI_PORT1);
        DrvSPI_SetSlaveSelectActiveLevel(eDRVSPI_PORT1, eDRVSPI_ACTIVE_LOW_FALLING);
        DrvSPI_SetEndian(eDRVSPI_PORT1, eDRVSPI_MSB_FIRST);
        DrvSPI_SetClockFreq(eDRVSPI_PORT1,300000,0);
        
        while(SD_CARD_Init() != 0x55);
        SD_CARD_DEBUG(("SD卡初始化完成\r"));
       
        DrvSPI_SetClockFreq(eDRVSPI_PORT1,10000000,0);
    }
    
    
    // 关闭SD卡
    void SD_CARD_Close(void)
    {
        DrvSPI_Close(eDRVSPI_PORT1);
    }
    
    
    // 收发一个字节
    static uint8_t SD_CARD_SPI_Transfer(uint8_t byte)
    {
        uint32_t SPIdata=(uint32_t)byte;
        DrvSPI_BurstTransfer(eDRVSPI_PORT1,1,2);
        DrvSPI_SingleWrite(eDRVSPI_PORT1,&SPIdata);
        while (DrvSPI_IsBusy(eDRVSPI_PORT1));
        DrvSPI_DumpRxRegister(eDRVSPI_PORT1,&SPIdata,1);
        return (uint8_t)SPIdata;
    }
    
    
    // SD卡写命令
    static uint8_t SD_CARD_Write_CMD(uint8_t *CMD)
    {
        uint8_t temp,retry;
        uint8_t i;
    
        SD_CARD_Set_nCS; // 失能SD卡
        SD_CARD_SPI_Transfer(0xFF); // 发8个脉冲
        SD_CARD_Clr_nCS; // 使能SD卡
    
        // 写6个字节到SD卡
        for(i=0;i<6;i++) SD_CARD_SPI_Transfer(*CMD++);
    
        // 读取16位响应
        SD_CARD_SPI_Transfer(0xFF); // 第一个字节无效
        retry=0;
        do{ // 只取最后一个字节
            temp=SD_CARD_SPI_Transfer(0xFF);
            retry++;
        }while((temp==0xFF) && (retry<100));
        
        return temp;
    }
    
    
    // 初始化SD卡;SPI模式
    static uint8_t SD_CARD_Init(void)
    {
        uint8_t retry,temp;
        uint8_t i;
        uint8_t CMD[]={0x40,0x00,0x00,0x00,0x00,0x95};
    
        SD_CARD_Set_nCS;
        Delay_Us(10*1000);    
        for(i=0;i<10;i++) // 最少先发74个脉冲
            SD_CARD_SPI_Transfer(0xFF);
        SD_CARD_Clr_nCS;
    
        retry=0;
        do{
            temp=SD_CARD_Write_CMD(CMD);
            retry++;
            if(retry==200) 
                return INIT_CMD0_ERROR;
        }while(temp!=1);
    
        CMD[0]=0x41;// CMD[1]
        CMD[5]=0xFF;
        retry=0;
        do{ 
            temp=SD_CARD_Write_CMD(CMD);
            retry++;
            if(retry==100)    
                return INIT_CMD1_ERROR;
        }while(temp!=0);
    
        SD_CARD_Set_nCS; // 失能SD卡
        
        return 0x55; // 初始化完成
    }
    
    
    // 写入一个块(扇区)
    uint8_t SD_CARD_Write_Sector(uint32_t addr,uint8_t *buf)
    {
        uint8_t temp,retry;
        uint16_t i;
        uint8_t CMD[]={0x58,0x00,0x00,0x00,0x00,0xFF}; // CMD24
    
        // 地址转换:逻辑块(扇区)地址 --> 字节地址
        addr=addr << 9;
        CMD[1]=((addr & 0xFF000000) >>24 );
        CMD[2]=((addr & 0x00FF0000) >>16 );
        CMD[3]=((addr & 0x0000FF00) >>8 );
    
    
        retry=0;
        do{ 
            temp=SD_CARD_Write_CMD(CMD);
            retry++;
            if(retry==100) 
                return temp;
        } while(temp!=0);
    
        // 写数据前,先发100个脉冲;100/8=13
        for(i=0;i<13;i++) SD_CARD_SPI_Transfer(0xFF);
    
        // 写入开始字节
        SD_CARD_SPI_Transfer(0xFE);
    
        // 写入512个字节
        for(i=0;i<512;i++) SD_CARD_SPI_Transfer(*buf++);
    
        SD_CARD_SPI_Transfer(0xFF); // 假读;读取CRC
        SD_CARD_SPI_Transfer(0xFF); // 假读;读取CRC
    
        // 读取响应
        temp=SD_CARD_SPI_Transfer(0xFF);
        if( (temp & 0x1F)!=0x05 ) {// 数据被接收否?    
            SD_CARD_Set_nCS; // 失能SD卡        
            return WRITE_BLOCK_ERROR;
        }
    
        // 等待,只到SD卡不忙
        while(SD_CARD_SPI_Transfer(0xFF)!=0xFF);
    
        SD_CARD_Set_nCS; // 失能SD卡
        
        return 0;
    }
    
    
    // 读取块(扇区)内的字节(一般情况下,1块对应512字节)
    uint8_t SD_CARD_Read_Sector(uint8_t *CMD,uint8_t *buf,uint16_t n_bytes)
    {
        uint16_t i;
        uint8_t retry,temp;
    
        retry=0;
        do{ 
            temp=SD_CARD_Write_CMD(CMD);
            retry++;
            if(retry==100) 
                return READ_BLOCK_ERROR;
        }while(temp!=0);
    
        // 读开始字节(0xFEh)
        while(SD_CARD_SPI_Transfer(0xFF)!=0xFE);
        
        // 读取n个字节
        for(i=0;i<n_bytes;i++) *buf++=SD_CARD_SPI_Transfer(0xFF);
    
        SD_CARD_SPI_Transfer(0xFF); // 假读;读取CRC
        SD_CARD_SPI_Transfer(0xFF); // 假读;读取CRC
    
        SD_CARD_Set_nCS; // 失能SD卡
        
        return 0;
    }
    
    
    // 开始读取某个扇区
    uint8_t SD_CARD_Read_Sector_Start(uint32_t sector)
    {
        uint8_t retry;
        uint8_t CMD[]={0x51,0x00,0x00,0x00,0x00,0xFF}; // CMD16
        uint8_t temp;
    
        // 地址转换:逻辑块(扇区)地址 --> 字节地址
        sector=sector << 9;
        CMD[1]=((sector & 0xFF000000) >>24 );
        CMD[2]=((sector & 0x00FF0000) >>16 );
        CMD[3]=((sector & 0x0000FF00) >>8 );
    
        retry=0;
        do{
            temp=SD_CARD_Write_CMD(CMD);
            retry++;
            if(retry==100) 
                return READ_BLOCK_ERROR;
        }while(temp!=0);
    
        // 读开始字节(0xFEh)
        while(SD_CARD_SPI_Transfer(0xFF) != 0xFE);
    
        gSectorOpened = 1; // 将扇区打开标志置一
        
        return 0;
    }
    
    
    static void SD_CARD_Read_Data(uint16_t n_bytes, uint8_t *buf)
    {
        uint16_t i;
        for(i=0; ((i<n_bytes) && (gByteOffset<512)); i++) {
            *buf++ = SD_CARD_SPI_Transfer(0xFF);
            gByteOffset++; // 读完一个字节;将扇区内的字节偏移地址加一
        }
        if(gByteOffset == 512) {
            gByteOffset=0; // 将扇区内的字节偏移地址清零
            
            SD_CARD_SPI_Transfer(0xFF); // 假读;读取CRC
            SD_CARD_SPI_Transfer(0xFF); // 假读;读取CRC
            
            gSectorOffset++; // 读完一个扇区;将SD卡内的扇区偏移地址加一
            
            gSectorOpened = 0; // 读完一个扇区后,扇区打开标志清零
            SD_CARD_Set_nCS; // 失能SD卡
        }
    }
    
    
    // 读取指定逻辑块地址(扇区偏移地址)内的数据;logic block address,LBA
    void SD_CARD_Read_Data_LBA(uint32_t LBA,uint16_t n_bytes,uint8_t *buf)
    {   // 如果某扇区被读完,则打开下一个扇区
        if(gByteOffset == 0) while(SD_CARD_Read_Sector_Start(LBA));
        SD_CARD_Read_Data(n_bytes,buf);
    }
    
    
    // 假读;读完某扇区内剩余的字节
    void SD_CARD_Read_Sector_End(void)
    {
        uint8_t temp[1];
        while((gByteOffset!=0x00) | (gSectorOpened==1))
            SD_CARD_Read_Data(1,temp); // 假读
    }
    
    
    // 读SD卡的CSD寄存器
    static uint8_t SD_CARD_Read_CSD(uint8_t *buf)
    { 
        uint8_t CMD[]={0x49,0x00,0x00,0x00,0x00,0xFF};
        return SD_CARD_Read_Sector(CMD,buf,16); // 读取16个字节
    }
    
    
    // 读SD卡的CID寄存器
    static uint8_t SD_CARD_Read_CID(uint8_t *buf)
    { 
        uint8_t CMD[]={0x4A,0x00,0x00,0x00,0x00,0xFF};
        return SD_CARD_Read_Sector(CMD,buf,16); // 读取16个字节
    }
    
    
    void SD_CARD_Get_Info(void)
    {
        CID_Info_STR CID;
        CSD_Info_STR CSD;
    
        SD_CARD_Read_CID(CID.data);
        SD_CARD_DEBUG("SD-CARD CID:\r");
        SD_CARD_DEBUG("    Manufacturer ID(MID): 0x%.2X\r", CID.CID.MID);
        SD_CARD_DEBUG("    OEM/Application ID(OLD): %c%c\r", CID.CID.OLD[0], CID.CID.OLD[1]);
        SD_CARD_DEBUG("    Product Name(PNM): %c%c%c%c%c\r", CID.CID.PNM[0], CID.CID.PNM[1], CID.CID.PNM[2], CID.CID.PNM[3], CID.CID.PNM[4]);
        SD_CARD_DEBUG("    Product Revision: 0x%.2X\r", CID.CID.PRV);
        SD_CARD_DEBUG("    Serial Number(PSN): 0x%.2X%.2X%.2X%.2X\r", CID.CID.PSN[0], CID.CID.PSN[1], CID.CID.PSN[2], CID.CID.PSN[3]);
        SD_CARD_DEBUG("    Manufacture Date Code(MDT): 0x%.1X%.2X\r", CID.CID.MDT[0] & 0x0F, CID.CID.MDT[1]);
        SD_CARD_DEBUG("    CRC-7 Checksum(CRC7):0x%.2X\r", CID.CID.CRC >> 1);
    
        SD_CARD_Read_CSD(CSD.data);
        CSD.C_SIZE = ((CSD.data[6]&0x03) << 10) | (CSD.data[7] << 2) | ((CSD.data[8]&0xC0) >>6);
        CSD.C_SIZE_MULT = ((CSD.data[9]&0x03) << 1) | ((CSD.data[10]&0x80) >> 7);
        CSD.READ_BL_LEN = (CSD.data[5]&0x0F);
        CSD.capacity_MB = (((CSD.C_SIZE)+1) << (((CSD.C_SIZE_MULT) +2) + (CSD.READ_BL_LEN))) >> 20;
        SD_CARD_DEBUG("SD-CARD CSD:\r");
        SD_CARD_DEBUG("    max.read data block length: %d\r", 1<<CSD.READ_BL_LEN);
        SD_CARD_DEBUG("    device size: %d\r", CSD.C_SIZE);
        SD_CARD_DEBUG("    device size multiplier: %d\r", CSD.C_SIZE_MULT);
        SD_CARD_DEBUG("    device capacity: %d MB\r", CSD.capacity_MB);
    }
    
    
    void SD_CARD_DEMO(void)
    {
        uint16_t i;
        uint8_t buf[512];
        
        SD_CARD_DEBUG("\r");    
        SD_CARD_DEBUG("开始读取SD卡信息\r");   
        SD_CARD_Get_Info(); // 读取CID和CSD
        SD_CARD_DEBUG("SD卡信息读取完毕\r");
        
        SD_CARD_DEBUG("\r");
        SD_CARD_DEBUG("开始读取SD卡的第一个块(扇区)\r");
        SD_CARD_Read_Data_LBA(0,512,buf); // 读取SD卡的第一个块(扇区)
        for(i=0; i<512; i++) {
            if(i%16 == 0) SD_CARD_DEBUG("0x%.3X ", i);
            SD_CARD_DEBUG("%.2X ", buf[i]);
            if((i+1) % 8 == 0) SD_CARD_DEBUG(" ");
            if((i+1) % 16 == 0) SD_CARD_DEBUG("\r");
        }
        SD_CARD_DEBUG("读取SD卡的第一个块(扇区)完毕\r");
    }
    

     Snap1 Snap2

  • 相关阅读:
    Create C++ Windows Forms Application in Visual Studio 2017
    VS项目打包发布
    获取光标所在行索引
    拖拽生成控件副本
    MDI中的ToolStrip合并
    使用FFmpeg音视频格式转换
    获取项目中其他文件
    解决Winform大多数DPI问题
    《Pro Git》第3章 分支
    《Pro Git》第2章 Git基础
  • 原文地址:https://www.cnblogs.com/yuphone/p/2021549.html
Copyright © 2011-2022 走看看