Micro SD卡(TF卡)spi
转自: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
- #ifndef SD_SPI_SOLUTION_H_
- #define SD_SPI_SOLUTION_H_
- #include<system.h>
- #include<alt_types.h>
- #include<altera_avalon_pio_regs.h>
- #define CMD0 0 /* GO_IDLE_STATE */
- #define CMD55 55 /* APP_CMD */
- #define ACMD41 41 /* SEND_OP_COND (ACMD) */
- #define CMD1 1 /* SEND_OP_COND */
- #define CMD17 17 /* READ_SINGLE_BLOCK */
- #define CMD8 8 /* SEND_IF_COND */
- #define CMD18 18 /* READ_MULTIPLE_BLOCK */
- #define CMD12 12 /* STOP_TRANSMISSION */
- #define CMD24 24 /* WRITE_BLOCK */
- #define CMD25 25 /* WRITE_MULTIPLE_BLOCK */
- #define CMD13 13 /* SEND_STATUS */
- #define CMD9 9 /* SEND_CSD */
- #define CMD10 10 /* SEND_CID */
- #define CSD 9
- #define CID 10
- //delay 1us(actually not,it maybe is several us,I don't test it)
- void usleep(alt_u8 i);
- //set CS low
- void CS_Enable();
- //set CS high and send 8 clocks
- void CS_Disable();
- //write a byte
- void SDWriteByte(alt_u8 data);
- //read a byte
- alt_u8 SDReadByte();
- //send a command and send back the response
- alt_u8 SDSendCmd(alt_u8 cmd,alt_u32 arg,alt_u8 crc);
- //reset SD card
- alt_u8 SDReset();
- //initial SD card
- alt_u8 SDInit();
- //read a single sector
- alt_u8 SDReadSector(alt_u32 addr,alt_u8 * buffer);
- //read multiple sectors
- alt_u8 SDReadMultiSector(alt_u32 addr,alt_u8 sector_num,alt_u8 * buffer);
- //write a single sector
- alt_u8 SDWriteSector(alt_u32 addr,alt_u8 * buffer);
- //write multiple sectors
- alt_u8 SDWriteMultiSector(alt_u32 addr,alt_u8 sector_num,alt_u8 * buffer);
- //get CID or CSD
- alt_u8 SDGetCIDCSD(alt_u8 cid_csd,alt_u8 * buffer);
- //spi speed(0-255),0 is fastest
- alt_u8 spi_speed;
- #endif /* SD_SPI_SOLUTION_H_ */
源文件SD_spi_Solution.c
- #include"SD_spi_Solution.h"
- alt_u8 spi_speed = 10;//the spi speed(0-255),0 is fastest
- //delay 1us(actually not,it maybe is several us,I don't test it)
- void usleep(alt_u8 i)
- {
- while(i --);
- }
- //set CS low
- void CS_Enable()
- {
- //set CS low
- IOWR_ALTERA_AVALON_PIO_DATA(CS_BASE, 0x00);
- }
- //set CS high and send 8 clocks
- void CS_Disable()
- {
- //set CS high
- IOWR_ALTERA_AVALON_PIO_DATA(CS_BASE, 0x01);
- //send 8 clocks
- SDWriteByte(0xff);
- }
- //write a byte
- void SDWriteByte(alt_u8 data)
- {
- alt_u8 i;
- //write 8 bits(MSB)
- for(i = 0;i < 8;i ++)
- {
- IOWR_ALTERA_AVALON_PIO_DATA(SCLK_BASE, 0x00);
- usleep(spi_speed);
- if(data & 0x80) IOWR_ALTERA_AVALON_PIO_DATA(DI_BASE, 0x01);
- else IOWR_ALTERA_AVALON_PIO_DATA(DI_BASE, 0x00);
- data <<= 1;
- IOWR_ALTERA_AVALON_PIO_DATA(SCLK_BASE, 0x01);
- usleep(spi_speed);
- }
- //when DI is free,it should be set high
- IOWR_ALTERA_AVALON_PIO_DATA(DI_BASE, 0x01);
- }
- //read a byte
- alt_u8 SDReadByte()
- {
- alt_u8 data = 0x00,i;
- //read 8 bit(MSB)
- for(i = 0;i < 8;i ++)
- {
- IOWR_ALTERA_AVALON_PIO_DATA(SCLK_BASE, 0x00);
- usleep(spi_speed);
- IOWR_ALTERA_AVALON_PIO_DATA(SCLK_BASE, 0x01);
- data <<= 1;
- if(IORD_ALTERA_AVALON_PIO_DATA(DO_BASE)) data |= 0x01;
- usleep(spi_speed);
- }
- return data;
- }
- //send a command and send back the response
- alt_u8 SDSendCmd(alt_u8 cmd,alt_u32 arg,alt_u8 crc)
- {
- alt_u8 r1,time = 0;
- //send the command,arguments and CRC
- SDWriteByte((cmd & 0x3f) | 0x40);
- SDWriteByte(arg >> 24);
- SDWriteByte(arg >> 16);
- SDWriteByte(arg >> 8);
- SDWriteByte(arg);
- SDWriteByte(crc);
- //read the respond until responds is not '0xff' or timeout
- do{
- r1 = SDReadByte();
- time ++;
- //if time out,return
- if(time > 254) break;
- }while(r1 == 0xff);
- return r1;
- }
- //reset SD card
- alt_u8 SDReset()
- {
- alt_u8 i,r1,time = 0;
- //set CS high
- CS_Disable();
- //send 128 clocks
- for(i = 0;i < 16;i ++)
- {
- SDWriteByte(0xff);
- }
- //set CS low
- CS_Enable();
- //send CMD0 till the response is 0x01
- do{
- r1 = SDSendCmd(CMD0,0,0x95);
- time ++;
- //if time out,set CS high and return r1
- if(time > 254)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- }while(r1 != 0x01);
- //set CS high and send 8 clocks
- CS_Disable();
- return 0;
- }
- //initial SD card(send CMD55+ACMD41 or CMD1)
- alt_u8 SDInit()
- {
- alt_u8 r1,time = 0;
- //set CS low
- CS_Enable();
- //check interface operating condition
- r1 = SDSendCmd(CMD8,0x000001aa,0x87);
- //if support Ver1.x,but do not support Ver2.0,set CS high and return r1
- if(r1 == 0x05)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- //read the other 4 bytes of response(the response of CMD8 is 5 bytes)
- r1=SDReadByte();
- r1=SDReadByte();
- r1=SDReadByte();
- r1=SDReadByte();
- do{
- //send CMD55+ACMD41 to initial SD card
- do{
- r1 = SDSendCmd(CMD55,0,0xff);
- time ++;
- //if time out,set CS high and return r1
- if(time > 254)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- }while(r1 != 0x01);
- r1 = SDSendCmd(ACMD41,0x40000000,0xff);
- //send CMD1 to initial SD card
- //r1 = SDSendCmd(CMD1,0x00ffc000,0xff);
- time ++;
- //if time out,set CS high and return r1
- if(time > 254)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- }while(r1 != 0x00);
- //set CS high and send 8 clocks
- CS_Disable();
- return 0;
- }
- //read a single sector
- alt_u8 SDReadSector(alt_u32 addr,alt_u8 * buffer)
- {
- alt_u8 r1;
- alt_u16 i,time = 0;
- //set CS low
- CS_Enable();
- //send CMD17 for single block read
- r1 = SDSendCmd(CMD17,addr << 9,0x55);
- //if CMD17 fail,return
- if(r1 != 0x00)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- //continually read till get the start byte 0xfe
- do{
- r1 = SDReadByte();
- time ++;
- //if time out,set CS high and return r1
- if(time > 30000)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- }while(r1 != 0xfe);
- //read 512 Bits of data
- for(i = 0;i < 512;i ++)
- {
- buffer[i] = SDReadByte();
- }
- //read two bits of CRC
- SDReadByte();
- SDReadByte();
- //set CS high and send 8 clocks
- CS_Disable();
- return 0;
- }
- //read multiple sectors
- alt_u8 SDReadMultiSector(alt_u32 addr,alt_u8 sector_num,alt_u8 * buffer)
- {
- alt_u16 i,time = 0;
- alt_u8 r1;
- //set CS low
- CS_Enable();
- //send CMD18 for multiple blocks read
- r1 = SDSendCmd(CMD18,addr << 9,0xff);
- //if CMD18 fail,return
- if(r1 != 0x00)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- //read sector_num sector
- do{
- //continually read till get start byte
- do{
- r1 = SDReadByte();
- time ++;
- //if time out,set CS high and return r1
- if(time > 30000 || ((r1 & 0xf0) == 0x00 && (r1 & 0x0f)))
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- }while(r1 != 0xfe);
- time = 0;
- //read 512 Bits of data
- for(i = 0;i < 512;i ++)
- {
- *buffer ++ = SDReadByte();
- }
- //read two bits of CRC
- SDReadByte();
- SDReadByte();
- }while( -- sector_num);
- time = 0;
- //stop multiple reading
- r1 = SDSendCmd(CMD12,0,0xff);
- //set CS high and send 8 clocks
- CS_Disable();
- return 0;
- }
- //write a single sector
- alt_u8 SDWriteSector(alt_u32 addr,alt_u8 * buffer)
- {
- alt_u16 i,time = 0;
- alt_u8 r1;
- //set CS low
- CS_Enable();
- do{
- do{
- //send CMD24 for single block write
- r1 = SDSendCmd(CMD24,addr << 9,0xff);
- time ++;
- //if time out,set CS high and return r1
- if(time > 254)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- }while(r1 != 0x00);
- time = 0;
- //send some dummy clocks
- for(i = 0;i < 5;i ++)
- {
- SDWriteByte(0xff);
- }
- //write start byte
- SDWriteByte(0xfe);
- //write 512 bytes of data
- for(i = 0;i < 512;i ++)
- {
- SDWriteByte(buffer[i]);
- }
- //write 2 bytes of CRC
- SDWriteByte(0xff);
- SDWriteByte(0xff);
- //read response
- r1 = SDReadByte();
- time ++;
- //if time out,set CS high and return r1
- if(time > 254)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- }while((r1 & 0x1f)!= 0x05);
- time = 0;
- //check busy
- do{
- r1 = SDReadByte();
- time ++;
- //if time out,set CS high and return r1
- if(time > 60000)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- }while(r1 != 0xff);
- //set CS high and send 8 clocks
- CS_Disable();
- return 0;
- }
- //write several blocks
- alt_u8 SDWriteMultiSector(alt_u32 addr,alt_u8 sector_num,alt_u8 * buffer)
- {
- alt_u16 i,time = 0;
- alt_u8 r1;
- //set CS low
- CS_Enable();
- //send CMD25 for multiple block read
- r1 = SDSendCmd(CMD25,addr << 9,0xff);
- //if CMD25 fail,return
- if(r1 != 0x00)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- do{
- do{
- //send several dummy clocks
- for(i = 0;i < 5;i ++)
- {
- SDWriteByte(0xff);
- }
- //write start byte
- SDWriteByte(0xfc);
- //write 512 byte of data
- for(i = 0;i < 512;i ++)
- {
- SDWriteByte(*buffer ++);
- }
- //write 2 byte of CRC
- SDWriteByte(0xff);
- SDWriteByte(0xff);
- //read response
- r1 = SDReadByte();
- time ++;
- //if time out,set CS high and return r1
- if(time > 254)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- }while((r1 & 0x1f)!= 0x05);
- time = 0;
- //check busy
- do{
- r1 = SDReadByte();printf("n%d",r1);
- time ++;
- //if time out,set CS high and return r1
- if(time > 30000)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- }while(r1 != 0xff);
- time = 0;
- }while(-- sector_num);
- //send stop byte
- SDWriteByte(0xfd);
- //check busy
- do{
- r1 = SDReadByte();
- time ++;
- //if time out,set CS high and return r1
- if(time > 30000)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- }while(r1 != 0xff);
- //set CS high and send 8 clocks
- CS_Disable();
- return 0;
- }
- //get CID or CSD
- alt_u8 SDGetCIDCSD(alt_u8 cid_csd,alt_u8 * buffer)
- {
- alt_u8 r1;
- alt_u16 i,time = 0;
- //set CS low
- CS_Enable();
- //send CMD10 for CID read or CMD9 for CSD
- do{
- if(cid_csd == CID)
- r1 = SDSendCmd(CMD10,0,0xff);
- else
- r1 = SDSendCmd(CMD9,0,0xff);
- time ++;
- //if time out,set CS high and return r1
- if(time > 254)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- }while(r1 != 0x00);
- time = 0;
- //continually read till get 0xfe
- do{
- r1 = SDReadByte();
- time ++;
- //if time out,set CS high and return r1
- if(time > 30000)
- {
- //set CS high and send 8 clocks
- CS_Disable();
- return r1;
- }
- }while(r1 != 0xfe);
- //read 512 Bits of data
- for(i = 0;i < 16;i ++)
- {
- *buffer ++ = SDReadByte();
- }
- //read two bits of CRC
- SDReadByte();
- SDReadByte();
- //set CS high and send 8 clocks
- CS_Disable();
- return 0;
- }
Micro SD卡(TF卡)spi相关推荐
- 物联网开发笔记(60)- 使用Micropython开发ESP32开发板之SPI接口控制Micro SD卡TF卡模块
一.目的 这一节我们学习如何使用我们的ESP32开发板来通过SPI接口控制Micro SD卡TF卡模块. 二.环境 ESP32 + SPI接口控制Micro SD卡TF卡模块 + Thonny IDE ...
- 物联网开发笔记(96)- Micropython ESP32开发之SPI接口控制Micro SD卡TF卡模块挂载内存卡
一.目的 这一节我们学习如何使用乐鑫的ESP32开发板连接SD卡模块,进行目录.文件的相关操作. 在早前我们也介绍过TFT SD卡的操作,这里我们重新复习一下. 物联网开发笔记(60)- 使用Micr ...
- PCB模块化设计07——Micro SD卡/TF卡PCB布局布线设计规范
目录 PCB模块化设计07--Micro SD卡/TF卡PCB布局布线设计规范 1.定义 2.引脚定义 3.TF卡布局布线要求 PCB模块化设计07--Micro SD卡/TF卡PCB布局布线设计规范 ...
- 基础——ROM, RAM, FLASH, SSD, DDR3/4, eMMC, UFS, SD卡, TF卡,相互关系
1. 关系 ROM, RAM, FLASH闪存, SSD, DDR3/4, eMMC, UFS, SD卡, TF卡, 这几个名词在手机和电脑等数码产品的参数中经常出现,单独看还明白是什么,放在一块,他 ...
- tf卡量产工具万能版_手上还有SD卡/TF卡的小伙伴,这些玩法你有关注过吗
技术的更迭,总会有一些产品或者技术成为过去时,当小狮子拉开抽屉时,总会有N个U盘又或者SD卡/TF卡不呆在某个角落吃灰,对于这些曾经很火的小物件,真的就只能扔在角落里偶尔怀念一下了吗? 有些落寞的SD ...
- Keil MDK STM32系列(九) 基于HAL和FatFs的FAT格式SD卡TF卡读写
Keil MDK STM32系列 Keil MDK STM32系列(一) 基于标准外设库SPL的STM32F103开发 Keil MDK STM32系列(二) 基于标准外设库SPL的STM32F401 ...
- SD卡 TF卡 接口引脚定义
SD卡 TF卡 接口引脚定义
- 使用SD Card Formatter工具格式化还原容量变少的SD卡TF卡
By Mcuzone 关键词: SD卡 TF卡 Linux分区 FAT32 exFAT NTFS SD Card Formatter 概述:SD卡/TF卡是应用广泛的存储媒介,在嵌入式系统 ...
- SD卡 TF卡 , micro-SD卡信号接口引脚定义
SD卡 TF卡 , micro-SD卡信号接口引脚定义 #SD卡 TF卡 , micro-SD卡信号接口引脚定义#
- SD卡TF卡CF卡相机卡的照片等数据如何去恢复?
SD卡TF卡CF卡相机卡的照片等数据如何去恢复? 1.首先将深度数据恢复软件安装到电脑上, 2.运行安装好的软件,进入软件操作主界面,在界面左侧的功能选择栏中--选择遇到的问题扫描 3.点击后,在跳转 ...
最新文章
- Android入门(十七)Android多线程
- Nginx动态路由的新姿势:使用Go取代lua
- java通过代码显示特定窗体,如何把这两段代码在一个窗体显示,类似于windows自带的扫雷一样...
- python excel详解_python操作excel详解
- 如何看待事理图谱版magi--学迹
- MongoDB警告信息
- linux nginx 清除缓存文件,linux nginx 内置缓存怎么去掉
- hdu 1142 记忆化搜索
- 我比领导小15岁,互相有好感,为什么每次路过我办公室都叹气?
- kotlin android 镜像,【54】Kotlin android Anko 神兵利器
- 【STL源码剖析读书笔记】自己实现stack之MyStack(底层用MyList)
- 牛顿插值法python代码_Python实现牛顿插值法(差商表)
- python调用讯飞付费版语音转写
- TQ2440开发板移植UBOOT-2010.06总结(2)
- python .center用法_python之testcenter操作
- 绿色建筑、装配式建筑工作加速推进,建筑行业招聘需求急速飞升
- Java API VIII
- html实现展开余下全文多个,DIV+css内容太长,怎么实现点击展开余下全文?
- 桌面的此电脑图标变成了快捷方式如何解决?
- Jordan CP3 11 Performance Reviews
热门文章
- OSChina 周三乱弹 —— 喜欢你的时候尾巴会竖起来
- 面试题-HTTP/HTML/浏览器
- 求一个矩阵中的马鞍点(c语言实现)
- Reeds-Shepp和Dubins曲线简介
- 双目立体匹配之视差优化
- Mac如何允许安装任何来源软件?
- 鸿蒙os更换壁纸,鸿蒙OS全新PC桌面模式即将上线?回顾一下手机桌面系统的发展历程...
- android系统中“关于设备”中android版本和android安全补丁信息修改
- 中国微电机行业需求规模与竞争格局研究报告2022版
- Unity 制作翻书电子书,外部异步加载千张图片(一)