📄 sd_spi.lst
字号:
C51 COMPILER V7.50 SD_SPI 06/04/2008 15:52:40 PAGE 1
C51 COMPILER V7.50, COMPILATION OF MODULE SD_SPI
OBJECT MODULE PLACED IN sd_spi.OBJ
COMPILER INVOKED BY: D:\Keil\C51\BIN\C51.exe sd_spi.c DB OE
line level source
1 //SD卡命令发送程序接口
2
3
4 #include "inc.h"
5 #include "define.h"
6
7 #define MAX SD_BLOCKSIZE
8
9 extern xdata uint8 statuslen = 4;
10 extern xdata uint8 cidlen = 16; //len取值0~MAX
11 //extern xdata uint8 csdlen = 16;
12 extern xdata uint8 sendbuf[16] ={0,1,2,3,4,5,6,7,8,9,0};
13 extern xdata uint8 recbuf[1] ={0};
14 extern xdata uint8 resp[5] = {0};
15
16 uint8 sd_send_cmd(uint8 cmd,uint8 *param,uint8 resptype,uint8 *resp) //发送命令
17 {
18 1
19 1 char i,rlen;
20 1 uint8 tmp;
21 1 spi_cs_clr();
22 1 // command = 0;
23 1
24 1 spi_sendbyte(((cmd & 0x3f) | 0x40)); //发送命令头和命令字
25 1
26 1 for(i=3;i>=0;i--)
27 1 {
28 2 spi_sendbyte(param[i]); //发送 send parameters
29 2 }
30 1
31 1 if(cmd == 0)
32 1 spi_sendbyte(0x95); //CRC校验,用于第一个命令
33 1 else
34 1 spi_sendbyte(0xFF);
35 1
36 1
37 1 switch(resptype)
38 1 {
39 2
40 2 case R1: rlen = 0; break;
41 2 case R1B: rlen = 1; break;
42 2 case R2: rlen = 2; break;
43 2 case R3: rlen = 5; break;
44 2
45 2
46 2 }
47 1
48 1 i = 0;
49 1 do
50 1 {
51 2 tmp = spi_recbyte();
52 2 i++;
53 2
54 2 }
55 1 while(((tmp &0x80 )!= 0) && (i<SD_CMD_TIMEOUT));
C51 COMPILER V7.50 SD_SPI 06/04/2008 15:52:40 PAGE 2
56 1
57 1 if(rlen == 0)
58 1 resp[0] = tmp;
59 1
60 1 for(i =rlen-1;i>=0;i--)
61 1 {
62 2 resp[i] = tmp;
63 2 tmp = spi_recbyte();
64 2 }
65 1
66 1 spi_sendbyte(0xFF);
67 1
68 1 // if((cmd != 9) && (cmd != 10) && (cmd != 13))
69 1 // {
70 1 // spi_cs_set();
71 1
72 1 // }
73 1
74 1 // return ret;
75 1 return tmp;
76 1
77 1 }
78
79
80 void sd_pack_param(uint8 *parameter,uint32 value) //将32位数据转化为4个字节
81 {
82 1
83 1 parameter[3] = (uint8)(value>>24);
84 1 parameter[2] = (uint8)(value>>16);
85 1 parameter[1] = (uint8)(value>>8);
86 1 parameter[0] = (uint8)(value);
87 1
88 1
89 1 }
90
91
92 uint8 sd_block_cmd(uint8 cmd,uint8 restype,uint32 parameter) //块命令
93 {
94 1 uint8 param[4],resp,ret;
95 1
96 1 sd_pack_param(param,parameter);
97 1
98 1 ret = sd_send_cmd(cmd,param,restype,&resp);
99 1
100 1
101 1 return ret;
102 1 }
103
104
105
106
107
108 uint8 sd_set_blocklen(uint32 length) //设置块长度
109 {
110 1 uint8 param[4],resp,ret;
111 1
112 1 sd_pack_param(param,length);
113 1
114 1 ret = sd_send_cmd(CMD16,param,CMD16_R,&resp);
115 1
116 1
117 1 return ret;
C51 COMPILER V7.50 SD_SPI 06/04/2008 15:52:40 PAGE 3
118 1
119 1 }
120
121
122 uint8 sd_crc(uint8 enable)
123 {
124 1 uint8 param[4],resp,ret;
125 1
126 1 if( enable == 1 )
127 1 param[0] = 1; //使能CRC
128 1 else //禁止CRC
129 1 param[1] = 0;
130 1
131 1 ret = sd_send_cmd(CMD59,param,CMD59_R,&resp);
132 1
133 1 if(ret != SD_NO_ERR)
134 1 return ret;
135 1
136 1
137 1 return SD_NO_ERR;
138 1
139 1 }
140
141 uint8 sd_read_single_block(uint32 blockaddr) //读单块命令
142 {
143 1 sd_block_cmd(CMD17,CMD17_R,blockaddr);
144 1
145 1 sd_read(SD_BLOCKSIZE,recbuf);
146 1
147 1 spi_cs_set();
148 1
149 1 return SD_NO_ERR;
150 1
151 1 }
152
153 uint8 sd_read_multiple_block(uint32 blockaddr) //读多块命令,直到收到停止命令
154 {
155 1 sd_block_cmd(CMD18,CMD18_R,blockaddr);
156 1
157 1 spi_cs_set();
158 1
159 1 return SD_NO_ERR;
160 1 }
161
162 uint8 sd_stop_transmission(void) //停止发送
163 {
164 1 uint8 param[4] = {0,0,0,0,},resp;
165 1
166 1 return(sd_send_cmd(CMD12,param,CMD12_R,&resp));
167 1
168 1 }
169
170 uint8 sd_write_single_block(uint32 blockaddr) //写单块命令
171 {
172 1
173 1 sd_block_cmd(CMD24,CMD24_R,blockaddr);
174 1
175 1 sd_write(0,SD_BLOCKSIZE,sendbuf);
176 1
177 1 return SD_NO_ERR;
178 1 }
179
C51 COMPILER V7.50 SD_SPI 06/04/2008 15:52:40 PAGE 4
180 uint8 sd_write_multiple_block_cmd(uint8 blockaddr) //写多块命令
181 {
182 1 sd_block_cmd(CMD25,CMD25_R,blockaddr);
183 1
184 1 sd_write(1,SD_BLOCKSIZE,sendbuf);
185 1
186 1 spi_cs_set();
187 1
188 1 return SD_NO_ERR;
189 1 }
190
191
192 uint8 erase_startblock(uint32 startblock) //设置块擦除起始地址
193 {
194 1
195 1 return(sd_block_cmd(CMD32,CMD32_R,startblock));
196 1
197 1 }
198
199 uint8 erase_endblock(uint32 endblock) //设置块擦除结尾地址
200 {
201 1
202 1 return(sd_block_cmd(CMD33,CMD33_R,endblock));
203 1 }
204
205
206
207 uint8 erase_selectedblock(void) //擦除选中的块
208 {
209 1 uint8 param[4],tmp,resp;
210 1
211 1 sd_pack_param(param,0);
212 1
213 1 tmp = sd_send_cmd(CMD38,param,CMD38_R,&resp);
214 1
215 1 spi_cs_set();
216 1
217 1 return SD_NO_ERR;
218 1
219 1 }
220
221 uint8 sd_check_protect(void)
222 {
223 1 uint8 param[4],tmp,resp;
224 1
225 1 sd_pack_param(param,0);
226 1
227 1 tmp = sd_send_cmd(CMD30,param,CMD29_R,&resp);
228 1
229 1 spi_cs_set();
230 1
231 1 return tmp;
232 1
233 1 }
234
235
236 uint8 sd_clear_protect(void)
237 {
238 1 uint8 param[4],tmp,resp;
239 1
240 1 sd_pack_param(param,0);
241 1
C51 COMPILER V7.50 SD_SPI 06/04/2008 15:52:40 PAGE 5
242 1 tmp = sd_send_cmd(CMD29,param,CMD29_R,&resp);
243 1
244 1 spi_cs_set();
245 1
246 1 return tmp;
247 1
248 1 }
249
250 uint8 sd_set_protect(void)
251 {
252 1 uint8 param[4],tmp,resp;
253 1
254 1 sd_pack_param(param,0);
255 1
256 1 tmp = sd_send_cmd(CMD28,param,CMD28_R,&resp);
257 1
258 1 spi_cs_set();
259 1
260 1 return tmp;
261 1
262 1 }
263
264
265 /************************************数据传输*****************************************/
266
267 uint8 sd_read(uint32 len,char* recbuf) //读SD卡,len为数据长度,recbuf为数据缓冲区
268 {
269 1
270 1 uint8 tmp;
271 1 uint16 i = 0;
272 1
273 1 spi_cs_clr();
274 1
275 1 do
276 1 { //等待数据起始令牌
277 2 tmp = spi_recbyte();
278 2 i++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -