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卡经过验证可以正常运行。
本节代码未对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中adc12与PWM配合使用
- 基于LaunchPad的Nokia5110显示
- msp430 按键 中断 轮询
- msp430 timerA interrupt
- MSP430 AD 单通道单次转换
- i/O 中断
- MSP430F149学习笔记——时钟
- MSP430F149学习笔记——时钟
- MSP430移植μCOS-II系统之时间管理函数OSTimeDlyHMSM()延时不准确解析
- 对于MSP430与SIM900A无法通信的问题解决
- MSP430仿真器降级失败的解决办法
- msp430学习笔记之时钟
- msp430学习笔记之uart
- msp430学习笔记之中断处理函数
- msp430单片机实现常按键和短按键加去抖功能
- msp430f5310定时器的认识
- 关于软件I2C与MSP430通信的问题
- MSP430 Launchpad MSP430g2452 SHT10 温湿度传感器
- 手把手教你使用TI MSP430 LaunchPad
- [MSP430] 1.第一个工程