我是靠谱客的博主 傻傻飞鸟,最近开发中收集的这篇文章主要介绍卡spi驱动代码_stm32 SPI读写储存卡(MicroSD TF卡)简述操作分析及实现实现,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
简述
花了较长的时间,来弄读写储存卡(大部分教程讲的比较全但是不是很容易懂),这里希望我的代码经验能够帮助到你。
操作分析及实现
0.整个流程
1、上电以后储存卡的初始化
2、如何进行读写
实现
1.上电以后储存卡的初始化
上电给MicroSD卡至少74个时钟信号发送CDM0 (x041)复位发送CMD1 让MicroSD卡进入SPI模式
2.如何进行读写
这里主要对1,3进行详细的讨论你需要知道的是spi通信是怎样进行的就可以完成以上连个任务了
3.下面是具体的过程
//首先看一下我们的函数char SD_Init(void); //初始化函数char WriteSectorToMicroSD(long addr,char *buff);//写一个扇区 512bitchar ReadSectorFromMicroSD(long sector,char *buffer);// 读一个扇区
下面是主函数里的的部分
//定义读入缓冲区extern char MicroSDDataBuff[512];void MicroSDTest(){//这是在内存卡初始化以后的测试进行读写如果不成功还是从读写序列号开始吧 //WriteSectorToMicroSD(2,"Hello I here did you find me!!!"); delay_ms(200); ReadSectorFromMicroSD(2,MicroSDDataBuff); //printf("MicroSD read is:%s!!!!",MicroSDDataBuff);}int main(){char arr[100]={0},key=-1;int x=0,y=0;SPI2_Init();uart_init(115200);delay_init();SD_Init();MicroSDTest();printf("Read:%s",MicroSDDataBuff);while(1);}
//下面是MicroSD的初始化及读写函数#define MicroSD_CS_SET GPIO_SetBits(GPIOB,GPIO_Pin_0)#define MicroSD_CS_RESET GPIO_ResetBits(GPIOB,GPIO_Pin_0)char MicroSDDataBuff[512]={0};//一个扇区的大小char SentCommandToMicroSD(char cmd,int data,char crc){char result=0,times=0;MicroSD_CS_SET;//禁止SD卡片选 同步时钟SPI1_ReadWriteByte(0xff); MicroSD_CS_RESET;//开始传输SPI1_ReadWriteByte(cmd);for(times=0;times<4;times++) { SPI1_ReadWriteByte((data>>24)&0xff); data<<=8; } SPI1_ReadWriteByte(crc);SPI1_ReadWriteByte(0xff); //八个时钟 times=0;do{ //读取后8位 result = SPI1_ReadWriteByte(0xFF); times++;}while((result==0xff)&&(times<200));return result;}//初始化化不是很稳定也就是说明传输数据可能不是很稳定char SD_Init(void){char i,temp=0;//char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};int retry=0;GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //PB0GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB0GPIO_SetBits(GPIOB,GPIO_Pin_0);//初始化SPI1SPI1_Init();MicroSD_CS_SET;//发送至少74个时钟信号,数据顺便填写for (i=0;i<0x2f;i++){SPI1_ReadWriteByte(0xff);} //为了能够成功写入CMD0,在这里写200次do { temp=SentCommandToMicroSD(0x40,0,0x95); retry++; if(retry>800){ //超过200次 //CMD0 Error!return(INIT_CMD0_ERROR); printf("Init MicroSD CMD0 Error!!!Back:%d",temp);return 0;} }while(temp!=0x01); //回应01h,停止写入printf("Reset MicroSD successfully!!!times:%d",retry);//发送CMD1到SD卡 retry=0; do{//为了能成功写入CMD1,写100次 temp=SentCommandToMicroSD(0x41,0,0xff);retry++; if(retry>800) { //超过100次printf("Init 1MicroSD CMD1 Error!!!Back:%d",temp);return 0;}}while(temp!=0x00);//回应00h停止写入 MicroSD_CS_SET; //片选无效printf("Init MicroSD sent CMD1 successfully!!!times:%d",retry);//更换更快的SPI速率SPI1_SetSpeed(SPI_BaudRatePrescaler_4);return 0;}char WriteSectorToMicroSD(long addr,char *buff) { int tmp,retry; unsigned int i; addr = addr << 9; //addr = addr * 512 //写命令24到SD卡中去 retry=0; do{ //为了可靠写入,写100次 tmp=SentCommandToMicroSD(0x58,addr,0xff); retry++; if(retry>800) { printf("Write CMD58 Error!!!"); return 1; //send commamd Error! } } while(tmp!=0);//在写之前先产生100个时钟信号 for (i=0;i<100;i++) { SPI1_ReadWriteByte(0xff); } //写入开始字节 SPI1_ReadWriteByte(0xfe); //现在可以写入512个字节 for (i=0;i<512;i++) { SPI1_ReadWriteByte(*buff); buff++; } //CRC-Byte spi模式只需要在前两个命令发送,后面的crc自动不校验 SPI1_ReadWriteByte(0xFF); //Dummy CRC SPI1_ReadWriteByte(0xFF); //CRC Code tmp=SPI1_ReadWriteByte(0xff); // read response if((tmp & 0x1F)!=0x05) // 写入的512个字节是未被接受 { MicroSD_CS_SET; printf("Write data didn't accept by MicroSD"); return 1; //Error! } //等到SD卡不忙为止 //因为数据被接受后,SD卡在向储存阵列中编程数据 while (SPI1_ReadWriteByte(0xff)!=0xff); //禁止SD卡 写入成功 MicroSD_CS_SET; return 0; }char ReadSectorFromMicroSD(long sector,char *buffer) {int retry; //命令16 int times=0;//unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF}; unsigned char temp; //地址变换 由逻辑块地址转为字节地址 sector = sector << 9; //sector = sector * 512//将命令16写入SD卡 retry=0; do{ //为了保证写入命令 一共写100次 temp=SentCommandToMicroSD(0x51,sector,0xff); retry++; if(retry>800) { printf("Read sector from MicroSD is failed!!"); return 1; //block write Error! } } while(temp!=0); //Read Start Byte form MMC/SD-Card (FEh/Start Byte) //Now data is ready,you can read it out. while (SPI1_ReadWriteByte(0xff) != 0xfe); for(times=0;times<512;times++) { MicroSDDataBuff[times]=SPI1_ReadWriteByte(0xff); } //禁止SD卡 读出完成 MicroSD_CS_SET; return 0;}
驱动MicroSD卡如果像我用的stm32f103c8t6的核心板的话,可能还会好一点。网上的资料由一点乱,如果想要具体的keil工程的话留下联系方式我会发给你的。
另外呢后面的工程会用到这里的MicroSD的驱动,然后架设文件系统,所以这里还是关键的,还有一些坑需要深挖。
最后
以上就是傻傻飞鸟为你收集整理的卡spi驱动代码_stm32 SPI读写储存卡(MicroSD TF卡)简述操作分析及实现实现的全部内容,希望文章能够帮你解决卡spi驱动代码_stm32 SPI读写储存卡(MicroSD TF卡)简述操作分析及实现实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复