sd_drive.s
来自「Atmega64单片机程序(完整工程)」· S 代码 · 共 1,636 行 · 第 1/3 页
S
1,636 行
; return SD_ERR_TIMEOUT_WRITE ;
;
; ret=SD_GetNumWRBlcoks(&i);
; /* 读正确写入的块数 read the blocks that be written correctly */
; if(ret!=SD_NO_ERR)
; return ret ;
;
; if(i!=blocknum)
; return SD_ERR_WRITE_BLKNUMS ;
; /* 正确写入块数错误 the blocks that be written correctly is error */
;
; return SD_NO_ERR ;
; /* 返回写入成功 return write sucessfully */
; }
; #endif
;
; /*******************************************************************************
; ** 函数名称: INT8U SD_EraseBlock()
; ** 功能描述: 擦除SD卡中的块
; ** 输 入: INT32U startaddr: 起始地址
; INT32U endaddr : 终止地址
; ** 输 出: 0: 正确 >0: 错误码
; ** 注 意: startaddr 和 blocknum 建议为sds.erase_uint的整数倍,
; 因为有的卡只能以sds.erase_uint为单位进行擦除
; *******************************************************************************/
; #if SD_EraseBlock_EN
; INT8U SD_EraseBlock(INT32U startaddr,INT32U blocknum)
; {
; INT32S tmp ;
; INT8U ret ;
;
; if((startaddr+blocknum)>sds.block_num)
movw R30,R28
ldd R2,z+14
ldd R3,z+15
ldd R4,z+16
ldd R5,z+17
movw R30,R28
ldd R6,z+10
ldd R7,z+11
ldd R8,z+12
ldd R9,z+13
add R6,R2
adc R7,R3
adc R8,R4
adc R9,R5
lds R4,_sds+2
lds R5,_sds+2+1
lds R2,_sds
lds R3,_sds+1
cp R2,R6
cpc R3,R7
cpc R4,R8
cpc R5,R9
brsh L36
; return SD_ERR_OVER_CARDRANGE ;
ldi R16,5
xjmp L35
L36:
; /* 操作超出卡容量范围 operate over the card range */
;
; if(SD_ChkCardWP()==1)
xcall _SD_ChkCardWP
cpi R16,1
brne L38
; return SD_ERR_WRITE_PROTECT ;
ldi R16,66
xjmp L35
L38:
; /* 卡有写保护 */
;
; tmp=blocknum-sds.erase_unit ;
lds R4,_sds+8+2
lds R5,_sds+8+2+1
lds R2,_sds+8
lds R3,_sds+8+1
movw R30,R28
ldd R6,z+14
ldd R7,z+15
ldd R8,z+16
ldd R9,z+17
sub R6,R2
sbc R7,R3
sbc R8,R4
sbc R9,R5
movw R30,R28
std z+0,R6
std z+1,R7
std z+2,R8
std z+3,R9
xjmp L42
L41:
; /* 每次擦除扇区大小 once erase is sector size */
; while(tmp>=0)
; {
; ret=SD_EraseStartBlock(startaddr);
movw R30,R28
ldd R16,z+10
ldd R17,z+11
ldd R18,z+12
ldd R19,z+13
xcall _SD_EraseStartBlock
mov R10,R16
; /* 选择起始块地址 select start address */
; if(ret!=SD_NO_ERR)
tst R16
breq L44
; return ret ;
xjmp L35
L44:
;
; ret=SD_EraseEndBlock(startaddr+sds.erase_unit-1);
lds R4,_sds+8+2
lds R5,_sds+8+2+1
lds R2,_sds+8
lds R3,_sds+8+1
movw R30,R28
ldd R6,z+10
ldd R7,z+11
ldd R8,z+12
ldd R9,z+13
add R6,R2
adc R7,R3
adc R8,R4
adc R9,R5
ldi R20,1
ldi R21,0
ldi R22,0
ldi R23,0
sub R6,R20
sbc R7,R21
sbc R8,R22
sbc R9,R23
movw R16,R6
movw R18,R8
xcall _SD_EraseEndBlock
mov R10,R16
; /* 选择终止块地址 select end address */
; if(ret!=SD_NO_ERR)
tst R16
breq L47
; return ret ;
xjmp L35
L47:
;
; ret=SD_EraseSelectedBlock();
xcall _SD_EraseSelectedBlock
mov R10,R16
; /* 擦除所选的块 erase blocks selected */
; if(ret!=SD_NO_ERR)
tst R16
breq L49
; return ret ;
xjmp L35
L49:
lds R4,_sds+8+2
lds R5,_sds+8+2+1
lds R2,_sds+8
lds R3,_sds+8+1
movw R30,R28
ldd R6,z+10
ldd R7,z+11
ldd R8,z+12
ldd R9,z+13
add R6,R2
adc R7,R3
adc R8,R4
adc R9,R5
movw R30,R28
std z+10,R6
std z+11,R7
std z+12,R8
std z+13,R9
lds R4,_sds+8+2
lds R5,_sds+8+2+1
lds R2,_sds+8
lds R3,_sds+8+1
movw R30,R28
ldd R6,z+14
ldd R7,z+15
ldd R8,z+16
ldd R9,z+17
sub R6,R2
sbc R7,R3
sbc R8,R4
sbc R9,R5
movw R30,R28
std z+14,R6
std z+15,R7
std z+16,R8
std z+17,R9
lds R4,_sds+8+2
lds R5,_sds+8+2+1
lds R2,_sds+8
lds R3,_sds+8+1
movw R30,R28
ldd R6,z+14
ldd R7,z+15
ldd R8,z+16
ldd R9,z+17
sub R6,R2
sbc R7,R3
sbc R8,R4
sbc R9,R5
movw R30,R28
std z+0,R6
std z+1,R7
std z+2,R8
std z+3,R9
L42:
ldi R20,0
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+0
ldd R3,z+1
ldd R4,z+2
ldd R5,z+3
cp R2,R20
cpc R3,R21
cpc R4,R22
cpc R5,R23
brlt X0
xjmp L41
X0:
;
; startaddr+=sds.erase_unit ;
; /* 起始地址递增 */
; blocknum-=sds.erase_unit ;
; tmp=blocknum-sds.erase_unit ;
; };
;
; /* 擦除不够擦除扇区大小的块 */
; if(blocknum>0)
ldi R20,0
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+14
ldd R3,z+15
ldd R4,z+16
ldd R5,z+17
cp R2,R20
cpc R3,R21
cpc R4,R22
cpc R5,R23
brne X1
xjmp L54
X1:
; {
; /* erase blocks that numbers is not enough a sector */
; ret=SD_EraseStartBlock(startaddr);
movw R30,R28
ldd R16,z+10
ldd R17,z+11
ldd R18,z+12
ldd R19,z+13
xcall _SD_EraseStartBlock
mov R10,R16
; if(ret!=SD_NO_ERR)
tst R16
breq L56
; return ret ;
xjmp L35
L56:
;
; ret=SD_EraseEndBlock(startaddr+blocknum-1);
movw R30,R28
ldd R2,z+14
ldd R3,z+15
ldd R4,z+16
ldd R5,z+17
movw R30,R28
ldd R6,z+10
ldd R7,z+11
ldd R8,z+12
ldd R9,z+13
add R6,R2
adc R7,R3
adc R8,R4
adc R9,R5
ldi R20,1
ldi R21,0
ldi R22,0
ldi R23,0
sub R6,R20
sbc R7,R21
sbc R8,R22
sbc R9,R23
movw R16,R6
movw R18,R8
xcall _SD_EraseEndBlock
mov R10,R16
; if(ret!=SD_NO_ERR)
tst R16
breq L58
; return ret ;
xjmp L35
L58:
;
; ret=SD_EraseSelectedBlock();
xcall _SD_EraseSelectedBlock
mov R10,R16
; if(ret!=SD_NO_ERR)
tst R16
breq L60
; return ret ;
xjmp L35
L60:
; }
L54:
; return SD_NO_ERR ;/* 返回擦除成功 return erase sucessfully */
clr R16
L35:
adiw R28,4
xcall pop_gset3
adiw R28,4
.dbline 0 ; func end
ret
; tmp -> y+16
; ret -> R10
; csdbuf -> y+0
.even
_SD_GetCardInfo::
xcall push_gset3
sbiw R28,20
; }
; #endif
;
;
; /*******************************************************************************
; ** 函数名称: INT8U SD_GetCardInfo()
; ** 功能描述: 获得SD卡的信息
; ** 输 入: INT8U cardtype: 卡类型
; ** 输 出: 0: 正确 >0: 错误码 O
; *******************************************************************************/
; INT8U SD_GetCardInfo(void)
; {
; INT32U tmp ;
; INT8U csdbuf[16],ret ;
;
; ret=SD_ReadCSD(16,csdbuf);/* 读CSD寄存器 */
movw R18,R28
ldi R16,16
xcall _SD_ReadCSD
mov R10,R16
; if(ret!=SD_NO_ERR)
tst R16
breq L63
; return ret ;
xjmp L62
L63:
;
; SD_CalTimeout(csdbuf);/* 计算超时时间值 */
movw R16,R28
xcall _SD_CalTimeout
;
; /* 计算块的最大长度 */
; /* calculate the size of a sector */
; sds.block_len=1<<(csdbuf[READ_BL_LEN_POS]&READ_BL_LEN_MSK);
ldd R18,y+5
clr R19
andi R18,15
andi R19,0
ldi R16,1
ldi R17,0
xcall lsl16
movw R2,R16
clr R4
sbrc R3,7
com R4
clr R5
sbrc R4,7
com R5
sts _sds+4+1,R3
sts _sds+4,R2
sts _sds+4+2+1,R5
sts _sds+4+2,R4
; /* (2 ^ READ_BL_LEN) */
;
; /* 计算卡中块的个数 */
; /* calculate the sector numbers of the SD Card */
; sds.block_num=((INT32U)(csdbuf[C_SIZE_POS1]&C_SIZE_MSK1)<<10)+((INT32U)csdbuf[C_SIZE_POS2]<<2)+((csdbuf[C_SIZE_POS3]&C_SIZE_MSK3)>>6)+1 ;
ldi R24,2
ldi R25,0
ldd R2,y+7
clr R3
clr R4
clr R5
st -y,R24
movw R16,R2
movw R18,R4
xcall lsl32
movw R2,R16
movw R4,R18
ldi R24,10
ldi R25,0
ldd R30,y+6
clr R31
andi R30,3
andi R31,0
movw R6,R30
clr R8
sbrc R7,7
com R8
clr R9
sbrc R8,7
com R9
st -y,R24
movw R16,R6
movw R18,R8
xcall lsl32
movw R6,R16
movw R8,R18
add R6,R2
adc R7,R3
adc R8,R4
adc R9,R5
ldi R18,6
ldi R19,0
ldd R16,y+8
clr R17
andi R16,192
andi R17,0
xcall asr16
movw R2,R16
clr R4
sbrc R3,7
com R4
clr R5
sbrc R4,7
com R5
add R6,R2
adc R7,R3
adc R8,R4
adc R9,R5
ldi R20,1
ldi R21,0
ldi R22,0
ldi R23,0
add R6,R20
adc R7,R21
adc R8,R22
adc R9,R23
sts _sds+1,R7
sts _sds,R6
sts _sds+2+1,R9
sts _sds+2,R8
; /* (C_SIZE + 1)*/
;
; tmp=((INT32U)(csdbuf[C_SIZE_MULT_POS1]&C_SIZE_MULT_MSK1)<<1)+((csdbuf[C_SIZE_MULT_POS2]&C_SIZE_MULT_MSK2)>>7)+2 ;
ldi R18,7
ldi R19,0
ldd R16,y+10
clr R17
andi R16,128
andi R17,0
xcall asr16
movw R2,R16
clr R4
sbrc R3,7
com R4
clr R5
sbrc R4,7
com R5
ldd R24,y+9
clr R25
andi R24,3
andi R25,0
movw R6,R24
clr R8
sbrc R7,7
com R8
clr R9
sbrc R8,7
com R9
lsl R6
rol R7
rol R8
rol R9
add R6,R2
adc R7,R3
adc R8,R4
adc R9,R5
ldi R20,2
ldi R21,0
ldi R22,0
ldi R23,0
add R6,R20
adc R7,R21
adc R8,R22
adc R9,R23
movw R30,R28
std z+16,R6
std z+17,R7
std z+18,R8
std z+19,R9
; /* (C_SIZE_MULT + 2) */
;
; /* 获得卡中块的数量 */
; /* get the block numbers in card */
; sds.block_num=sds.block_num*(1<<tmp);
movw R30,R28
ldd R18,z+16
ldd R19,z+17
ldi R16,1
ldi R17,0
xcall lsl16
movw R2,R16
clr R4
sbrc R3,7
com R4
clr R5
sbrc R4,7
com R5
lds R8,_sds+2
lds R9,_sds+2+1
lds R6,_sds
lds R7,_sds+1
st -y,R5
st -y,R4
st -y,R3
st -y,R2
movw R16,R6
movw R18,R8
xcall empy32u
sts _sds+1,R17
sts _sds,R16
sts _sds+2+1,R19
sts _sds+2,R18
; /* (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */
;
; /* 计算扇区大小 */
; /*calculate the size of sector */
; sds.erase_unit=((INT32U)(csdbuf[SECTOR_SIZE_POS1]&SECTOR_SIZE_MSK1)<<1)+((csdbuf[SECTOR_SIZE_POS2]&SECTOR_SIZE_MSK2)>>7)+1 ;
ldi R18,7
ldi R19,0
ldd R16,y+11
clr R17
andi R16,128
andi R17,0
xcall asr16
movw R2,R16
clr R4
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?