This section provides sample code for the msp430f5438a SPI Read and write SD card, using the official library msp430_driverlib_2_60_00_02, using IAR for msp430 6.3 by compiling.
This section of the code does not differentiate the SD card, so only the SDHC card is operated, and the program is verified to work properly on the Kingston 8GB SDHC microSD card.
sdhc.h
#ifndef _sdhc_h_ #define _SDHC_H_ #define SDHC_INIT_CLK 125000 #define SDHC_HIGH_CLK 3125000 #define Sdhc_cs_port gpio_p ORT_P9 #define Sdhc_cs_pin gpio_pin0 #define CMD0 0 */go_idle_state/#define CMD55//app_cmd * * #def INE ACMD41 */Send_op_cond (ACMD) */#define CMD1 1/* Send_op_cond * #define CMD17//READ_SINGLE_BL Ock */#define CMD8 8 */send_if_cond */#define CMD18//read_multiple_block/#define CMD12//S Top_transmission */#define CMD24//Write_block */#define CMD25//Write_multiple_block */#define CMD */* Send_status/#define CMD9 9 */SEND_CSD */#define CMD10 */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 <=) {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 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 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 >=) {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 <=) {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_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; }