}
//=======================================================================
//Read data from the specified address of the SD card, up to 512 bytes at a time
unsigned char SdReadBlock(unsigned char *Block, unsigned long address,int len)
{
unsigned int count;
int trials=0;
//Block size is 512 bytes exactly
//First Lower SS
// printf("MMC_read_blockn");
SD_CS=0;
//Then send write command
SdCommand(0x11,address,0xff);
if(SdResponse()==0x00)
{
//command was a success - now send data
//start with DATA TOKEN = 0xFE
while(SdRead()!=0xfe);
for(count=0;count for(;count<512;count++) SdRead(); //data block sent - now send checksum SdRead(); SdRead(); //Now read in the DATA RESPONSE token SD_CS=1; SdRead(); return 1; } // printf("Command 0x11 (Read) was not received by the MMC.n"); return 0; } HAL.c 4G and above: CMD0+CMD8+CMD55+CMD41 #include "HAL.H" //============================================================ //Write one byte to the SD card, simulating the SPI bus mode void SdWrite(unsigned char n) { unsigned char i; for(i=8;i;i--) { SD_CLK=0; SD_DI=(n&0x80); n<<=1; SD_CLK=1; } SD_DI=1; } //================================================================ //Read one byte from the SD card, simulating the SPI bus mode unsigned char SdRead() { unsigned char n,i; for(i=8;i;i--) { SD_CLK=0; SD_CLK=1; n<<=1; if(SD_DO) n|=1; } return n; } //================================================================ //Detect the response of SD card unsigned char SdResponse() { unsigned char i=0,response; while(i<=8) { response = SdRead(); if(response==0x00) break; if(response==0x01) break; i++; } return response; } //================================================================ //Send command to SD card void SdCommand(unsigned char command, unsigned long argument, unsigned char CRC) { SdWrite(command|0x40); SdWrite(((unsigned char *)&argument)[0]); SdWrite(((unsigned char *)&argument)[1]); SdWrite(((unsigned char *)&argument)[2]); SdWrite(((unsigned char *)&argument)[3]); SdWrite(CRC); } //================================================================ // Initialize SD card unsigned char SdInit(void) { int delay=0, trials=0; unsigned char i; unsigned char response=0x01; SD_CS=1; for (i=0;i<0x0f;i++) { SdWrite(0xff); } SD_CS=0; //Send Command 0 to put MMC in SPI mode do{ SdCommand(0x00,0,0x95); response=SdResponse(); trials++; if(trials>=200){ return 0xfe; } }while(response!=0x01); USB2.0 trials=0; do{ SdCommand(0x08,0x1AA,0x87); response=SdResponse(); trials++; if(trials>=200){ return 0xfd; } }while(response!=0x01); SD_CS=1; SdWrite(0xff); SD_CS=0; trials =0; do { SdRead();SdRead();SdRead();SdRead(); SdCommand(55, 0, 0); response=SdResponse(); if(response!=0x01) { return 0xfb; } SdCommand(41, 0x40000000, 0); response=SdResponse(); trials++; if(trials>=200){ return 0xf7; } }while(response!=0x00); SD_CS=1; SdWrite(0xff); return 1; } //================================================================ //Write data to the specified address of the SD card, up to 512 bytes at a time unsigned char SdWriteBlock(unsigned char *Block, unsigned long address,int len) { unsigned int count; unsigned char dataResp; //Block size is 512 bytes exactly //First Lower SS SD_CS=0; //Then send write command SdCommand(0x18,address,0xff); if(SdResponse()==0x00) { SdWrite(0xff); SdWrite(0xff); SdWrite(0xff); //command was a success - now send data //start with DATA TOKEN = 0xFE SdWrite(0xfe); //now send data for(count=0;count for(;count<512;count++) SdWrite(0); //data block sent - now send checksum SdWrite(0xff); //Two-byte CRC check, 0XFFFF means CRC is not considered SdWrite(0xff); //Now read in the DATA RESPONSE token dataResp=SdRead(); //Following the DATA RESPONSE token //are a number of BUSY bytes //a zero byte indicates the MMC is busy while(SdRead()==0); dataResp=dataResp&0x0f; //mask the high byte of the DATA RESPONSE token SD_CS=1; SdWrite(0xff); if(dataResp==0x0b) { //P0=0x0b; //printf("DATA WAS NOT ACCEPTED BY CARD -- CRC ERRORn"); return 0; } if(dataResp==0x05){ //P0=0x05; return 1; } //printf("Invalid data Response token.n"); //P0=0x02; return 0; } //P0=0x01; //printf("Command 0x18 (Write) was not received by the MMC.n"); return 0; } //======================================================================= //Read data from the specified address of the SD card, up to 512 bytes at a time unsigned char SdReadBlock(unsigned char *Block, unsigned long address,int len) { unsigned int count; int trials=0; //Block size is 512 bytes exactly //First Lower SS // printf("MMC_read_blockn"); SD_CS=0; //Then send write command SdCommand(0x11,address,0xff); if(SdResponse()==0x00) { //command was a success - now send data //start with DATA TOKEN = 0xFE while(SdRead()!=0xfe); for(count=0;count for(;count<512;count++) SdRead(); //data block sent - now send checksum SdRead(); SdRead(); //Now read in the DATA RESPONSE token SD_CS=1; SdRead(); return 1; } // printf("Command 0x11 (Read) was not received by the MMC.n"); return 0; } main.c Slightly modified to confirm that the data read out is indeed the data written previously. #include #include "HAL.H" char buf[16]; char buf2[16]={0xAA,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0}; //======================================================= //Delay subroutine void delay() { unsigned int i; for(i=0;i<0x8000;i++); } //======================================================= //Main program char code SST516[3] _at_ 0x003b; main() { unsigned char rsp; CLK_DIV=0x03; P0M0=0xff; // 00000000 11111111 high impedance, same as below P0M1=0xff;// P1M0=0xff;// 11111111 11111111 P1M1=0xff;// P2M0=0xff;// 11111111 111111111 P2M1=0xff; //General P3M0=0xff; P3M1=0xff; //TXD push-pull RXD normal 11111111 11111111 P4M0=0xff; P4M1=0xff;//11111111 11111111 P5M0=0xff; P5M1=0xff;// 00000000 00000010 P1M0=0xef;// 11111111 11110001 P1M1=0xe1; // P11 push-pull P12 push-pull P13 push-pull P14 normal /* sbit SD_CS =P1^1; //SD/MMC interface definition qinyg@163.net sbit SD_DI =P1^2; sbit SD_CLK =P1^3; sbit SD_DO =P1^4; */ delay(); //Power-on delay delay(); delay(); delay(); delay(); //Power-on delay delay(); delay(); delay(); SdInit(); while(1) { rsp=SdInit(); //P0=rsp; if(rsp==1) //Initialize SD card { SdReadBlock(buf2,1024,16); //Read 16 bytes of data from the SD card address 1024 to BUFFER. A maximum of 512 bytes can be read at a time. //buf2[0]+=2; P0 = buf2[0]; //Only use the first byte and send to port P0 buf[0]++; // add 1 delay(); //rewrapBlock(); //delay(); //delay SdWriteBlock(buf,1024,sizeof(buf)); //Write back to SD card } delay(); //Delay } } The test was successful and it was concluded that all cards support 2.0. Among them, 1G cards are most likely SD SC cards, the type of 2G cards is still uncertain, and 4G and above are SD HC cards. Unfortunately, there is another class 6 4G card that can't read or write data even though it initializes correctly (the one that succeeded is class 4). Trying different read and write speeds didn't help. I'll leave it for later. Unlike 51 which must use IO port to simulate timing, STC15 has its own SPI mechanism. So next I plan to use the SPI function of the chip to rewrite the read and write logic, and learn to use znFTP or CH375/376 to implement file access.
Previous article:STC15W reads RM3100 data via SPI
Next article:Use 51 single chip microcomputer to write timer (minutes, seconds separated version)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- MCU Programming_Interrupt
- Using TI power timing controller in 5G MIMO application
- MCU development full-time/part-time and sales assistant
- G100 acoustic imager is used in many product development and fault diagnosis fields
- The moon rises over the sea, and the world is sharing this moment
- Treatment of cross-partition area and slot in EMC design of power board
- Resistor Accuracy and Temperature Drift
- Multisum circuit simulation has problems
- The use of archiver in DSP
- Dealing with the noise of switching power supply from three aspects