sd_drive.s

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

S
1,636
字号
	.module SD_Drive.c
	.area lit(rom, con, rel)
_time_unit::
	.word 51712,15258
	.word 57600,1525
	.word 38528,152
	.word 16960,15
	.word 34464,1
	.word 10000,0
	.word 1000,0
	.word 100,0
_time_value::
	.byte 0,10
	.byte 12,13
	.byte 15,20
	.byte 25,30
	.byte 35,40
	.byte 45,50
	.byte 55,60
	.byte 'F,'P
_r2w_fator::
	.byte 1,2
	.byte 4,8
	.byte 16,32
	.area text(rom, con, rel)
;         recbuf -> y+0
;            ret -> R10
	.even
_SD_Initialize::
	xcall push_gset3
	sbiw R28,4
; /*--------------File Info-------------------------------------------------------
; ** 文   件   名:    SD_Driver.c
; ** 最后修改日期:    2008.3.28
; ** 版        本:    V1.0
; ** 描        述:    sd 卡驱动软件包: 用户API函数			
; **------------------------------------------------------------------------------
; ** Created   by:    		
; ** Created date:			
; *******************************************************************************/
; 
; #include "SYS_Config.h" 
; #include "SD_Config.h" 
; #include "SD_Hal.h" 
; #include "SD_Cmd.h" 
; #include "SD_Drive.h" 
; 
; 
; extern INT8U Data_Buf[SD_BLOCKSIZE];//在main函数中定义
; 
; 
; sd_struct sds ;/* SD卡信息结构体变量  */
; 
; /* 超时时间单位表(单位:0.000000001ns) timeout unit table */
; const INT32U time_unit[8]=
; {
;     1000000000,100000000,10000000,
;     1000000,100000,10000,1000,100 
; };
; 
; /* 超时时间表 timeout value table */
; const INT8U time_value[16]=
; {
;     0,10,12,13,15,20,25,30,35,40,45,50,55,60,70,80 
; };
; 
; /* 超时时间因数表 timeout factor table */
; const INT8U r2w_fator[6]=
; {
;     1,2,4,8,16,32 
; };
; 
; 
; /*       
; ********************************************************************************
; 用户API函数:  初始化,读,写,擦 SD卡 
; 				
; /******************************************************************************
; ** 函数名称: INT8U SD_Initialize()				
; ** 功能描述: 初始化SD卡							
; ** 输   入: 无									
; ** 输   出: 0:   正确    >0:   错误码		  	
; *******************************************************************************/
; INT8U SD_Initialize(void)
; {
;     INT8U recbuf[4],ret ;
;     
;     SD_HardWareInit();  //初始化读写SD卡的硬件条件 
	xcall _SD_HardWareInit
;        
;     if(!SD_ChkCard())   // 检查卡是否插入
	xcall _SD_ChkCard
	tst R16
	brne L2
;         return SD_ERR_NO_CARD ;
	ldi R16,1
	xjmp L1
L2:
;     
;     SPI_CS_Assert();         /* 1. 置CS为低 assert CS */
	xcall _SPI_CS_Assert
;     
;     SD_SPIDelay(100);        /* 2. 至少延时 74  */
	ldi R16,100
	xcall _SD_SPIDelay
;    
;     SPI_CS_Deassert();       /* 3. 置CS为高 dessert CS */
	xcall _SPI_CS_Deassert
;     
;     SD_SPIDelay(20);         /* 4. 延时2(8 clock)  */
	ldi R16,20
	xcall _SD_SPIDelay
;     
;     ret=SD_ResetSD();        /* 5. 发出CMDO命令复位SD卡  */
	xcall _SD_ResetSD
	mov R10,R16
;     if(ret!=SD_NO_ERR)
	tst R16
	breq L4
;         return ret ;
	xjmp L1
L4:
;     
;     ret=SD_ActiveInit();     /* 6. 激活卡进入初始化过程.  */
	xcall _SD_ActiveInit
	mov R10,R16
;     if(ret!=SD_NO_ERR)
	tst R16
	breq L6
;         return ret ;
	xjmp L1
L6:
;     
;     ret=SD_ReadOCR(4,recbuf);/* 7. 读OCR寄存器,查询卡支持的电压值 */
	movw R18,R28
	ldi R16,4
	xcall _SD_ReadOCR
	mov R10,R16
;     if(ret!=SD_NO_ERR)
	tst R16
	breq L8
;         return ret ;
	xjmp L1
L8:
;     
;     if((recbuf[1]&MSK_OCR_33)!=MSK_OCR_33)
	ldd R24,y+1
	andi R24,192
	cpi R24,192
	breq L10
; 	return SD_ERR_VOL_NOTSUSP ;/* 不支持3.3V,返回错误码  */
	ldi R16,4
	xjmp L1
L10:
;   
;     SPI_Clk_MAX();           /* 8. 设置SPI时钟到最大值 */
	in R24,0xd
	andi R24,252
	out 0xd,R24
	sbi 0xe,0
;     
;     #if SD_CRC_EN  
;         ret=SD_EnableCRC(1); /* 使能CRC校验 enable CRC check */
;         if(ret!=SD_NO_ERR)
;             return ret ;
;     #endif 
;     
;     ret=SD_SetBlockLen(SD_BLOCKSIZE);/* 9. 设置块的长度: 512Bytes  */
	ldi R16,0
	ldi R17,2
	ldi R18,0
	ldi R19,0
	xcall _SD_SetBlockLen
	mov R10,R16
;     if(ret!=SD_NO_ERR)
	tst R16
	breq L13
;         return ret ;
	xjmp L1
L13:
;     
;     return(SD_GetCardInfo());        /* 10. 读CSD寄存器,获取SD卡信息  */
	xcall _SD_GetCardInfo
L1:
	adiw R28,4
	xcall pop_gset3
	.dbline 0 ; func end
	ret
;            ret -> R10
;         recbuf -> y+12
;      blockaddr -> y+8
	.even
_SD_ReadBlock::
	xcall push_arg4
	xcall push_gset3
	sbiw R28,2
; }
; 
; /*******************************************************************************
; ** 函数名称: INT8U SD_ReadBlock()					
; ** 功能描述: 从SD卡中读一个块						
; ** 输   入: INT32U blockaddr: 块地址				
; 	     INT8U *recbuf   : 接收缓冲区,长度512Bytes	 	
; ** 输   出: 0:   正确    >0:   错误码		  		
; *******************************************************************************/
; INT8U SD_ReadBlock(INT32U blockaddr,INT8U *recbuf)
; {
;     INT8U ret ;
;     
;     if(blockaddr>sds.block_num)
	lds R4,_sds+2
	lds R5,_sds+2+1
	lds R2,_sds
	lds R3,_sds+1
	movw R30,R28
	ldd R6,z+8
	ldd R7,z+9
	ldd R8,z+10
	ldd R9,z+11
	cp R2,R6
	cpc R3,R7
	cpc R4,R8
	cpc R5,R9
	brsh L16
;         return SD_ERR_OVER_CARDRANGE ;
	ldi R16,5
	xjmp L15
L16:
;     /* 操作超出卡容量范围 operate over the card range */
;     
;     ret=SD_ReadSingleBlock(blockaddr);
	movw R30,R28
	ldd R16,z+8
	ldd R17,z+9
	ldd R18,z+10
	ldd R19,z+11
	xcall _SD_ReadSingleBlock
	mov R10,R16
;     /* 读单块命令 read single blocks command */
;     if(ret!=SD_NO_ERR)
	tst R16
	breq L18
;         return ret ;
	xjmp L15
L18:
;     
;     return(SD_ReadBlockData(SD_BLOCKSIZE,recbuf));
	ldd R0,y+12
	ldd R1,y+13
	std y+1,R1
	std y+0,R0
	ldi R16,0
	ldi R17,2
	ldi R18,0
	ldi R19,0
	xcall _SD_ReadBlockData
L15:
	adiw R28,2
	xcall pop_gset3
	adiw R28,4
	.dbline 0 ; func end
	ret
;            tmp -> y+4
;            ret -> R10
;        sendbuf -> y+16
;      blockaddr -> y+12
	.even
_SD_WriteBlock::
	xcall push_arg4
	xcall push_gset3
	sbiw R28,6
;     /* 读出数据 read data from sd card */
; }
; 
; 
; /*******************************************************************************
; ** 函数名称: SD_Read_word		
; ** 功能描述: 块偏移为offset 的长整形数据 						
; ** 输   入: INT32U blockaddr: 块地址				
; 	     INT16U offset   : 块内偏移				 
; ** 输   出: INT32U     
;              0xFFFF:   错误码		  		
; *******************************************************************************/
; #if SD_Read_Word_EN 
; INT16U SD_Read_Word(INT32U blockaddr,INT16U offset)
; {
;     INT8U  *buff;
;     INT16U resp;
;     
;     buff=Data_Buf;
;     
;     if( SD_ReadBlock(blockaddr,buff)==0 )
;     {
;         resp=buff[offset+1];
; 	resp=(resp<<8)+buff[offset];
;         return resp;
;     }
;     return 0xFFFF;
; }
; #endif
; 
; /*******************************************************************************
; ** 函数名称: SD_Read_Dword		
; ** 功能描述: 块偏移为offset 的长整形数据 						
; ** 输   入: INT32U blockaddr: 块地址				
; 	     INT16U offset   : 块内偏移				 
; ** 输   出: INT32U     
;              0xFFFFFFFF:   错误码		  		
; *******************************************************************************/
; #if SD_Read_Dword_EN 
; INT32U SD_Read_Dword(INT32U blockaddr,INT16U offset)
; {
;     INT8U  *buff;
;     INT32U resp;
;     
;     buff=Data_Buf;
;     
;     if( SD_ReadBlock(blockaddr,buff)==0 )
;     {
;         resp=buff[offset+3];
; 	resp=(resp<<8)+buff[offset+2];
; 	resp=(resp<<8)+buff[offset+1];
; 	resp=(resp<<8)+buff[offset];
; 	return resp;
;     }
;     return 0xFFFFFFFF;
; }
; #endif
; 
; 
; /*******************************************************************************
; ** 函数名称: INT8U SD_ReadMultiBlock()				
; ** 功能描述: 从SD卡中读多个块						
; ** 输   入: INT32U blockaddr: 块地址				
; 	     INT32U blocknum : 块数量					
; 	     INT8U *recbuf   : 接收缓冲区,每块512字节		 
; ** 输   出: 0:   正确    >0:   错误码		  		
; *******************************************************************************/
; #if SD_ReadMultiBlock_EN 
; INT8U SD_ReadMultiBlock(INT32U blockaddr,INT32U blocknum,INT8U*recbuf)
; {
;     INT32U i ;
;     INT8U ret ;
;     
;     if((blockaddr+blocknum)>sds.block_num)
;         return SD_ERR_OVER_CARDRANGE ;
;     /* 操作超出卡容量范围 operate over the card range */
;     
;     ret=SD_ReadMultipleBlock(blockaddr);
;     /* 读多块命令 read multiple blocks command */
;     if(ret!=SD_NO_ERR)
;         return ret ;
;     
;     for(i=0;i<blocknum;i++)
;     {
;         /* 读出数据 read data from sd card */
;         ret=SD_ReadBlockData(SD_BLOCKSIZE,recbuf);
;         if(ret==SD_NO_ERR)
;             recbuf=recbuf+SD_BLOCKSIZE ;
;         else 
;             return ret ;
;     }
;     return(SD_StopTransmission());
;     /* 结束数据传输 stop transmission operation */
; }
; #endif 
; 
; /*******************************************************************************
; ** 函数名称: INT8U SD_WriteBlock()					
; ** 功能描述: 向SD卡中写入一个块						
; ** 输   入: INT32U blockaddr: 块地址				
; 	     INT8U *sendbuf  : 发送缓冲区,长度512Bytes	  	
; ** 输   出: 0:   正确    >0:   错误码		  		
; *******************************************************************************/
; INT8U SD_WriteBlock(INT32U blockaddr,INT8U *sendbuf)
; {
;     INT8U ret,tmp[2];
;     
;     if(blockaddr>sds.block_num)
	lds R4,_sds+2
	lds R5,_sds+2+1
	lds R2,_sds
	lds R3,_sds+1
	movw R30,R28
	ldd R6,z+12
	ldd R7,z+13
	ldd R8,z+14
	ldd R9,z+15
	cp R2,R6
	cpc R3,R7
	cpc R4,R8
	cpc R5,R9
	brsh L21
;         return SD_ERR_OVER_CARDRANGE ;
	ldi R16,5
	xjmp L20
L21:
;     /* 操作超出卡容量范围 operate over the card range */
;     
;     if(SD_ChkCardWP()==1)
	xcall _SD_ChkCardWP
	cpi R16,1
	brne L23
;         return SD_ERR_WRITE_PROTECT ;
	ldi R16,66
	xjmp L20
L23:
;     /* 卡有写保护 */
;     
;     ret=SD_WriteSingleBlock(blockaddr);
	movw R30,R28
	ldd R16,z+12
	ldd R17,z+13
	ldd R18,z+14
	ldd R19,z+15
	xcall _SD_WriteSingleBlock
	mov R10,R16
;     /* 写单块命令 write single block */
;     if(ret!=SD_NO_ERR)
	tst R16
	breq L25
;         return ret ;
	xjmp L20
L25:
;     
;     ret=SD_WriteBlockData(0,SD_BLOCKSIZE,sendbuf);
	ldd R0,y+16
	ldd R1,y+17
	std y+3,R1
	std y+2,R0
	ldi R20,0
	ldi R21,2
	ldi R22,0
	ldi R23,0
	std y+0,R22
	std y+1,R23
	movw R18,R20
	clr R16
	xcall _SD_WriteBlockData
	mov R10,R16
;     /* 写入数据 write data */
;     /* 读Card Status寄存器, 检查写入是否成功 */
;     if(ret==SD_NO_ERR)
	tst R16
	brne L27
;     {
;         /* read Card Status register to check write wheather sucessfully */
;         ret=SD_ReadCard_Status(2,tmp);
	movw R18,R28
	subi R18,252  ; offset = 4
	sbci R19,255
	ldi R16,2
	xcall _SD_ReadCard_Status
	mov R10,R16
;         if(ret!=SD_NO_ERR)
	tst R16
	breq L29
;             return ret ;
	xjmp L20
L29:
;         /* 读寄存器失败 read register fail */
;         
;         if((tmp[0]!=0)||(tmp[1]!=0))
	ldd R2,y+4
	tst R2
	brne L34
	ldd R2,y+5
	tst R2
	breq L31
L34:
;         ret=SD_ERR_WRITE_BLK ;
	ldi R24,64
	mov R10,R24
L31:
;         /* 响应指示写失败 response indicate write fail */
;     }
L27:
;     return ret ;/* 返回写入结果 return the result of writing */
	mov R16,R10
L20:
	adiw R28,6
	xcall pop_gset3
	adiw R28,4
	.dbline 0 ; func end
	ret
;            tmp -> y+0
;            ret -> R10
;       blocknum -> y+14
;      startaddr -> y+10
	.even
_SD_EraseBlock::
	xcall push_arg4
	xcall push_gset3
	sbiw R28,4
; }
; 
; /*******************************************************************************
; ** 函数名称: INT8U SD_WriteMultiBlock()				
; ** 功能描述: 向SD卡中写入多个块						
; ** 输   入: INT32U blockaddr: 块地址				
; 	     INT32U blocknum : 块数量					
; 	     INT8U *sendbuf  : 发送缓冲区每块512字节    	
; ** 输   出: 0:   正确    >0:   错误码		  		
; *******************************************************************************/
; #if SD_WriteMultiBlock_EN 
; INT8U SD_WriteMultiBlock(INT32U blockaddr,INT32U blocknum,INT8U *sendbuf)
; {
;     INT32U i ;
;     INT8U ret ;
;     
;     if((blockaddr+blocknum)>sds.block_num)
;         return SD_ERR_OVER_CARDRANGE ;
;     /* 操作超出卡容量范围 operate over the card range */
;     
;     if(SD_ChkCardWP()==1)
;         return SD_ERR_WRITE_PROTECT ;
;     /* 卡有写保护 */
;     
;     ret=SD_WriteMultipleBlock(blockaddr);
;     /* 写多块命令 write multiple blocks command */
;     if(ret!=SD_NO_ERR)
;         return ret ;
;     
;     for(i=0;i<blocknum;i++)
;     {
;         ret=SD_WriteBlockData(1,SD_BLOCKSIZE,sendbuf);
;         /* 写入数据 write data */
;         if(ret==SD_NO_ERR)
;             sendbuf=sendbuf+SD_BLOCKSIZE ;
;         else 
;         {
;             /* 写失败 write fail */
;             SD_StopTransmission();
;             /* 停止数据传输 stop data transmission */
;             SD_WaitBusy(SD_WAIT_WRITE);
;             /* 等待 waiting */
;             return ret ;
;         }
;     }
;     
;     SD_StopMultiToken();
;     /* 发送数据停止令牌 send data stop token */
;     
;     ret=SD_WaitBusy(SD_WAIT_WRITE);
;     /* 等待写入的完成 wait for finishing writing */
;     if(ret!=SD_NO_ERR)

⌨️ 快捷键说明

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