您的位置:首页 > 其它

MSP430 SD卡SPI读写操作(3) —— SD卡读写实现(以MSP430F5438A为例)

2016-06-12 10:32 537 查看
本节提供了MSP430F5438A SPI读写SD卡的示例代码,使用官方函数库msp430_driverlib_2_60_00_02,使用IAR for msp430 6.3通过编译。

本节代码未对SD卡进行区分,因此只针对SDHC卡进行操作,程序在金士顿
8GB SDHC microSD卡经过验证可以正常运行。


sdhc.h

#ifndef _SDHC_H_
#define _SDHC_H_

#define SDHC_INIT_CLK 125000
#define SDHC_HIGH_CLK 3125000
#define SDHC_CS_PORT GPIO_PORT_P9
#define SDHC_CS_PIN  GPIO_PIN0

#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 */

void SDHC_csInit(void);
void SDHC_csEnable(void);
void SDHC_csDisable(void);
void SDHC_spiInit(void);
void SDHC_spiEnable(void);
void SDHC_spiDisable(void);
uint8_t SDHC_writeByte(uint8_t data);
uint8_t SDHC_sendCmd(const uint8_t cmd,uint32_t arg,const uint8_t crc);
bool SDHC_reset(void);
bool SDHC_init(void);
bool SDHC_checkBusy(void);
bool SDHC_readBlock(uint32_t addr,uint8_t *buffer);
bool SDHC_writeBlock(uint32_t addr,uint8_t *buffer);
bool SDHC_readMultiBlock(uint32_t addr,uint8_t block_num,uint8_t *buffer);
bool SDHC_writeMultiBlock(uint32_t addr,uint8_t block_num,uint8_t *buffer);
#endif



sdhc.c

#include "driverlib.h"
#include "sdhc.h"

void SDHC_csInit(void)
{
GPIO_setAsOutputPin(SDHC_CS_PORT,SDHC_CS_PIN);
}

void SDHC_csEnable(void)
{
GPIO_setOutputLowOnPin(SDHC_CS_PORT,SDHC_CS_PIN);
}

void SDHC_csDisable(void)
{
GPIO_setOutputHighOnPin(SDHC_CS_PORT,SDHC_CS_PIN);
SDHC_writeByte(0xFF);
}

void SDHC_spiInit(void)
{
GPIO_setAsPeripheralModuleFunctionInputPin(
GPIO_PORT_P9,
GPIO_PIN1 + GPIO_PIN2 + GPIO_PIN3
);

//Initialize Master
USCI_B_SPI_initMasterParam param = {0};
param.selectClockSource = USCI_B_SPI_CLOCKSOURCE_SMCLK;
param.clockSourceFrequency = UCS_getSMCLK();
param.desiredSpiClock = SDHC_INIT_CLK;
param.msbFirst = USCI_B_SPI_MSB_FIRST;
param.clockPhase = USCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT;
param.clockPolarity = USCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH;
USCI_B_SPI_initMaster(USCI_B2_BASE, ¶m);
}

void SDHC_spiEnable(void)
{
USCI_B_SPI_enable(USCI_B2_BASE);
}

void SDHC_spiDisable(void)
{
USCI_B_SPI_disable(USCI_B2_BASE);
}

uint8_t SDHC_writeByte(uint8_t data)
{
USCI_B_SPI_transmitData(USCI_B2_BASE,data);
while(USCI_B_SPI_isBusy(USCI_B2_BASE));
data = USCI_B_SPI_receiveData(USCI_B2_BASE);
return data;
}

uint8_t SDHC_getResponse(void)
{
uint8_t retrytime = 0;
uint8_t response;

while(retrytime <= 240)
{
response = SDHC_writeByte(0xFF);
if(response == 0x00) break;
if(response == 0x01) break;
if(response == 0xFE) break;
retrytime++;
}
return response;
}

uint8_t SDHC_sendCmd(const uint8_t cmd,uint32_t arg,const uint8_t crc)
{
uint8_t rec;
SDHC_writeByte((cmd & 0x3F) | 0x40);
SDHC_writeByte(arg >> 24);
SDHC_writeByte(arg >> 16);
SDHC_writeByte(arg >> 8);
SDHC_writeByte(arg);
SDHC_writeByte(crc);
rec = SDHC_getResponse();
return rec;
}

bool SDHC_reset(void)
{
uint8_t  i,rec;
SDHC_csDisable(); //PULL HIGH CS

for(i = 0;i < 16;i++)
{
SDHC_writeByte(0xFF);
} //send 128 clocks for normal voltage and sync

SDHC_csEnable(); //PULL LOW CS

rec = SDHC_sendCmd(CMD0,0,0x95);

SDHC_csDisable();

if(rec != 0x01)
{
return false;
}
return true;
}

bool SDHC_init(void)
{
uint8_t rec;
uint16_t retrytime = 0;

SDHC_csEnable();

rec = SDHC_sendCmd(CMD8,0x1AA,0x87);

if(rec != 0x01)
{
//SD card not support ver2.0 or later
SDHC_csDisable();
return false;
}

rec = SDHC_writeByte(0xFF);
rec = SDHC_writeByte(0xFF);
rec = SDHC_writeByte(0xFF);
rec = SDHC_writeByte(0xFF);

if(rec != 0xAA)
{
SDHC_csDisable();
return false;
}
do
{
do
{
rec = SDHC_sendCmd(CMD55,0,0xff);
retrytime++;
}while(rec != 0x01 && retrytime < 200);
if(retrytime >= 200)
{
SDHC_csDisable();
return false;
}
rec = SDHC_sendCmd(ACMD41,0x40000000,0xFF);
retrytime++;
}while(rec != 0x00 && retrytime < 200);
if(retrytime >= 200)
{
SDHC_csDisable();
return false;
}
SDHC_csDisable();
//SPI HIGH SPEED
USCI_B_SPI_changeMasterClockParam clockparam = {0};
clockparam.clockSourceFrequency = UCS_getSMCLK();
clockparam.desiredSpiClock = SDHC_HIGH_CLK;
USCI_B_SPI_changeMasterClock(USCI_B2_BASE, &clockparam);
return true;
}

bool SDHC_checkBusy(void)
{
uint16_t i = 0,response;
bool rvalue = false;
while(i <= 240)
{
response = SDHC_writeByte(0xFF);
response = response & 0x1F;
if(response == 0x05) {rvalue = true; break;}
i++;
}
i = 0;
do
{
response = SDHC_writeByte(0xFF);
i++;
if(i >= 65000)
{
rvalue = false;
break;
}
}while(response == 0x00);
return rvalue;
}

bool SDHC_readBlock(uint32_t addr,uint8_t *buffer)
{
uint8_t rec;
uint16_t i;
SDHC_csEnable();

rec = SDHC_sendCmd(CMD17,addr,0x55);
if(rec != 0x00)
{
SDHC_csDisable();
return false;
}

rec = SDHC_getResponse();
if(rec != 0xFE)
{
SDHC_csDisable();
return false;
}

for(i = 0; i < 512;i++)
{
*buffer ++ = SDHC_writeByte(0xFF);
}
SDHC_writeByte(0xFF);
SDHC_writeByte(0xFF);

SDHC_csDisable();
return true;
}

bool SDHC_writeBlock(uint32_t addr,uint8_t *buffer)
{
uint8_t rec;
uint16_t i;
bool rvalue = true;
SDHC_csEnable();

rec = SDHC_sendCmd(CMD24,addr,0xFF);
if(rec != 0x00)
{
SDHC_csDisable();
return false;
}

SDHC_writeByte(0xFE);
for(i = 0; i < 512;i++)
{
SDHC_writeByte(*buffer ++);
}
SDHC_writeByte(0xFF);
SDHC_writeByte(0xFF);

rvalue = SDHC_checkBusy();
SDHC_csDisable();
return rvalue;
}

bool SDHC_readMultiBlock(uint32_t addr,uint8_t block_num,uint8_t *buffer)
{
uint8_t rec;
uint16_t i;
SDHC_csEnable();

rec = SDHC_sendCmd(CMD18,addr,0xFF);
if(rec != 0x00)
{
SDHC_csDisable();
return false;
}

do
{
rec = SDHC_getResponse();
if(rec != 0xFE)
{
SDHC_csDisable();
return false;
}

for(i = 0; i < 512;i++)
{
*buffer ++ = SDHC_writeByte(0xFF);
}
SDHC_writeByte(0xFF);
SDHC_writeByte(0xFF);
}while(-- block_
4000
num);

rec = SDHC_sendCmd(CMD12,0,0xFF);
SDHC_csDisable();
return true;
}

bool SDHC_writeMultiBlock(uint32_t addr,uint8_t block_num,uint8_t *buffer)
{
uint8_t rec;
uint16_t i;
bool rvalue = true;
SDHC_csEnable();

rec = SDHC_sendCmd(CMD25,addr,0xFF);
if(rec != 0x00)
{
SDHC_csDisable();
return false;
}

do
{
SDHC_writeByte(0xFC);
for(i = 0; i < 512;i++)
{
SDHC_writeByte(*buffer ++);
}
SDHC_writeByte(0xFF);
SDHC_writeByte(0xFF);

rvalue = SDHC_checkBusy();
if(!rvalue) break;
}while(-- block_num);

rec = SDHC_sendCmd(0xFD,0,0xFF);
i = 0;
do
{
rec = SDHC_writeByte(0xFF);
i++;
if(i >= 65000)
{
rvalue = false;
break;
}
}while(rec == 0x00);
SDHC_csDisable();
return rvalue;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  msp430 spi sd卡读写