📄 sd.lss
字号:
438: 0f b6 in r0, 0x3f ; 63
43a: f8 94 cli
43c: de bf out 0x3e, r29 ; 62
43e: 0f be out 0x3f, r0 ; 63
440: cd bf out 0x3d, r28 ; 61
442: cf 91 pop r28
444: df 91 pop r29
446: 1f 91 pop r17
448: 0f 91 pop r16
44a: ff 90 pop r15
44c: ef 90 pop r14
44e: 08 95 ret
00000450 <SD_Init>:
- 返回说明:调用成功,返回0x00,否则返回INIT_CMD1_ERROR (sd.h中有定义)
- 注:SD卡初始化成功后,读写扇区时,尽量将SPI速度提上来,提高效率
**********************************************************************************/
uint8_t SD_Init() //初始化,使用CMD1(1号命令)
{
450: ef 92 push r14
452: ff 92 push r15
454: 1f 93 push r17
456: df 93 push r29
458: cf 93 push r28
45a: 00 d0 rcall .+0 ; 0x45c <SD_Init+0xc>
45c: 00 d0 rcall .+0 ; 0x45e <SD_Init+0xe>
45e: 00 d0 rcall .+0 ; 0x460 <SD_Init+0x10>
460: cd b7 in r28, 0x3d ; 61
462: de b7 in r29, 0x3e ; 62
unsigned char retry,temp;
unsigned char pcmd[] = {0x41,0x00,0x00,0x00,0x00,0xff};
464: de 01 movw r26, r28
466: 11 96 adiw r26, 0x01 ; 1
468: ea ec ldi r30, 0xCA ; 202
46a: f0 e0 ldi r31, 0x00 ; 0
46c: 86 e0 ldi r24, 0x06 ; 6
46e: 01 90 ld r0, Z+
470: 0d 92 st X+, r0
472: 81 50 subi r24, 0x01 ; 1
474: e1 f7 brne .-8 ; 0x46e <SD_Init+0x1e>
476: 1f ef ldi r17, 0xFF ; 255
retry = 0;
do
{
temp = SD_Write_Cmd(pcmd);
478: 7e 01 movw r14, r28
47a: 08 94 sec
47c: e1 1c adc r14, r1
47e: f1 1c adc r15, r1
480: c7 01 movw r24, r14
482: 0e 94 bb 01 call 0x376 ; 0x376 <SD_Write_Cmd>
486: 11 50 subi r17, 0x01 ; 1
retry++;
if(retry > 254)
488: 19 f4 brne .+6 ; 0x490 <SD_Init+0x40>
{
SET_SD_CS; //关闭片选
48a: d8 9a sbi 0x1b, 0 ; 27
48c: 82 e0 ldi r24, 0x02 ; 2
48e: 0d c0 rjmp .+26 ; 0x4aa <SD_Init+0x5a>
return(INIT_CMD1_ERROR); //CMD1写入失败
}
}while(temp != 0);
490: 88 23 and r24, r24
492: b1 f7 brne .-20 ; 0x480 <SD_Init+0x30>
SET_SD_CS; //关闭SD卡的片选
494: d8 9a sbi 0x1b, 0 ; 27
//将SS SCK MOSI置为输出
}
uint8_t SPI_RW(uint8_t dat)
{//SPI读写1Byte(欲想读之必先与之)
SPDR = dat;
496: 8f ef ldi r24, 0xFF ; 255
498: 8f b9 out 0x0f, r24 ; 15
while(!(SPSR & (1 << SPIF)))
49a: 77 9b sbis 0x0e, 7 ; 14
49c: fe cf rjmp .-4 ; 0x49a <SD_Init+0x4a>
;
return (SPDR);
49e: 8f b1 in r24, 0x0f ; 15
//使能SPI,主机方式,MSB在前,模式0,128分频
}
void SPI_High(void)
{//SPI高速模式
SPCR = 0;
4a0: 1d b8 out 0x0d, r1 ; 13
SPCR = (1 << SPE) | (1 << MSTR);
4a2: 80 e5 ldi r24, 0x50 ; 80
4a4: 8d b9 out 0x0d, r24 ; 13
SPSR |= (1 << SPI2X);
4a6: 70 9a sbi 0x0e, 0 ; 14
4a8: 80 e0 ldi r24, 0x00 ; 0
SET_SD_CS; //关闭SD卡的片选
SPI_RW(0XFF); //按照SD卡的操作时序在这里补8个时钟
SPI_High(); //SPI高速模式
return(0); //返回0,说明初始化操作成功
}
4aa: 26 96 adiw r28, 0x06 ; 6
4ac: 0f b6 in r0, 0x3f ; 63
4ae: f8 94 cli
4b0: de bf out 0x3e, r29 ; 62
4b2: 0f be out 0x3f, r0 ; 63
4b4: cd bf out 0x3d, r28 ; 61
4b6: cf 91 pop r28
4b8: df 91 pop r29
4ba: 1f 91 pop r17
4bc: ff 90 pop r15
4be: ef 90 pop r14
4c0: 08 95 ret
000004c2 <SD_Write_Sector>:
buffer:指向数据缓冲区的指针
- 返回说明:调用成功,返回0x00,否则返回WRITE_BLOCK_ERROR (sd.h中有定义)
********************************************************************************************/
uint8_t SD_Write_Sector(uint32_t addr , const uint8_t *Buffer) //向SD卡中的指定地址的扇区写入512个字节,使用CMD24(24号命令)
{
4c2: cf 92 push r12
4c4: df 92 push r13
4c6: ef 92 push r14
4c8: ff 92 push r15
4ca: 1f 93 push r17
4cc: df 93 push r29
4ce: cf 93 push r28
4d0: 00 d0 rcall .+0 ; 0x4d2 <SD_Write_Sector+0x10>
4d2: 00 d0 rcall .+0 ; 0x4d4 <SD_Write_Sector+0x12>
4d4: 00 d0 rcall .+0 ; 0x4d6 <SD_Write_Sector+0x14>
4d6: cd b7 in r28, 0x3d ; 61
4d8: de b7 in r29, 0x3e ; 62
4da: 6a 01 movw r12, r20
uint8_t temp,retry;
uint16_t i;
uint8_t pcmd[] = {0x58,0x00,0x00,0x00,0x00,0xff}; //向SD卡中单个块(512字节,一个扇区)写入数据,用CMD24
4dc: de 01 movw r26, r28
4de: 11 96 adiw r26, 0x01 ; 1
4e0: e4 ec ldi r30, 0xC4 ; 196
4e2: f0 e0 ldi r31, 0x00 ; 0
4e4: 26 e0 ldi r18, 0x06 ; 6
4e6: 01 90 ld r0, Z+
4e8: 0d 92 st X+, r0
4ea: 21 50 subi r18, 0x01 ; 1
4ec: e1 f7 brne .-8 ; 0x4e6 <SD_Write_Sector+0x24>
addr <<= 9; //addr = addr * 512 将块地址(扇区地址)转为字节地址 [这里就限制了SD卡的最大容量为4G]
4ee: dc 01 movw r26, r24
4f0: cb 01 movw r24, r22
4f2: 49 e0 ldi r20, 0x09 ; 9
4f4: 88 0f add r24, r24
4f6: 99 1f adc r25, r25
4f8: aa 1f adc r26, r26
4fa: bb 1f adc r27, r27
4fc: 4a 95 dec r20
4fe: d1 f7 brne .-12 ; 0x4f4 <SD_Write_Sector+0x32>
pcmd[1]=((addr & 0xff000000) >> 24); //将字节地址写入到CMD24字节序列中
500: 2b 2f mov r18, r27
502: 33 27 eor r19, r19
504: 44 27 eor r20, r20
506: 55 27 eor r21, r21
508: 2a 83 std Y+2, r18 ; 0x02
pcmd[2]=((addr & 0x00ff0000) >> 16);
50a: ab 83 std Y+3, r26 ; 0x03
pcmd[3]=((addr & 0x0000ff00) >> 8);
50c: 80 70 andi r24, 0x00 ; 0
50e: a0 70 andi r26, 0x00 ; 0
510: b0 70 andi r27, 0x00 ; 0
512: 89 2f mov r24, r25
514: 9a 2f mov r25, r26
516: ab 2f mov r26, r27
518: bb 27 eor r27, r27
51a: 8c 83 std Y+4, r24 ; 0x04
51c: 1e ef ldi r17, 0xFE ; 254
retry = 0;
do
{
temp = SD_Write_Cmd(pcmd);
51e: 7e 01 movw r14, r28
520: 08 94 sec
522: e1 1c adc r14, r1
524: f1 1c adc r15, r1
526: c7 01 movw r24, r14
528: 0e 94 bb 01 call 0x376 ; 0x376 <SD_Write_Cmd>
52c: 48 2f mov r20, r24
retry++;
if(retry > 254)
52e: 11 23 and r17, r17
530: 11 f4 brne .+4 ; 0x536 <SD_Write_Sector+0x74>
{
SET_SD_CS; //关闭片选
532: d8 9a sbi 0x1b, 0 ; 27
534: 43 c0 rjmp .+134 ; 0x5bc <SD_Write_Sector+0xfa>
return(temp); //命令写入失败
536: 11 50 subi r17, 0x01 ; 1
}
}while(temp != 0);
538: 88 23 and r24, r24
53a: a9 f7 brne .-22 ; 0x526 <SD_Write_Sector+0x64>
53c: 80 e0 ldi r24, 0x00 ; 0
53e: 90 e0 ldi r25, 0x00 ; 0
//将SS SCK MOSI置为输出
}
uint8_t SPI_RW(uint8_t dat)
{//SPI读写1Byte(欲想读之必先与之)
SPDR = dat;
540: 2f ef ldi r18, 0xFF ; 255
542: 2f b9 out 0x0f, r18 ; 15
while(!(SPSR & (1 << SPIF)))
544: 77 9b sbis 0x0e, 7 ; 14
546: fe cf rjmp .-4 ; 0x544 <SD_Write_Sector+0x82>
;
return (SPDR);
548: 3f b1 in r19, 0x0f ; 15
SET_SD_CS; //关闭片选
return(temp); //命令写入失败
}
}while(temp != 0);
for(i=0;i<100;i++) //这里要插入若干时钟信号
54a: 01 96 adiw r24, 0x01 ; 1
54c: 84 36 cpi r24, 0x64 ; 100
54e: 91 05 cpc r25, r1
550: c1 f7 brne .-16 ; 0x542 <SD_Write_Sector+0x80>
//将SS SCK MOSI置为输出
}
uint8_t SPI_RW(uint8_t dat)
{//SPI读写1Byte(欲想读之必先与之)
SPDR = dat;
552: 8e ef ldi r24, 0xFE ; 254
554: 8f b9 out 0x0f, r24 ; 15
while(!(SPSR & (1 << SPIF)))
556: 77 9b sbis 0x0e, 7 ; 14
558: fe cf rjmp .-4 ; 0x556 <SD_Write_Sector+0x94>
;
return (SPDR);
55a: 8f b1 in r24, 0x0f ; 15
55c: 20 e0 ldi r18, 0x00 ; 0
55e: 30 e0 ldi r19, 0x00 ; 0
SPI_RW(0XFE); //写入开始字节 0xfe,后面就是要写入的512个字节的数据
for (i=0;i<512;i++) //将缓冲区中要写入的512个字节写入SD卡
{
SPI_RW(*Buffer++);
560: f6 01 movw r30, r12
562: 81 91 ld r24, Z+
564: 6f 01 movw r12, r30
//将SS SCK MOSI置为输出
}
uint8_t SPI_RW(uint8_t dat)
{//SPI读写1Byte(欲想读之必先与之)
SPDR = dat;
566: 8f b9 out 0x0f, r24 ; 15
while(!(SPSR & (1 << SPIF)))
568: 77 9b sbis 0x0e, 7 ; 14
56a: fe cf rjmp .-4 ; 0x568 <SD_Write_Sector+0xa6>
;
return (SPDR);
56c: 8f b1 in r24, 0x0f ; 15
SPI_RW(0XFF);
}
SPI_RW(0XFE); //写入开始字节 0xfe,后面就是要写入的512个字节的数据
for (i=0;i<512;i++) //将缓冲区中要写入的512个字节写入SD卡
56e: 2f 5f subi r18, 0xFF ; 255
570: 3f 4f sbci r19, 0xFF ; 255
572: f2 e0 ldi r31, 0x02 ; 2
574: 20 30 cpi r18, 0x00 ; 0
576: 3f 07 cpc r19, r31
578: 99 f7 brne .-26 ; 0x560 <SD_Write_Sector+0x9e>
//将SS SCK MOSI置为输出
}
uint8_t SPI_RW(uint8_t dat)
{//SPI读写1Byte(欲想读之必先与之)
SPDR = dat;
57a: 8f ef ldi r24, 0xFF ; 255
57c: 8f b9 out 0x0f, r24 ; 15
while(!(SPSR & (1 << SPIF)))
57e: 77 9b sbis 0x0e, 7 ; 14
580: fe cf rjmp .-4 ; 0x57e <SD_Write_Sector+0xbc>
;
return (SPDR);
582: 8f b1 in r24, 0x0f ; 15
//将SS SCK MOSI置为输出
}
uint8_t SPI_RW(uint8_t dat)
{//SPI读写1Byte(欲想读之必先与之)
SPDR = dat;
584: 8f ef ldi r24, 0xFF ; 255
586: 8f b9 out 0x0f, r24 ; 15
while(!(SPSR & (1 << SPIF)))
588: 77 9b sbis 0x0e, 7 ; 14
58a: fe cf rjmp .-4 ; 0x588 <SD_Write_Sector+0xc6>
;
return (SPDR);
58c: 8f b1 in r24, 0x0f ; 15
//将SS SCK MOSI置为输出
}
uint8_t SPI_RW(uint8_t dat)
{//SPI读写1Byte(欲想读之必先与之)
SPDR = dat;
58e: 8f ef ldi r24, 0xFF ; 255
590: 8f b9 out 0x0f, r24 ; 15
while(!(SPSR & (1 << SPIF)))
592: 77 9b sbis 0x0e, 7 ; 14
594: fe cf rjmp .-4 ; 0x592 <SD_Write_Sector+0xd0>
;
return (SPDR);
596: 8f b1 in r24, 0x0f ; 15
SPI_RW(0XFF);;
SPI_RW(0XFF);; //两个字节的CRC校验码,不用关心
temp = SPI_RW(0XFF); //读取返回值
if((temp & 0x1F)!=0x05) //如果返回值是 XXX00DELAY_TIME1 说明数据已经被SD卡接受了
598: 8f 71 andi r24, 0x1F ; 31
59a: 85 30 cpi r24, 0x05 ; 5
59c: 19 f0 breq .+6 ; 0x5a4 <SD_Write_Sector+0xe2>
{
SET_SD_CS;
59e: d8 9a sbi 0x1b, 0 ; 27
5a0: 43 e0 ldi r20, 0x03 ; 3
5a2: 0c c0 rjmp .+24 ; 0x5bc <SD_Write_Sector+0xfa>
//将SS SCK MOSI置为输出
}
uint8_t SPI_RW(uint8_t dat)
{//SPI读写1Byte(欲想读之必先与之)
SPDR = dat;
5a4: 9f ef ldi r25, 0xFF ; 255
5a6: 9f b9 out 0x0f, r25 ; 15
while(!(SPSR & (1 << SPIF)))
5a8: 77 9b sbis 0x0e, 7 ; 14
5aa: fe cf rjmp .-4 ; 0x5a8 <SD_Write_Sector+0xe6>
;
return (SPDR);
5ac: 8f b1 in r24, 0x0f ; 15
{
SET_SD_CS;
return(WRITE_BLOCK_ERROR); //写块数据失败
}
while(SPI_RW(0XFF) != 0XFF);//等到SD卡不忙(数据被接受以后,SD卡要将这些数据写入到自身的FLASH中,需要一个时间)
5ae: 8f 3f cpi r24, 0xFF ; 255
5b0: d1 f7 brne .-12 ; 0x5a6 <SD_Write_Sector+0xe4>
//忙时,读回来的值为0x00,不忙时,为0xff
SET_SD_CS; //关闭片选
5b2: d8 9a sbi 0x1b, 0 ; 27
//将SS SCK MOSI置为输出
}
uint8_t SPI_RW(uint8_t dat)
{//SPI读写1Byte(欲想读之必先与之)
SPDR = dat;
5b4: 8f b9 out 0x0f, r24 ; 15
while(!(SPSR & (1 << SPIF)))
5b6: 77 9b sbis 0x0e, 7 ; 14
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -