转自:http://blog.csdn.net/ming1006/article/details/7283689

上一篇文章已经介绍了Micro SD卡SPI模式的实现方法,这里给出自己写的基于nios ii的Micro SD卡读写程序(IO口模拟spi)。

硬件设计就不多说了,主要是添加4的1为PIO口来模拟SPI的CS、SCLK、MISO和MOSI。

以下是代码:

头文件SD_spi_solution.h

[cpp]  view plain copy print ?
  1. #ifndef SD_SPI_SOLUTION_H_
  2. #define SD_SPI_SOLUTION_H_
  3. #include<system.h>
  4. #include<alt_types.h>
  5. #include<altera_avalon_pio_regs.h>
  6. #define CMD0    0   /* GO_IDLE_STATE */
  7. #define CMD55   55  /* APP_CMD */
  8. #define ACMD41  41  /* SEND_OP_COND (ACMD) */
  9. #define CMD1    1   /* SEND_OP_COND */
  10. #define CMD17   17  /* READ_SINGLE_BLOCK */
  11. #define CMD8    8   /* SEND_IF_COND */
  12. #define CMD18   18  /* READ_MULTIPLE_BLOCK */
  13. #define CMD12   12  /* STOP_TRANSMISSION */
  14. #define CMD24   24  /* WRITE_BLOCK */
  15. #define CMD25   25  /* WRITE_MULTIPLE_BLOCK */
  16. #define CMD13   13  /* SEND_STATUS */
  17. #define CMD9    9   /* SEND_CSD */
  18. #define CMD10   10  /* SEND_CID */
  19. #define CSD     9
  20. #define CID     10
  21. //delay 1us(actually not,it maybe is several us,I don't test it)
  22. void usleep(alt_u8 i);
  23. //set CS low
  24. void CS_Enable();
  25. //set CS high and send 8 clocks
  26. void CS_Disable();
  27. //write a byte
  28. void SDWriteByte(alt_u8 data);
  29. //read a byte
  30. alt_u8 SDReadByte();
  31. //send a command and send back the response
  32. alt_u8  SDSendCmd(alt_u8 cmd,alt_u32 arg,alt_u8 crc);
  33. //reset SD card
  34. alt_u8 SDReset();
  35. //initial SD card
  36. alt_u8 SDInit();
  37. //read a single sector
  38. alt_u8 SDReadSector(alt_u32 addr,alt_u8 * buffer);
  39. //read multiple sectors
  40. alt_u8 SDReadMultiSector(alt_u32 addr,alt_u8 sector_num,alt_u8 * buffer);
  41. //write a single sector
  42. alt_u8 SDWriteSector(alt_u32 addr,alt_u8 * buffer);
  43. //write multiple sectors
  44. alt_u8 SDWriteMultiSector(alt_u32 addr,alt_u8 sector_num,alt_u8 * buffer);
  45. //get CID or CSD
  46. alt_u8 SDGetCIDCSD(alt_u8 cid_csd,alt_u8 * buffer);
  47. //spi speed(0-255),0 is fastest
  48. alt_u8 spi_speed;
  49. #endif /* SD_SPI_SOLUTION_H_ */

源文件SD_spi_Solution.c

[cpp]  view plain copy print ?
  1. #include"SD_spi_Solution.h"
  2. alt_u8 spi_speed = 10;//the spi speed(0-255),0 is fastest
  3. //delay 1us(actually not,it maybe is several us,I don't test it)
  4. void usleep(alt_u8 i)
  5. {
  6. while(i --);
  7. }
  8. //set CS low
  9. void CS_Enable()
  10. {
  11. //set CS low
  12. IOWR_ALTERA_AVALON_PIO_DATA(CS_BASE, 0x00);
  13. }
  14. //set CS high and send 8 clocks
  15. void CS_Disable()
  16. {
  17. //set CS high
  18. IOWR_ALTERA_AVALON_PIO_DATA(CS_BASE, 0x01);
  19. //send 8 clocks
  20. SDWriteByte(0xff);
  21. }
  22. //write a byte
  23. void SDWriteByte(alt_u8 data)
  24. {
  25. alt_u8 i;
  26. //write 8 bits(MSB)
  27. for(i = 0;i < 8;i ++)
  28. {
  29. IOWR_ALTERA_AVALON_PIO_DATA(SCLK_BASE, 0x00);
  30. usleep(spi_speed);
  31. if(data & 0x80) IOWR_ALTERA_AVALON_PIO_DATA(DI_BASE, 0x01);
  32. else IOWR_ALTERA_AVALON_PIO_DATA(DI_BASE, 0x00);
  33. data <<= 1;
  34. IOWR_ALTERA_AVALON_PIO_DATA(SCLK_BASE, 0x01);
  35. usleep(spi_speed);
  36. }
  37. //when DI is free,it should be set high
  38. IOWR_ALTERA_AVALON_PIO_DATA(DI_BASE, 0x01);
  39. }
  40. //read a byte
  41. alt_u8 SDReadByte()
  42. {
  43. alt_u8 data = 0x00,i;
  44. //read 8 bit(MSB)
  45. for(i = 0;i < 8;i ++)
  46. {
  47. IOWR_ALTERA_AVALON_PIO_DATA(SCLK_BASE, 0x00);
  48. usleep(spi_speed);
  49. IOWR_ALTERA_AVALON_PIO_DATA(SCLK_BASE, 0x01);
  50. data <<= 1;
  51. if(IORD_ALTERA_AVALON_PIO_DATA(DO_BASE)) data |= 0x01;
  52. usleep(spi_speed);
  53. }
  54. return data;
  55. }
  56. //send a command and send back the response
  57. alt_u8  SDSendCmd(alt_u8 cmd,alt_u32 arg,alt_u8 crc)
  58. {
  59. alt_u8 r1,time = 0;
  60. //send the command,arguments and CRC
  61. SDWriteByte((cmd & 0x3f) | 0x40);
  62. SDWriteByte(arg >> 24);
  63. SDWriteByte(arg >> 16);
  64. SDWriteByte(arg >> 8);
  65. SDWriteByte(arg);
  66. SDWriteByte(crc);
  67. //read the respond until responds is not '0xff' or timeout
  68. do{
  69. r1 = SDReadByte();
  70. time ++;
  71. //if time out,return
  72. if(time > 254) break;
  73. }while(r1 == 0xff);
  74. return r1;
  75. }
  76. //reset SD card
  77. alt_u8 SDReset()
  78. {
  79. alt_u8 i,r1,time = 0;
  80. //set CS high
  81. CS_Disable();
  82. //send 128 clocks
  83. for(i = 0;i < 16;i ++)
  84. {
  85. SDWriteByte(0xff);
  86. }
  87. //set CS low
  88. CS_Enable();
  89. //send CMD0 till the response is 0x01
  90. do{
  91. r1 = SDSendCmd(CMD0,0,0x95);
  92. time ++;
  93. //if time out,set CS high and return r1
  94. if(time > 254)
  95. {
  96. //set CS high and send 8 clocks
  97. CS_Disable();
  98. return r1;
  99. }
  100. }while(r1 != 0x01);
  101. //set CS high and send 8 clocks
  102. CS_Disable();
  103. return 0;
  104. }
  105. //initial SD card(send CMD55+ACMD41 or CMD1)
  106. alt_u8 SDInit()
  107. {
  108. alt_u8 r1,time = 0;
  109. //set CS low
  110. CS_Enable();
  111. //check interface operating condition
  112. r1 = SDSendCmd(CMD8,0x000001aa,0x87);
  113. //if support Ver1.x,but do not support Ver2.0,set CS high and return r1
  114. if(r1 == 0x05)
  115. {
  116. //set CS high and send 8 clocks
  117. CS_Disable();
  118. return r1;
  119. }
  120. //read the other 4 bytes of response(the response of CMD8 is 5 bytes)
  121. r1=SDReadByte();
  122. r1=SDReadByte();
  123. r1=SDReadByte();
  124. r1=SDReadByte();
  125. do{
  126. //send CMD55+ACMD41 to initial SD card
  127. do{
  128. r1 = SDSendCmd(CMD55,0,0xff);
  129. time ++;
  130. //if time out,set CS high and return r1
  131. if(time > 254)
  132. {
  133. //set CS high and send 8 clocks
  134. CS_Disable();
  135. return r1;
  136. }
  137. }while(r1 != 0x01);
  138. r1 = SDSendCmd(ACMD41,0x40000000,0xff);
  139. //send CMD1 to initial SD card
  140. //r1 = SDSendCmd(CMD1,0x00ffc000,0xff);
  141. time ++;
  142. //if time out,set CS high and return r1
  143. if(time > 254)
  144. {
  145. //set CS high and send 8 clocks
  146. CS_Disable();
  147. return r1;
  148. }
  149. }while(r1 != 0x00);
  150. //set CS high and send 8 clocks
  151. CS_Disable();
  152. return 0;
  153. }
  154. //read a single sector
  155. alt_u8 SDReadSector(alt_u32 addr,alt_u8 * buffer)
  156. {
  157. alt_u8 r1;
  158. alt_u16 i,time = 0;
  159. //set CS low
  160. CS_Enable();
  161. //send CMD17 for single block read
  162. r1 = SDSendCmd(CMD17,addr << 9,0x55);
  163. //if CMD17 fail,return
  164. if(r1 != 0x00)
  165. {
  166. //set CS high and send 8 clocks
  167. CS_Disable();
  168. return r1;
  169. }
  170. //continually read till get the start byte 0xfe
  171. do{
  172. r1 = SDReadByte();
  173. time ++;
  174. //if time out,set CS high and return r1
  175. if(time > 30000)
  176. {
  177. //set CS high and send 8 clocks
  178. CS_Disable();
  179. return r1;
  180. }
  181. }while(r1 != 0xfe);
  182. //read 512 Bits of data
  183. for(i = 0;i < 512;i ++)
  184. {
  185. buffer[i] = SDReadByte();
  186. }
  187. //read two bits of CRC
  188. SDReadByte();
  189. SDReadByte();
  190. //set CS high and send 8 clocks
  191. CS_Disable();
  192. return 0;
  193. }
  194. //read multiple sectors
  195. alt_u8 SDReadMultiSector(alt_u32 addr,alt_u8 sector_num,alt_u8 * buffer)
  196. {
  197. alt_u16 i,time = 0;
  198. alt_u8 r1;
  199. //set CS low
  200. CS_Enable();
  201. //send CMD18 for multiple blocks read
  202. r1 = SDSendCmd(CMD18,addr << 9,0xff);
  203. //if CMD18 fail,return
  204. if(r1 != 0x00)
  205. {
  206. //set CS high and send 8 clocks
  207. CS_Disable();
  208. return r1;
  209. }
  210. //read sector_num sector
  211. do{
  212. //continually read till get start byte
  213. do{
  214. r1 = SDReadByte();
  215. time ++;
  216. //if time out,set CS high and return r1
  217. if(time > 30000 || ((r1 & 0xf0) == 0x00 && (r1 & 0x0f)))
  218. {
  219. //set CS high and send 8 clocks
  220. CS_Disable();
  221. return r1;
  222. }
  223. }while(r1 != 0xfe);
  224. time = 0;
  225. //read 512 Bits of data
  226. for(i = 0;i < 512;i ++)
  227. {
  228. *buffer ++ = SDReadByte();
  229. }
  230. //read two bits of CRC
  231. SDReadByte();
  232. SDReadByte();
  233. }while( -- sector_num);
  234. time = 0;
  235. //stop multiple reading
  236. r1 = SDSendCmd(CMD12,0,0xff);
  237. //set CS high and send 8 clocks
  238. CS_Disable();
  239. return 0;
  240. }
  241. //write a single sector
  242. alt_u8 SDWriteSector(alt_u32 addr,alt_u8 * buffer)
  243. {
  244. alt_u16 i,time = 0;
  245. alt_u8 r1;
  246. //set CS low
  247. CS_Enable();
  248. do{
  249. do{
  250. //send CMD24 for single block write
  251. r1 = SDSendCmd(CMD24,addr << 9,0xff);
  252. time ++;
  253. //if time out,set CS high and return r1
  254. if(time > 254)
  255. {
  256. //set CS high and send 8 clocks
  257. CS_Disable();
  258. return r1;
  259. }
  260. }while(r1 != 0x00);
  261. time = 0;
  262. //send some dummy clocks
  263. for(i = 0;i < 5;i ++)
  264. {
  265. SDWriteByte(0xff);
  266. }
  267. //write start byte
  268. SDWriteByte(0xfe);
  269. //write 512 bytes of data
  270. for(i = 0;i < 512;i ++)
  271. {
  272. SDWriteByte(buffer[i]);
  273. }
  274. //write 2 bytes of CRC
  275. SDWriteByte(0xff);
  276. SDWriteByte(0xff);
  277. //read response
  278. r1 = SDReadByte();
  279. time ++;
  280. //if time out,set CS high and return r1
  281. if(time > 254)
  282. {
  283. //set CS high and send 8 clocks
  284. CS_Disable();
  285. return r1;
  286. }
  287. }while((r1 & 0x1f)!= 0x05);
  288. time = 0;
  289. //check busy
  290. do{
  291. r1 = SDReadByte();
  292. time ++;
  293. //if time out,set CS high and return r1
  294. if(time > 60000)
  295. {
  296. //set CS high and send 8 clocks
  297. CS_Disable();
  298. return r1;
  299. }
  300. }while(r1 != 0xff);
  301. //set CS high and send 8 clocks
  302. CS_Disable();
  303. return 0;
  304. }
  305. //write several blocks
  306. alt_u8 SDWriteMultiSector(alt_u32 addr,alt_u8 sector_num,alt_u8 * buffer)
  307. {
  308. alt_u16 i,time = 0;
  309. alt_u8 r1;
  310. //set CS low
  311. CS_Enable();
  312. //send CMD25 for multiple block read
  313. r1 = SDSendCmd(CMD25,addr << 9,0xff);
  314. //if CMD25 fail,return
  315. if(r1 != 0x00)
  316. {
  317. //set CS high and send 8 clocks
  318. CS_Disable();
  319. return r1;
  320. }
  321. do{
  322. do{
  323. //send several dummy clocks
  324. for(i = 0;i < 5;i ++)
  325. {
  326. SDWriteByte(0xff);
  327. }
  328. //write start byte
  329. SDWriteByte(0xfc);
  330. //write 512 byte of data
  331. for(i = 0;i < 512;i ++)
  332. {
  333. SDWriteByte(*buffer ++);
  334. }
  335. //write 2 byte of CRC
  336. SDWriteByte(0xff);
  337. SDWriteByte(0xff);
  338. //read response
  339. r1 = SDReadByte();
  340. time ++;
  341. //if time out,set CS high and return r1
  342. if(time > 254)
  343. {
  344. //set CS high and send 8 clocks
  345. CS_Disable();
  346. return r1;
  347. }
  348. }while((r1 & 0x1f)!= 0x05);
  349. time = 0;
  350. //check busy
  351. do{
  352. r1 = SDReadByte();printf("n%d",r1);
  353. time ++;
  354. //if time out,set CS high and return r1
  355. if(time > 30000)
  356. {
  357. //set CS high and send 8 clocks
  358. CS_Disable();
  359. return r1;
  360. }
  361. }while(r1 != 0xff);
  362. time = 0;
  363. }while(-- sector_num);
  364. //send stop byte
  365. SDWriteByte(0xfd);
  366. //check busy
  367. do{
  368. r1 = SDReadByte();
  369. time ++;
  370. //if time out,set CS high and return r1
  371. if(time > 30000)
  372. {
  373. //set CS high and send 8 clocks
  374. CS_Disable();
  375. return r1;
  376. }
  377. }while(r1 != 0xff);
  378. //set CS high and send 8 clocks
  379. CS_Disable();
  380. return 0;
  381. }
  382. //get CID or CSD
  383. alt_u8 SDGetCIDCSD(alt_u8 cid_csd,alt_u8 * buffer)
  384. {
  385. alt_u8 r1;
  386. alt_u16 i,time = 0;
  387. //set CS low
  388. CS_Enable();
  389. //send CMD10 for CID read or CMD9 for CSD
  390. do{
  391. if(cid_csd == CID)
  392. r1 = SDSendCmd(CMD10,0,0xff);
  393. else
  394. r1 = SDSendCmd(CMD9,0,0xff);
  395. time ++;
  396. //if time out,set CS high and return r1
  397. if(time > 254)
  398. {
  399. //set CS high and send 8 clocks
  400. CS_Disable();
  401. return r1;
  402. }
  403. }while(r1 != 0x00);
  404. time = 0;
  405. //continually read till get 0xfe
  406. do{
  407. r1 = SDReadByte();
  408. time ++;
  409. //if time out,set CS high and return r1
  410. if(time > 30000)
  411. {
  412. //set CS high and send 8 clocks
  413. CS_Disable();
  414. return r1;
  415. }
  416. }while(r1 != 0xfe);
  417. //read 512 Bits of data
  418. for(i = 0;i < 16;i ++)
  419. {
  420. *buffer ++ = SDReadByte();
  421. }
  422. //read two bits of CRC
  423. SDReadByte();
  424. SDReadByte();
  425. //set CS high and send 8 clocks
  426. CS_Disable();
  427. return 0;
  428. }

Micro SD卡(TF卡)spi相关推荐

  1. 物联网开发笔记(60)- 使用Micropython开发ESP32开发板之SPI接口控制Micro SD卡TF卡模块

    一.目的 这一节我们学习如何使用我们的ESP32开发板来通过SPI接口控制Micro SD卡TF卡模块. 二.环境 ESP32 + SPI接口控制Micro SD卡TF卡模块 + Thonny IDE ...

  2. 物联网开发笔记(96)- Micropython ESP32开发之SPI接口控制Micro SD卡TF卡模块挂载内存卡

    一.目的 这一节我们学习如何使用乐鑫的ESP32开发板连接SD卡模块,进行目录.文件的相关操作. 在早前我们也介绍过TFT SD卡的操作,这里我们重新复习一下. 物联网开发笔记(60)- 使用Micr ...

  3. PCB模块化设计07——Micro SD卡/TF卡PCB布局布线设计规范

    目录 PCB模块化设计07--Micro SD卡/TF卡PCB布局布线设计规范 1.定义 2.引脚定义 3.TF卡布局布线要求 PCB模块化设计07--Micro SD卡/TF卡PCB布局布线设计规范 ...

  4. 基础——ROM, RAM, FLASH, SSD, DDR3/4, eMMC, UFS, SD卡, TF卡,相互关系

    1. 关系 ROM, RAM, FLASH闪存, SSD, DDR3/4, eMMC, UFS, SD卡, TF卡, 这几个名词在手机和电脑等数码产品的参数中经常出现,单独看还明白是什么,放在一块,他 ...

  5. tf卡量产工具万能版_手上还有SD卡/TF卡的小伙伴,这些玩法你有关注过吗

    技术的更迭,总会有一些产品或者技术成为过去时,当小狮子拉开抽屉时,总会有N个U盘又或者SD卡/TF卡不呆在某个角落吃灰,对于这些曾经很火的小物件,真的就只能扔在角落里偶尔怀念一下了吗? 有些落寞的SD ...

  6. Keil MDK STM32系列(九) 基于HAL和FatFs的FAT格式SD卡TF卡读写

    Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...

  7. SD卡 TF卡 接口引脚定义

    SD卡 TF卡 接口引脚定义

  8. 使用SD Card Formatter工具格式化还原容量变少的SD卡TF卡

    By Mcuzone 关键词: SD卡  TF卡  Linux分区  FAT32  exFAT  NTFS  SD Card Formatter 概述:SD卡/TF卡是应用广泛的存储媒介,在嵌入式系统 ...

  9. SD卡 TF卡 , micro-SD卡信号接口引脚定义

    SD卡 TF卡 , micro-SD卡信号接口引脚定义 #SD卡 TF卡 , micro-SD卡信号接口引脚定义#

  10. SD卡TF卡CF卡相机卡的照片等数据如何去恢复?

    SD卡TF卡CF卡相机卡的照片等数据如何去恢复? 1.首先将深度数据恢复软件安装到电脑上, 2.运行安装好的软件,进入软件操作主界面,在界面左侧的功能选择栏中--选择遇到的问题扫描 3.点击后,在跳转 ...

最新文章

  1. Android入门(十七)Android多线程
  2. Nginx动态路由的新姿势:使用Go取代lua
  3. java通过代码显示特定窗体,如何把这两段代码在一个窗体显示,类似于windows自带的扫雷一样...
  4. python excel详解_python操作excel详解
  5. 如何看待事理图谱版magi--学迹
  6. MongoDB警告信息
  7. linux nginx 清除缓存文件,linux nginx 内置缓存怎么去掉
  8. hdu 1142 记忆化搜索
  9. 我比领导小15岁,互相有好感,为什么每次路过我办公室都叹气?
  10. kotlin android 镜像,【54】Kotlin android Anko 神兵利器
  11. 【STL源码剖析读书笔记】自己实现stack之MyStack(底层用MyList)
  12. 牛顿插值法python代码_Python实现牛顿插值法(差商表)
  13. python调用讯飞付费版语音转写
  14. TQ2440开发板移植UBOOT-2010.06总结(2)
  15. python .center用法_python之testcenter操作
  16. 绿色建筑、装配式建筑工作加速推进,建筑行业招聘需求急速飞升
  17. Java API VIII
  18. html实现展开余下全文多个,DIV+css内容太长,怎么实现点击展开余下全文?
  19. 桌面的此电脑图标变成了快捷方式如何解决?
  20. Jordan CP3 11 Performance Reviews

热门文章

  1. OSChina 周三乱弹 —— 喜欢你的时候尾巴会竖起来
  2. 面试题-HTTP/HTML/浏览器
  3. 求一个矩阵中的马鞍点(c语言实现)
  4. Reeds-Shepp和Dubins曲线简介
  5. 双目立体匹配之视差优化
  6. Mac如何允许安装任何来源软件?
  7. 鸿蒙os更换壁纸,鸿蒙OS全新PC桌面模式即将上线?回顾一下手机桌面系统的发展历程...
  8. android系统中“关于设备”中android版本和android安全补丁信息修改
  9. 中国微电机行业需求规模与竞争格局研究报告2022版
  10. Unity 制作翻书电子书,外部异步加载千张图片(一)