sd_drive.lis

来自「Atmega64单片机程序(完整工程)」· LIS 代码 · 共 1,540 行 · 第 1/5 页

LIS
1,540
字号
                        .module SD_Drive.c
                        .area lit(rom, con, rel)
 0000           _time_unit::
 0000 00CA9A3B          .word 51712,15258
 0004 00E1F505          .word 57600,1525
 0008 80969800          .word 38528,152
 000C 40420F00          .word 16960,15
 0010 A0860100          .word 34464,1
 0014 10270000          .word 10000,0
 0018 E8030000          .word 1000,0
 001C 64000000          .word 100,0
 0020           _time_value::
 0020 000A              .byte 0,10
 0022 0C0D              .byte 12,13
 0024 0F14              .byte 15,20
 0026 191E              .byte 25,30
 0028 2328              .byte 35,40
 002A 2D32              .byte 45,50
 002C 373C              .byte 55,60
 002E 4650              .byte 'F,'P
 0030           _r2w_fator::
 0030 0102              .byte 1,2
 0032 0408              .byte 4,8
 0034 1020              .byte 16,32
                        .area text(rom, con, rel)
                ;         recbuf -> y+0
                ;            ret -> R10
                        .even
 0000           _SD_Initialize::
 0000 0E940000          xcall push_gset3
 0004 2497              sbiw R28,4
 0006           ; /*--------------File Info-------------------------------------------------------
 0006           ; ** 文   件   名:    SD_Driver.c
 0006           ; ** 最后修改日期:    2008.3.28
 0006           ; ** 版        本:    V1.0
 0006           ; ** 描        述:    sd 卡驱动软件包: 用户API函数                      
 0006           ; **------------------------------------------------------------------------------
 0006           ; ** Created   by:              
 0006           ; ** Created date:                      
 0006           ; *******************************************************************************/
 0006           ; 
 0006           ; #include "SYS_Config.h" 
 0006           ; #include "SD_Config.h" 
 0006           ; #include "SD_Hal.h" 
 0006           ; #include "SD_Cmd.h" 
 0006           ; #include "SD_Drive.h" 
 0006           ; 
 0006           ; 
 0006           ; extern INT8U Data_Buf[SD_BLOCKSIZE];//在main函数中定义
 0006           ; 
 0006           ; 
 0006           ; sd_struct sds ;/* SD卡信息结构体变量  */
 0006           ; 
 0006           ; /* 超时时间单位表(单位:0.000000001ns) timeout unit table */
 0006           ; const INT32U time_unit[8]=
 0006           ; {
 0006           ;     1000000000,100000000,10000000,
 0006           ;     1000000,100000,10000,1000,100 
 0006           ; };
 0006           ; 
 0006           ; /* 超时时间表 timeout value table */
 0006           ; const INT8U time_value[16]=
 0006           ; {
 0006           ;     0,10,12,13,15,20,25,30,35,40,45,50,55,60,70,80 
 0006           ; };
 0006           ; 
 0006           ; /* 超时时间因数表 timeout factor table */
 0006           ; const INT8U r2w_fator[6]=
 0006           ; {
 0006           ;     1,2,4,8,16,32 
 0006           ; };
 0006           ; 
 0006           ; 
 0006           ; /*       
 0006           ; ********************************************************************************
 0006           ; 用户API函数:  初始化,读,写,擦 SD卡 
 0006           ;                               
 0006           ; /******************************************************************************
 0006           ; ** 函数名称: INT8U SD_Initialize()                            
 0006           ; ** 功能描述: 初始化SD卡                                                       
 0006           ; ** 输   入: 无                                                                       
 0006           ; ** 输   出: 0:   正确    >0:   错误码                        
 0006           ; *******************************************************************************/
 0006           ; INT8U SD_Initialize(void)
 0006           ; {
 0006           ;     INT8U recbuf[4],ret ;
 0006           ;     
 0006           ;     SD_HardWareInit();  //初始化读写SD卡的硬件条件 
 0006 0E940000          xcall _SD_HardWareInit
 000A           ;        
 000A           ;     if(!SD_ChkCard())   // 检查卡是否插入
 000A 0E940000          xcall _SD_ChkCard
 000E 0023              tst R16
 0010 11F4              brne L2
 0012           ;         return SD_ERR_NO_CARD ;
 0012 01E0              ldi R16,1
 0014 32C0              xjmp L1
 0016           L2:
 0016           ;     
 0016           ;     SPI_CS_Assert();         /* 1. 置CS为低 assert CS */
 0016 0E940000          xcall _SPI_CS_Assert
 001A           ;     
 001A           ;     SD_SPIDelay(100);        /* 2. 至少延时 74  */
 001A 04E6              ldi R16,100
 001C 0E940000          xcall _SD_SPIDelay
 0020           ;    
 0020           ;     SPI_CS_Deassert();       /* 3. 置CS为高 dessert CS */
 0020 0E940000          xcall _SPI_CS_Deassert
 0024           ;     
 0024           ;     SD_SPIDelay(20);         /* 4. 延时2(8 clock)  */
 0024 04E1              ldi R16,20
 0026 0E940000          xcall _SD_SPIDelay
 002A           ;     
 002A           ;     ret=SD_ResetSD();        /* 5. 发出CMDO命令复位SD卡  */
 002A 0E940000          xcall _SD_ResetSD
 002E A02E              mov R10,R16
 0030           ;     if(ret!=SD_NO_ERR)
 0030 0023              tst R16
 0032 09F0              breq L4
 0034           ;         return ret ;
 0034 22C0              xjmp L1
 0036           L4:
 0036           ;     
 0036           ;     ret=SD_ActiveInit();     /* 6. 激活卡进入初始化过程.  */
 0036 02D4              xcall _SD_ActiveInit
 0038 A02E              mov R10,R16
 003A           ;     if(ret!=SD_NO_ERR)
 003A 0023              tst R16
 003C 09F0              breq L6
 003E           ;         return ret ;
 003E 1DC0              xjmp L1
 0040           L6:
 0040           ;     
 0040           ;     ret=SD_ReadOCR(4,recbuf);/* 7. 读OCR寄存器,查询卡支持的电压值 */
 0040 9E01              movw R18,R28
 0042 04E0              ldi R16,4
 0044 0E940000          xcall _SD_ReadOCR
 0048 A02E              mov R10,R16
 004A           ;     if(ret!=SD_NO_ERR)
 004A 0023              tst R16
 004C 09F0              breq L8
 004E           ;         return ret ;
 004E 15C0              xjmp L1
 0050           L8:
 0050           ;     
 0050           ;     if((recbuf[1]&MSK_OCR_33)!=MSK_OCR_33)
 0050 8981              ldd R24,y+1
 0052 807C              andi R24,192
 0054 803C              cpi R24,192
 0056 11F0              breq L10
 0058           ;       return SD_ERR_VOL_NOTSUSP ;/* 不支持3.3V,返回错误码  */
 0058 04E0              ldi R16,4
 005A 0FC0              xjmp L1
 005C           L10:
 005C           ;   
 005C           ;     SPI_Clk_MAX();           /* 8. 设置SPI时钟到最大值 */
 005C 8DB1              in R24,0xd
 005E 8C7F              andi R24,252
 0060 8DB9              out 0xd,R24
 0062 709A              sbi 0xe,0
 0064           ;     
 0064           ;     #if SD_CRC_EN  
 0064           ;         ret=SD_EnableCRC(1); /* 使能CRC校验 enable CRC check */
 0064           ;         if(ret!=SD_NO_ERR)
 0064           ;             return ret ;
 0064           ;     #endif 
 0064           ;     
 0064           ;     ret=SD_SetBlockLen(SD_BLOCKSIZE);/* 9. 设置块的长度: 512Bytes  */
 0064 00E0              ldi R16,0
 0066 12E0              ldi R17,2
 0068 20E0              ldi R18,0
 006A 30E0              ldi R19,0
 006C 0E940000          xcall _SD_SetBlockLen
 0070 A02E              mov R10,R16
 0072           ;     if(ret!=SD_NO_ERR)
 0072 0023              tst R16
 0074 09F0              breq L13
 0076           ;         return ret ;
 0076 01C0              xjmp L1
 0078           L13:
 0078           ;     
 0078           ;     return(SD_GetCardInfo());        /* 10. 读CSD寄存器,获取SD卡信息  */
 0078 90D1              xcall _SD_GetCardInfo
 007A           L1:
 007A 2496              adiw R28,4
 007C 0E940000          xcall pop_gset3
 0080                   .dbline 0 ; func end
 0080 0895              ret
 0082           ;            ret -> R10
 0082           ;         recbuf -> y+12
 0082           ;      blockaddr -> y+8
                        .even
 0082           _SD_ReadBlock::
 0082 0E940000          xcall push_arg4
 0086 0E940000          xcall push_gset3
 008A 2297              sbiw R28,2
 008C           ; }
 008C           ; 
 008C           ; /*******************************************************************************
 008C           ; ** 函数名称: INT8U SD_ReadBlock()                                     
 008C           ; ** 功能描述: 从SD卡中读一个块                                         
 008C           ; ** 输   入: INT32U blockaddr: 块地址                         
 008C           ;            INT8U *recbuf   : 接收缓冲区,长度512Bytes          
 008C           ; ** 输   出: 0:   正确    >0:   错误码                                
 008C           ; *******************************************************************************/
 008C           ; INT8U SD_ReadBlock(INT32U blockaddr,INT8U *recbuf)
 008C           ; {
 008C           ;     INT8U ret ;
 008C           ;     
 008C           ;     if(blockaddr>sds.block_num)
 008C 40900200          lds R4,_sds+2
 0090 50900300          lds R5,_sds+2+1
 0094 20900000          lds R2,_sds
 0098 30900100          lds R3,_sds+1
 009C FE01              movw R30,R28
 009E 6084              ldd R6,z+8
 00A0 7184              ldd R7,z+9
 00A2 8284              ldd R8,z+10
 00A4 9384              ldd R9,z+11
 00A6 2614              cp R2,R6
 00A8 3704              cpc R3,R7
 00AA 4804              cpc R4,R8
 00AC 5904              cpc R5,R9
 00AE 10F4              brsh L16
 00B0           ;         return SD_ERR_OVER_CARDRANGE ;
 00B0 05E0              ldi R16,5
 00B2 15C0              xjmp L15
 00B4           L16:
 00B4           ;     /* 操作超出卡容量范围 operate over the card range */
 00B4           ;     
 00B4           ;     ret=SD_ReadSingleBlock(blockaddr);
 00B4 FE01              movw R30,R28
 00B6 0085              ldd R16,z+8
 00B8 1185              ldd R17,z+9
 00BA 2285              ldd R18,z+10
 00BC 3385              ldd R19,z+11
 00BE 0E940000          xcall _SD_ReadSingleBlock
 00C2 A02E              mov R10,R16
 00C4           ;     /* 读单块命令 read single blocks command */
 00C4           ;     if(ret!=SD_NO_ERR)
 00C4 0023              tst R16
 00C6 09F0              breq L18
 00C8           ;         return ret ;
 00C8 0AC0              xjmp L15
 00CA           L18:
 00CA           ;     
 00CA           ;     return(SD_ReadBlockData(SD_BLOCKSIZE,recbuf));
 00CA 0C84              ldd R0,y+12
 00CC 1D84              ldd R1,y+13
 00CE 1982              std y+1,R1
 00D0 0882              std y+0,R0
 00D2 00E0              ldi R16,0
 00D4 12E0              ldi R17,2
 00D6 20E0              ldi R18,0
 00D8 30E0              ldi R19,0
 00DA 0E940000          xcall _SD_ReadBlockData
 00DE           L15:
 00DE 2296              adiw R28,2
 00E0 0E940000          xcall pop_gset3
 00E4 2496              adiw R28,4
 00E6                   .dbline 0 ; func end
 00E6 0895              ret
 00E8           ;            tmp -> y+4
 00E8           ;            ret -> R10
 00E8           ;        sendbuf -> y+16
 00E8           ;      blockaddr -> y+12
                        .even
 00E8           _SD_WriteBlock::
 00E8 0E940000          xcall push_arg4
 00EC 0E940000          xcall push_gset3
 00F0 2697              sbiw R28,6
 00F2           ;     /* 读出数据 read data from sd card */
 00F2           ; }
 00F2           ; 
 00F2           ; 
 00F2           ; /*******************************************************************************
 00F2           ; ** 函数名称: SD_Read_word             
 00F2           ; ** 功能描述: 块偏移为offset 的长整形数据                                              
 00F2           ; ** 输   入: INT32U blockaddr: 块地址                         
 00F2           ;            INT16U offset   : 块内偏移                          
 00F2           ; ** 输   出: INT32U     
 00F2           ;              0xFFFF:   错误码                         
 00F2           ; *******************************************************************************/
 00F2           ; #if SD_Read_Word_EN 
 00F2           ; INT16U SD_Read_Word(INT32U blockaddr,INT16U offset)
 00F2           ; {
 00F2           ;     INT8U  *buff;
 00F2           ;     INT16U resp;
 00F2           ;     
 00F2           ;     buff=Data_Buf;
 00F2           ;     
 00F2           ;     if( SD_ReadBlock(blockaddr,buff)==0 )
 00F2           ;     {
 00F2           ;         resp=buff[offset+1];
 00F2           ;       resp=(resp<<8)+buff[offset];
 00F2           ;         return resp;
 00F2           ;     }
 00F2           ;     return 0xFFFF;
 00F2           ; }
 00F2           ; #endif
 00F2           ; 
 00F2           ; /*******************************************************************************
 00F2           ; ** 函数名称: SD_Read_Dword            
 00F2           ; ** 功能描述: 块偏移为offset 的长整形数据                                              
 00F2           ; ** 输   入: INT32U blockaddr: 块地址                         
 00F2           ;            INT16U offset   : 块内偏移                          
 00F2           ; ** 输   出: INT32U     
 00F2           ;              0xFFFFFFFF:   错误码                             

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?