u8 r1;u16 i=0;
r1=SD_SendCommand(CMD17,address<<9,0);//发送读扇区命令 if(r1)return r1; //应答不正确,直接返回
SD_CS=0;//选中SD卡
if(SD_GetResponse(0xFE))//等待SD卡发回数据起始令牌0xFE
{
SD_CS=1; //关闭SD卡
return 1;//读取失败
}
for(i=0;i for(;i for(;i<512;i++) SPIx_ReadWriteByte(0xff); SPIx_ReadWriteByte(0xff);//发送伪CRC码 SPIx_ReadWriteByte(0xff); //读出剩余字节 SD_CS=1;//关闭SD卡 return 0; } 此部分代码我们在本节主要用到的就是 SD 卡初始化函数 SD_Init 和 SD 卡读取函数 SD_ReadSingleBlock,通过前面的介绍,相信大家不难理解,这里我们就不多说了,接下来 保存 MMC_SD.C文件,并加入到 HARDWARE 组下,然后打开MMC_SD.H,在该文件里 面输入如下代码: #ifndef _MMC_SD_H_ #define _MMC_SD_H_ #include //正点原子@ALIENTEK //2010/6/13 //SD传输数据结束后是否释放总线宏定义 #define NO_RELEASE 0 #define RELEASE 1 // SD卡类型定义 #define SD_TYPE_MMC 0 #define SD_TYPE_V1 1 #define SD_TYPE_V2 2 #define SD_TYPE_V2HC 4 // SD卡指令表 #define CMD0 0 //卡复位 #define CMD1 1 #define CMD9 9 //命令9 ,读CSD数据 #define CMD10 10 //命令10,读CID数据 #define CMD12 12 //命令12,停止数据传输 315 #define CMD16 16 //命令16,设置SectorSize 应返回0x00 #define CMD17 17 //命令17,读sector #define CMD18 18 //命令18,读Multi sector #define ACMD23 23 //命令23,设置多sector写入前预先擦除N个block #define CMD24 24 //命令24,写sector #define CMD25 25 //命令25,写Multi sector #define ACMD41 41 //命令41,应返回0x00 #define CMD55 55 //命令55,应返回0x01 #define CMD58 58 //命令58,读OCR信息 #define CMD59 59 //命令59,使能/禁止CRC,应返回0x00 //数据写入回应字意义 #define MSD_DATA_OK 0x05 #define MSD_DATA_CRC_ERROR 0x0B #define MSD_DATA_WRITE_ERROR 0x0D #define MSD_DATA_OTHER_ERROR 0xFF //SD卡回应标记字 #define MSD_RESPONSE_NO_ERROR 0x00 #define MSD_IN_IDLE_STATE 0x01 #define MSD_ERASE_RESET 0x02 #define MSD_ILLEGAL_COMMAND 0x04 #define MSD_COM_CRC_ERROR 0x08 #define MSD_ERASE_SEQUENCE_ERROR 0x10 #define MSD_ADDRESS_ERROR 0x20 #define MSD_PARAMETER_ERROR 0x40 #define MSD_RESPONSE_FAILURE 0xFF //这部分应根据具体的连线来修改! //Mini STM32使用的是PA3作为SD卡的CS脚. #define SD_CS PAout(3) //SD卡片选引脚 extern u8 SD_Type;//SD卡的类型 //函数申明区 u8 SD_WaitReady(void); //等待SD卡就绪 u8 SD_SendCommand(u8 cmd, u32 arg, u8 crc); //SD卡发送一个命令 u8 SD_SendCommand_NoDeassert(u8 cmd, u32 arg, u8 crc); u8 SD_Init(void); //SD卡初始化 u8 SD_Idle_Sta(void); //设置SD卡到挂起模式 u8 SD_ReceiveData(u8 *data, u16 len, u8 release);//SD卡读数据 u8 SD_GetCID(u8 *cid_data); //读SD卡CID u8 SD_GetCSD(u8 *csd_data); //读SD卡CSD u32 SD_GetCapacity(void); //取SD卡容量 //USB 读卡器 SD卡操作函数 u8 MSD_WriteBuffer(u8* pBuffer, u32 WriteAddr, u32 NumByteToWrite); u8 MSD_ReadBuffer(u8* pBuffer, u32 ReadAddr, u32 NumByteToRead); 316 u8 SD_ReadSingleBlock(u32 sector, u8 *buffer); //读一个sector u8 SD_WriteSingleBlock(u32 sector, const u8 *buffer); //写一个sector u8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count); //读多个sector u8 SD_WriteMultiBlock(u32 sector, const u8 *data, u8 count);//写多个sector u8 SD_Read_Bytes(unsigned long address,unsigned char *buf,unsigned int offset,unsigned int bytes);//读取一byte #endif 该部分代码主要是一些命令的宏定义以及函数声明,在这里我们设定了SD卡的CS管 脚为PA3。保存MMC_SD.H,就可以在主函数里面编写我们的应用代码了,打开 test.c文件, 在该文件中修改 main 函数如下: u8 buf[512];//SD 卡数据缓存区 int main(void) { u32 sd_size; u8 t=0; Stm32_Clock_Init(9);//系统时钟设置 delay_init(72); //延时初始化 uart_init(72,9600); //串口 1 初始化 LCD_Init(); //初始化液晶 LED_Init(); //LED 初始化 POINT_COLOR=RED;//设置字体为红色 LCD_ShowString(60,50,\ LCD_ShowString(60,70,\ LCD_ShowString(60,90,\ LCD_ShowString(60,110,\ while(SD_Init()!=0)//检测不到 SD 卡 { LCD_ShowString(60,130,\ delay_ms(500); LCD_ShowString(60,130,\ \ delay_ms(500); LED0=!LED0;//DS0 闪烁 } //检测 SD 卡成功 LCD_ShowString(60,130,\ LCD_ShowString(60,150,\ Mb\ sd_size=SD_GetCapacity(); LCD_ShowNum(164,150,sd_size>>20,4,16);//显示 SD 卡容量 while(1) { if(t==30)//每 6s 钟执行一次 { 317 if(SD_ReadSingleBlock(0,buf)==0)//读取MBR扇区 { LCD_ShowString(60,170,\ printf(\ for(sd_size=0;sd_size<512;sd_size++)//打印MBR扇区数据 { printf(\ } printf(\ LCD_ShowString(60,170,\ } t=0; } t++; delay_ms(200); LED0=!LED0; } } 这里我们通过SD_GetCapacity函数来得到 SD卡的容量,然后在液晶上显示出来,接着 我们读取SD卡的扇区0,然后把这部分数据通过串口打印出来。每6s钟执行一次。至此, 我们的软件设计就结束了。 3.20.4 下载与测试 在代码编译成功之后,我们通过下载代码到ALIENTEK MiniSTM32开发板上,可以看 到LCD 显示如下内容(默认SD 卡已经接上了): 图3.19.4.1 SD 卡实验LCD显示内容 此时我们打开串口调试助手,就可以看到从开发板发回来的数据了,如下图示: 318
相关推荐: