/***************************************************************************
*Copyright 2013, 产品开发部
*All rights reserved
*
*文件名称:SD.c
*摘 要:SD卡读写函数
*
*当前版本:1.0
*作 者:Felix Zhang
*完成日期:2010年11月23日
*
*取代版本:
*原 作 者:
*完成日期:
****************************************************************************/
#include <msp430f5438.h>
#include "HAL_5438.h"
#include "SD.h"
#include "define.h"
Uint8 temp;
Uint8 SD_Type;
/***************************************************************************
*函数名称 :SD_WriteByte(Uint8 Value)
*创建时间 :2011.02.09
*创建人 :Felix Zhang
*函数功能 :读Si4432的配置寄存器
使用USCI_B2,SPI方式
P9.0 CSn
P9.1 MOSI
P9.2 MISO
P9.3 SCLK
*输入参数 :Value写入的值
*输出参数 :无
*返回信息 :无
*修改日期 :
*修改人 :
*修改内容 :
***************************************************************************/
Uint8 SD_ReadWriteByte(Uint8 Value)
{
while (!(UCB2IFG & UCTXIFG)); // Wait for USCI_B2 TX buffer ready
UCB2TXBUF = Value; // Send the header byte
while (!(UCB2IFG & UCTXIFG));
while(!(UCB2IFG & UCRXIFG)); // Wait for USCI_B2 RX buffer ready
UCB2IFG &= ~UCRXIFG;
temp = UCB2RXBUF;
return temp;
}
/***************************************************************************
*函数名称 :SD_ReadByte(Uint8 Value)
*创建时间 :2011.02.09
*创建人 :Felix Zhang
*函数功能 :读Si4432的配置寄存器
使用USCI_B2,SPI方式
P9.0 CSn
P9.1 MOSI
P9.2 MISO
P9.3 SCLK
*输入参数 :读出temp的值
*输出参数 :无
*返回信息 :temp
*修改日期 :
*修改人 :
*修改内容 :
***************************************************************************/
Uint8 SD_ReadByte(void)
{
while (!(UCB2IFG & UCTXIFG)); // Wait for USCI_B2 TX buffer ready
UCB2TXBUF = 0xFF; // Send the header byte
while (!(UCB2IFG & UCTXIFG));
while(!(UCB2IFG & UCRXIFG)); // Wait for USCI_B2 RX buffer ready
UCB2IFG &= ~UCRXIFG;
temp = UCB2RXBUF;
return temp;
}
/***************************************************************************
*函数名称 :SD_WriteCmd(Uint8 *pcmd)
*创建时间 :2013.07.03
*创建人 :Alize wu
*函数功能 :写SD的配置寄存器
使用USCI_B1,SPI方式
P9.0 CSn
P9.1 MOSI
P9.2 MISO
P9.3 SCLK
*输入参数 :*pcmd SD卡的命令6个字节,pcmd是指向,命令字节的序列的指针
*输出参数 :无
*返回信息 :命令写入后,SD卡的回应值,调用不成功,将返回0xff
*修改日期 :
*修改人 :
*修改内容 :
***************************************************************************/
Uint8 SD_WriteCmd(Uint8 *pcmd)
{
Uint8 i, time=0;
for(i=0;i<6;i++)
{
SD_ReadWriteByte(pcmd[i]);
_NOP( );
}
do
{
temp = SD_ReadWriteByte(0xFF);
time++;
}while((temp == 0xFF)&& (time<100));
return temp;
}
/***************************************************************************
*函数名称 :SD_Reset( )
*创建时间 :2013.07.03
*创建人 :Alize wu
*函数功能 :SD的软件复位,进入SPI模式,使用CMD0命令
*输入参数 :无
*输出参数 :无
*返回信息 :调用成功返回0x00,否则返回cmd1_error
*修改日期 :
*修改人 :
*修改内容 :
***************************************************************************/
Uint8 SD_Reset(void)
{
Uint16 i,time=0;
Uint8 pcmd[] = {0x40,0x00,0x00,0x00,0x00,0x95}; //CMD0
P9OUT |= BIT0; //关闭片选
for(i=0;i<0x0f;i++) //复位时发送至少74时钟
{
SD_ReadWriteByte(0xff); //提高兼容性,如果没有这里,有些SD卡不支持
}
P9OUT &= ~BIT0; //打开片选
do
{
temp = SD_WriteCmd(pcmd);
time++;
if(time==200)
return (cmd0_error);//复位失败
}while(temp !=0x01);//判断SD卡回应是否正确,进入idle
P9OUT |= BIT0; //关闭片选
SD_ReadWriteByte(0xff); //补偿8时钟
return 0;
}
/***************************************************************************
*函数名称 :SD_Init( )
*创建时间 :2013.07.03
*创建人 :Alize wu
*函数功能 :SD的初始化
*输入参数 :无
*输出参数 :无
*返回信息 :调用成功返回0x00,否则返回cmd1_error
*修改日期 :
*修改人 :
*修改内容 :
***************************************************************************/
Uint8 SD_Init(void)
{
Uint8 time=0;
temp = 0;
Uint8 Rev_Data[4]={0};
Uint8 pcmd8[] = {0x48,0x00,0x00,0x01,0xAA,0x87}; //CMD8
Uint8 pcmd55[] = {0x77,0x00,0x00,0x00,0x00,0x00}; //CMD55
Uint8 pcmd41[] = {0x69,0x40,0x00,0x00,0x00,0x00}; //CMD41
Uint8 pcmd58[] = {0x7A,0x00,0x00,0x00,0x00,0x00}; //CMD58
P9OUT &= ~BIT0; //打开片选
temp = SD_WriteCmd(pcmd8); //读取卡片版本
if(temp==0x05)
{
SD_Type =SDV1;
//设置卡类型为SD V1.0,如果是V1.0卡,CM8指令后没有后续数据
P9OUT |= BIT0;
SD_ReadWriteByte(0xff); //多发8时钟
P9OUT &= ~BIT0;
do
{
temp = SD_WriteCmd(pcmd55);
if(temp!=0x01) return temp;
temp = SD_WriteCmd(pcmd41);
time++;
}while((temp!= 0x00)&& (time<200));
P9OUT |= BIT0;
}// if(temp==0x05)
else if(temp == 0x01)
{
//V2.0卡,CM8命令后会传回4字节的数据,要跳过再结束本命令
Rev_Data[0] = SD_ReadWriteByte(0xff); //返回0x00
Rev_Data[1] = SD_ReadWriteByte(0xff); //返回0x00
Rev_Data[2] = SD_ReadWriteByte(0xff); //返回0x01
Rev_Data[3] = SD_ReadWriteByte(0xff); //返回0xAA
P9OUT |= BIT0;
SD_ReadWriteByte(0xff); //多发8时钟
P9OUT &= ~BIT0;
do
{
temp = SD_WriteCmd(pcmd55);
if(temp!=0x01) return temp;
temp = SD_WriteCmd(pcmd41);
time++;
if(time>250) return temp;
}while(temp!= 0x00);
//初始化指令发送完成,接下来获取OCR信息
/*------鉴别SD2.0卡版本--------------*/
temp=SD_WriteCmd(pcmd58);
if(temp != 0x00)return temp;
//读OCR指令发出后,紧接着是4字节的OCR信息
Rev_Data[0] = SD_ReadWriteByte(0xff);
Rev_Data[1] = SD_ReadWriteByte(0xff);
Rev_Data[2] = SD_ReadWriteByte(0xff);
Rev_Data[3] = SD_ReadWriteByte(0xff);
P9OUT |= BIT0;
SD_ReadWriteByte(0xff);
if(Rev_Data[0] & 0x40) SD_Type = SDHC;
else SD_Type =SDV2;
}// else if(temp == 0x01)
UCB2BR0 = 0x01; //SD为高速
UCB2BR1 = 0x00;
return 1;
}
/***************************************************************************
*函数名称 :SD_WriteSector( )
*创建时间 :2013.07.03
*创建人 :Alize wu
*函数功能 :向SD卡的指定地址的扇区写入512字节数据,使用CMD24命令,
*输入参数 :addr 扇区地址
Buffer 指向数据缓冲区的指针
*输出参数 :无
*返回信息 :调用成功返回0x00,否则返回write_block_error
*修改日期 :
*修改人 :
*修改内容 :
***************************************************************************/
Uint8 SD_WriteSector(Uint32 addr,Uint8 *Buffer)
{
Uint16 i,time=0;
temp=0;
Uint8 pcmd[] = {0x58,0x00,0x00,0x00,0x00,0x00}; //CMD24
addr = addr << 9; //addr = addr *512
pcmd[1] = (addr & 0xff000000) >> 24 ;
pcmd[2] = (addr & 0x00ff0000) >> 16 ;
pcmd[3] = (addr & 0x0000ff00) >> 8 ;
pcmd[4] = addr & 0x000000ff;
P9OUT &= ~BIT0;
do
{
temp = SD_WriteCmd(pcmd);
time ++;
if(time==100) return write_block_error;
}while(temp!= 0x00);//判断命令是否写入成功
SD_ReadWriteByte(0xff); //先放3个空数据,等待SD卡准备好
SD_ReadWriteByte(0xff);
SD_ReadWriteByte(0xff);
SD_ReadWriteByte(0xfe); // 写入开始字节0xfe,后面写入512字节数据
for(i=0;i<512;i++) //放一个sector的数据
{
SD_ReadWriteByte(Buffer[i]);
}
SD_ReadWriteByte(0xff); //2字节�
- 1
- 2
前往页