📄 sdcard.lst
字号:
223 1 j = 0;
224 1 do
225 1 {
226 2 RdFromSPI(&temp); //读忙标志 为OXFF表示SD卡忙
227 2 j++;
228 2 }
229 1 while((j<1000) && (temp == 0xff)) ;
230 1 Assert_SPI_CS(1);
231 1 if((j >= 1000) || (temp == 0xff)) {/*print("over time\r\n");*/return ERROR;}
232 1 else {/*print("wait:");printhex(j);print("\r\n");*/return NO_ERROR;}
233 1 }
234
235
236
237 // 函数说明 向sd卡发送一个命令
238 //参数:cmdNo命令码,para命令参数,paralen参数长度,respondtype响应类型,respond响应内容指针
239 //返回值:无错的情况下返回NO_ERROR 有错的情况下有两种返回值
240 char SendCmd(unsigned char cmdNo, unsigned char *para, unsigned char respondtype,unsigned char *respond)
C51 COMPILER V7.10 SDCARD 09/18/2007 10:28:29 PAGE 5
241 {
242 1 char i, respondlength, ret;
243 1 unsigned char temp;
244 1 int retry=0;
245 1 //print("in cmd\r\n");
246 1 ret = WriteToSPI((cmdNo & 0x3F) | 0x40); //发送命令字节 置命令码的最高两位为“01”
247 1 for(i=3;i>=0;i--) //发送参数 先发高字节 4字节参数每个命令必须有
248 1 {
249 2 ret = WriteToSPI(para[i]);
250 2 }
251 1 temp = GenerateCRC((cmdNo & 0x3F) | 0x40,para);
252 1 ret = WriteToSPI(temp); //发送校验字节
253 1 switch (respondtype) /* 根据不同的命令,得到不同的响应长度 */
254 1 {
255 2 case R1:
256 2 case R1b: respondlength = 1; break;
257 2 case R2: respondlength = 2; break;
258 2 case R3: respondlength = 5; break;
259 2 default: respondlength = 0; break; /* 返回命令响应类型错误 return error of command response type
- */
260 2 }
261 1 if(respondlength == 0)
262 1 {
263 2 return ERROR; //命令参数中返回类型给错
264 2 }
265 1 RdFromSPI(&temp);
266 1 while((temp & 0x80) != 0)// 等待命令响应,响应的开始位为0
267 1 {
268 2 RdFromSPI(&temp);
269 2 retry++;
270 2 if(retry >= 200) break;
271 2 }
272 1 if((retry >= 200) && ((temp & 0x80) != 0))
273 1 {
274 2 //print("over 200\r\n");
275 2 return ERROR;
276 2
277 2 }
278 1
279 1 respond[0] = temp;
280 1 return NO_ERROR;
281 1 }
282
283
284
285
286
287
288
289
290
291
292 //函数说明 激活sd卡
293 //参数
294 //返回 返回值统一
295 char Activate_SD()
296 {
297 1 char ret;
298 1 unsigned char temp, para[4];
299 1 unsigned char i;
300 1 for(i=0;i<4;i++)
301 1 {
C51 COMPILER V7.10 SDCARD 09/18/2007 10:28:29 PAGE 6
302 2 para[i] = 0;
303 2 }
304 1 Assert_SPI_CS(0);
305 1 do
306 1 {
307 2 ret = SendCmd(1, para, R1,&temp); //发送CMD1
308 2
309 2 if((ret == NO_ERROR) && (temp == 0x00)) //出错处理
310 2 {Assert_SPI_CS(1);return NO_ERROR;}
311 2 i++;
312 2 }
313 1 while(i<200);
314 1
315 1 Assert_SPI_CS(1);
316 1 return ERROR;
317 1
318 1 }
319
320 //函数说明 允许校验与否
321 //参数
322 //返回
323
324
325 char Enable_CRC(unsigned char bEnable)
326 {
327 1 unsigned char ret, temp, para[4];
328 1 // print("in enable crc\r\n");
329 1 if (bEnable == 1)
330 1 para[0] = 1; /* 使能crc enable crc */
331 1 else
332 1 para[1] = 0;
333 1 Assert_SPI_CS(0);
334 1 ret = SendCmd(59, para, R1,&temp); //发送CMD59
335 1 //printhex(temp);
336 1 if(ret == ERROR) {Assert_SPI_CS(1);return ERROR;}
337 1 if(temp != 0x00) {Assert_SPI_CS(1);return ERROR;}
338 1 Assert_SPI_CS(1);
339 1 return NO_ERROR;
340 1 }
341
342
343
344
345 //函数说明 计算命令的校验码
346 //参数
347 //返回
348
349 char GenerateCRC(unsigned char cmdNo, unsigned char *para)
350 {
351 1
352 1 unsigned char i, j;
353 1 unsigned char reg = 0;
354 1 unsigned char array[5];
355 1
356 1 array[0] = cmdNo;
357 1 for (i = 1; i < 5; i++) //将参数的顺序重新排列
358 1 array[i] = para[4 - i];
359 1
360 1 for (i = 0; i < 5; i++) /// 计算5个字节的CRC7
361 1 {
362 2 for (j = 0; j < 8; j++)
363 2 {
C51 COMPILER V7.10 SDCARD 09/18/2007 10:28:29 PAGE 7
364 3 reg <<= 1;
365 3 reg ^= ((((array[i] << j) ^ reg) & 0x80) ? 0x9 : 0);
366 3 }
367 2 }
368 1 return ((reg << 1) + 0x01) ; // 计算结果的CRC7左移一位,并将最低位置1
369 1 }
370
371 //函数说明 复位sd卡
372 //参数
373 //返回 返回值统一
374 char Reset_SD()
375 {
376 1 char ret;
377 1 int i;
378 1 unsigned char para[4];
379 1 char respond;
380 1 Assert_SPI_CS(0);
381 1 for(i=0;i<4;i++)
382 1 {
383 2 para[i] = 0;
384 2 }
385 1 for(i=0;i<100;i++)
386 1 {
387 2 ret = SendCmd(0,¶[0],R1,&respond); //发送CMD0命令
388 2 if((ret == NO_ERROR) && (respond == 0x01))
389 2 {Assert_SPI_CS(1);return NO_ERROR;} //出错处理
390 2 }
391 1 Assert_SPI_CS(1);
392 1 return ERROR;
393 1
394 1 }
395
396
397 //初始化SD卡为SPI模式
398 char InitSDToSpi()
399 {
400 1 char ret;
401 1 unsigned char x;
402 1 Assert_SPI_CS(1); //置SD卡的CS线为高
403 1 for(x=0;x<10;x++) //写80个正脉冲到SD卡 ,要求发送74个
404 1 WriteToSPI(0xff);
405 1 Assert_SPI_CS(0); //CS=0;
406 1 ret = Reset_SD(); //复位SD卡,此时CS = 0,因此进入SPI模式
407 1 if(ret != NO_ERROR) {Assert_SPI_CS(1);return ERROR;}
408 1 else {Assert_SPI_CS(1);return NO_ERROR;}
409 1 }
410
411 //初始化SD卡
412 char InitialSD()
413 {
414 1 while(1)
415 1 {
416 2 if(InitSDToSpi() == NO_ERROR) break; //初始化为SPI模式
417 2 }
418 1 while(1)
419 1 {
420 2 if(Activate_SD() == NO_ERROR) break; //激活SD卡
421 2 }
422 1 while(1)
423 1 {
424 2 if( Enable_CRC(0) == NO_ERROR) break; //不使用校验
425 2
C51 COMPILER V7.10 SDCARD 09/18/2007 10:28:29 PAGE 8
426 2 }
427 1 while(1)
428 1 {
429 2 if( SetBlockLen(512) == NO_ERROR) break; //设置读写块长度为512字节
430 2
431 2 }
432 1 return NO_ERROR;
433 1 }
434
435
436
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1247 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = ---- 75
IDATA SIZE = ---- ----
BIT SIZE = ---- 1
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -