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 + -
显示快捷键?