微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > STC52单片机的SD卡底层驱动——SPI

STC52单片机的SD卡底层驱动——SPI

时间:11-22 来源:互联网 点击:

最近在做SD卡以及单片机上的FAT32文件系统,这个是我参考别人的源程序以后写出来的自己的SD卡驱动,如有不完整的地方,还望大家不吝指教。

定义声明:

#ifndef _SD_H_
#define _SD_H_

#include

sbit SD_CS=P2^7; //SD卡片选信号
sbit SD_SI=P2^6; //SD卡数据输入
sbit SD_SCL=P2^5; //SD卡时钟信号
sbit SD_SO=P2^4; //SD卡数据输出

#define DELAY_TIME 100 //SD卡的复位与初始化时SPI延时
#define TRY_TIME 200 //SD卡写入命令以后,读取SD卡的回应次数

#define INIT_CMD0_ERROR 0x01 //CMD0错误
#define INIT_CMD1_ERROR 0x02//CMD1错误
#define WRITE_BLOCK_ERROR 0x03//写块错误
#define READ_BLOCK_ERROR 0x04//读块错误

unsigned char SD_Reset();
unsigned char SD_Init();
unsigned char SD_Write_Sector(unsigned long addr,unsigned char *buffer);
unsigned char SD_Read_Sector(unsigned long addr,unsigned char *buffer);

#endif

代码实现:

#include"SD.h"
#include"myfun.h"

unsigned char Is_init;

unsigned char bdata _dat;
sbit _dat7 = _dat^7;
sbit _dat6 = _dat^6;
sbit _dat5 = _dat^5;
sbit _dat4 = _dat^4;
sbit _dat3 = _dat^3;
sbit _dat2 = _dat^2;
sbit _dat1 = _dat^1;
sbit _dat0 = _dat^0;

void SD_spi_write(unsigned char x)
{
_dat=x;

SD_SI = _dat7;
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL=1;
if(Is_init) Delay20us(DELAY_TIME);

SD_SI = _dat6;
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL=1;
if(Is_init) Delay20us(DELAY_TIME);

SD_SI = _dat5;
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL=1;
if(Is_init) Delay20us(DELAY_TIME);

SD_SI = _dat4;
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL=1;
if(Is_init) Delay20us(DELAY_TIME);

SD_SI = _dat3;
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL=1;
if(Is_init) Delay20us(DELAY_TIME);

SD_SI = _dat2;
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL=1;
if(Is_init) Delay20us(DELAY_TIME);

SD_SI = _dat1;
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL=1;
if(Is_init) Delay20us(DELAY_TIME);

SD_SI = _dat0;
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL=1;
if(Is_init) Delay20us(DELAY_TIME);

}

unsigned char SD_spi_read()
{
SD_SO = 1;

SD_SCL = 1;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
_dat7 = SD_SO;

SD_SCL = 1;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
_dat6 = SD_SO;

SD_SCL = 1;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
_dat5 = SD_SO;

SD_SCL = 1;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
_dat4 = SD_SO;

SD_SCL = 1;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
_dat3 = SD_SO;

SD_SCL = 1;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
_dat2 = SD_SO;

SD_SCL = 1;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
_dat1 = SD_SO;

SD_SCL = 1;
if(Is_init) Delay20us(DELAY_TIME);
SD_SCL = 0;
if(Is_init) Delay20us(DELAY_TIME);
_dat0 = SD_SO;

return(_dat);
}

unsigned char SD_Write_Cmd(unsigned char *pcmd)
{
unsigned char temp,time=0;

SD_CS=1;
SD_spi_write(0xff); //提高程序的兼容性
SD_CS=0;

SD_spi_write(pcmd[0]);
SD_spi_write(pcmd[1]);
SD_spi_write(pcmd[2]);
SD_spi_write(pcmd[3]);
SD_spi_write(pcmd[4]);
SD_spi_write(pcmd[5]);
do
{
temp = SD_spi_read();
time++;
}
while((temp==0xff)&&(timereturn(temp);
}

unsigned char SD_Reset()
{
unsigned char time,temp,i;
unsigned char pcmd[] = {0x40,0x00,0x00,0x00,0x00,0x95};

Is_init = 1;

SD_CS = 1; //关闭片选
for(i=0;i<0x0f;i++){
SD_spi_write(0xff); //补充120个时钟,唤醒SPI
}
SD_CS = 0; //打开片选
time=0;
do{
temp=SD_Write_Cmd(pcmd);//写入CMD0
time++;
if(time==TRY_TIME){
SD_CS = 1; //关闭片选
return(INIT_CMD0_ERROR); //CMD0 写入失败
}
}while(temp!=0x01);

SD_CS = 1; //关闭片选

SD_spi_write(0xff);//补充8个时钟,提高兼容性

return 0 ; //返回0,复位操作成功
}

unsigned char SD_Init()
{
unsigned char time,temp;
unsigned char pcmd[] = {0x41,0x00,0x00,0x00,0x00,0xff};
SD_CS = 0; //打开片选

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top