1, Environment introduction
Trolley main control MCU: STM32F103ZET6
STM32 program development IDE: keil5
STM32 program style: developed in register mode, complete annotations, high execution efficiency and convenient transplantation
The hardware includes: a STM32F103ZET6 system board, a 2.8-inch TFT resistance touch screen, an SD card slot (SPI interface), and an SD card (storing word library and novel files)
Project complete source code download address: https://download.csdn.net/download/xiaolong1126626497/19628524
2, Function introduction
This is a novel reader designed based on ST32F103ZET6. Although there is still a lot of difference in practicability and function for real novel reader products, the technology designed here is the most valuable for STM32 and MCU development engineers who have just started.
Therefore, the novel reader of this article is mainly used as an introductory training project for embedded MCU engineers, curriculum design for college students, etc. The purpose is not to use the novel reader, but to take the novel reader as an example to learn relevant technologies: SD card, serial communication, SPI communication, 8080 timing, touch screen calibration principle, use of FATFS file system, use of voice broadcast module, etc.
The reader supports the basic functions of a conventional novel Reader:
1. It supports selecting the specified novel for viewing and reading, which can be switched through the button on the touch screen.
2. Support switching font size
3. Support switching font color and background color
4. The title bar displays the name of the novel file viewed by the current reader
5. Support page turning, previous page and next page
6. It supports automatic voice reading, and its voice is close to that of normal real people. It is very powerful.
There are two voice schemes: (1) Yu Yin syn6658 (2) IFLYTEK SYN5152. These two chips communicate through serial port, and the programming is very simple.
Introduction to internal programming ideas:
The font of the novel reader is stored on the SD card. The SD card uses the card slot of SPI interface to connect with STM32. STM32 cooperates with FATFS file system to operate the files on the SD card; In order to improve the access efficiency, the font file on the SD card will be copied to the on-board W25Q64 chip at the first power on. The novel file is still stored on the SD card. Each time the page is turned, the text file is obtained from the SD card and rendered to the LCD display.
The display screen is a 2.8-inch resistive touch screen, the driving chip is ILI9341 (compatible: 93259328), and the LCD pin wiring is compatible with the 2.8-inch LCD display screen of punctual atom; The driving chip of the resistance screen is XPT2046, which is a very common combination. This XPT2046 is an ADC chip. Finally, to complete the coordinate point positioning on the touch screen, you need to write your own calibration algorithm for conversion. ILI9341 driver chip supports 8080 timing operation, which can be driven by IO analog mode or STM32 FSMC interface. STM32 enhanced version supports FSMC function. Other chips without FSMC interface can be driven by analog 8080 timing. The effect is the same, but the efficiency is poor, and high-speed screen brushing cannot be realized. As long as high-speed screen brushing is not carried out, there is no problem in making do with it.




3, Introduction to the hardware used (all bought on Taobao)
3.1 STM32F103ZET6 minimum system board
This is the hardware details bought on Taobao. You can use either development board or LCD. The programming ideas are the same.


The onboard resources of the development board are as follows: CPU: STM32F103ZET6,LQFP144,FLASH: 512K,SRAM: 64K; Extended SPI FLASH: W25Q32, 8M bytes; 1 power indicator; 2 status indicators; An EEPROM chip, 24C02, with a capacity of 256 bytes (Note: the labels of different places of origin are different, but they are all 24C02 chips, which are correct after testing) 1 photosensitive sensor; 1 wireless module interface, which can be connected to NRF24L01/RFID/CC01 module; 1 channel CAN interface, using TJA1050 chip; 1 channel 485 interface, using SP485 chip; 1 standard 2.4/2.8/3.5/4.3/7 inch LCD interface, supporting touch screen; A USB serial port, which can be used for program download and code debugging (USMART debugging); 1 USB SLAVE interface for USB communication; 1 reset button; 2 independent keys; 1 SD card holder for connecting SD card; 1 RTC backup battery base; 1 standard JTAG/SWD simulation download and debugging interface; 1 circuit from 5V to 3.3V; All 144 pins of the chip are led out to facilitate external expansion experiment; 1 power switch to switch USB power supply;
3.2 SD card slot

3.3 SYN6658 speech synthesis chip

Functional features: • the chip supports the synthesis of any Chinese text, and can adopt four coding methods: GB2312, GBK, BIG5 and Unicode; • the chip has the function of text intelligent analysis and processing, which can analyze the text in common formats such as numerical value, telephone number, time and date, scale symbol, etc; • the chip can automatically analyze the text, identify the pronunciation of polyphonic words in the text and synthesize the correct pronunciation; • the chip can realize 10 levels of digital volume control, making the volume larger and wider; • 77 sound prompts and 14 chord music are integrated in the chip; • provide 6 Chinese speakers, including two men, two women, one effector and one girl voice; • support a variety of text control tags to improve the accuracy of text processing; • support a variety of control commands, including: synthesis, stop, pause synthesis, continue synthesis, change baud rate, etc; • support multiple ways to query the working status of the chip; • two communication modes: the chip supports UART and SPI; • the chip supports Power Down mode. The chip can enter the Power Down mode by using the control command; • communication baud rate supported by the chip: 4800bps, 9600bps, 57600bps, 115200bps; • all indicators of the chip meet the application in outdoor harsh environment;
Application scope: • on board information terminal voice broadcasting, on-board dispatching and on-board navigation • parking charge system / guidance system • bus stop announcer and attendance machine • mobile phones, landlines • queuing machine, cashier and toll machine • vending machines, information machines, POS machines • intelligent instruments, weather warning machines, intelligent transformers • smart toys, smart watches • electric bicycle • voice e-book, color screen story book, voice electronic dictionary, voice electronic tour guide • short message broadcast, news broadcast • electronic maps
4, Operating instructions
4.1 program download
The development board supports Jlink download and serial port download.

4.2 screen operation instructions
Currently implemented functions: 1. Novel page turning: it supports clicking the touch screen button to turn the next page 2. Change the novel: click the touch screen button "next" to switch the novel. 3. Change color: click the touch screen button "color adjustment" to switch colors, and 12 font colors are supported. 4. Change font: click the touch screen button "font adjustment" to switch fonts. At present, two fonts (16x16 24x24) are supported.
Idea Description: FATFS file system is transplanted in the program. Font files and novel files are stored on the SD card. The novel files in the SD card are read and displayed through the file system.
During the operation, the serial port debugging assistant will also synchronize the output information.

4.3 calibration instructions
The first time you use it, you need to calibrate the screen, otherwise the touch screen will not respond.
If the screen is not sensitive, it can be forced to calibrate. Press the key K2 and then press the reset key to force calibration.

Click the four red circles on the screen in turn.

4.4 documents stored on SD card
There are two directories on the SD card: font directory and txt directory.
Font Directory: store font library files. There are two font libraries.
txt Directory: store novel files, built-in 3 novels.


5, Core code
The code is written in Keil5, which can be downloaded, compiled, tested and learned.
Project complete source code download address: https://download.csdn.net/download/xiaolong1126626497/19628524

5.1 main.c main function code
#include "stm32f10x.h" #include "delay.h" #include "sys.h" #include "usart.h" #include <string.h> #include <stdio.h> #include "iic.h" #include "at24c08.h" #include "w25q64.h" #include "nt35310_lcd.h" #include "xpt2046.h" #include "sdcard.h" #Include "FF. H" / / header file of FatFs file system //Update font --- read font from SD card to W25Q64 void FontUpdate_to_W25Q64(); FATFS fatfs; //File system registration workspace required u16 select_color[]={WHITE,BLACK,BLUE,RED,YELLOW,BROWN,BRRED,GRAY,DARKBLUE,LIGHTBLUE,GRAYBLUE,LIGHTGREEN}; u8 read_text_buf[4096+1]; int main() { u32 x;u32 y;u32 size=16;u8 *p; u8 color_select_cnt=0; //12 FIL text_file; u16 br=0; u8 r_data=10; u32 read_cnt=0; DIR dir; FRESULT res; FILINFO fno; //Store read file information char *abs_path=NULL; char path[]="0:/txt"; u32 cnt=0; USART_X_Init(USART1,72,115200); NT35310_LcdInit(); NT35310_Clear(WHITE); IIC_Init(); //IIC bus initialization W25Q64_Init(); //Initialize W25Q64 TOUCH_Init(); //Touch screen initialization TOUCH_CheckXY(); //Touch screen calibration procedure RCC->APB2ENR|=1<<5; GPIOD->CRH&=0xFF0FFFFF; GPIOD->CRH|=0x00300000; while(SDCardDeviceInit()!=0) { printf("SDCard_DeviceInit error.\r\n"); PDout(13)=!PDout(13); delay_ms(100); } f_mount(&fatfs,"0:",0); //Workspace for registering file systems //Design interface LCD_color_1=RED; LCD_color_2=LIGHTBLUE; NT35310_DisplayString(16,0,16,"be based on STM32 Novel reader design based on"); NT35310_DrawLine(0,16,239,16,DARKBLUE); //Draw keys NT35310_DrawRectangle(0,319-80,239,319,RED); NT35310_DrawLine(0,319-40,239,319-40,DARKBLUE); NT35310_DrawLine(239/2,319-80,239/2,319,DARKBLUE); LCD_color_2=WHITE; NT35310_DisplayString(32,319-70,16,"next page"); NT35310_DisplayString(239/2+32,319-70,16,"Next book"); NT35310_DisplayString(32,319-30,16,"Font adjustment"); NT35310_DisplayString(239/2+32,319-30,16,"Color adjustment"); /*1. Open Directory*/ res=f_opendir(&dir,path); if(res!=FR_OK)return res; res=f_readdir(&dir,&fno); printf("File name: %s,file size: %ld byte\r\n",fno.fname,fno.fsize); LCD_color_1=BLACK; NT35310_DisplayString(0,17,16,fno.fname); if(abs_path) { free(abs_path); abs_path=NULL; } //Length of the name of the file to be stored abs_path=malloc(strlen(path)+strlen(fno.fname)+1); strcpy(abs_path,path); strcat(abs_path,"/"); strcat(abs_path,fno.fname); printf("abs_path=%s\n",abs_path); NT35310_DisplayString(0,17+16,16,"Volume 1\ For the first time, Zhen Shiyin dreamily knew the spirit, and Jia Yu was pregnant with a girl in the dust of the village\ This is also the first time to open the book. Author Ziyun: because I had a dream, I hid the truth,\ And borrow the theory of "channeling", write this<<Stone record>>Not a book. So it's called "Zhen Shiyin".\ But what's in the book and who? He said again: "today, I am busy and accomplish nothing. I suddenly miss all the women of that day,\ One by one, after careful examination, I feel that my actions and knowledge are all above me. How can I be a man, sincere not like that skirt hairpin?"); while(1) { if(TOUCH_PEN==0) //Judge whether the touch screen is pressed { //Judge whether the XY coordinate is read if(TOUCH_ReadXY()) { // printf("x=%d,y=%d\r\n",touch_info.x,touch_info.y); //Judgment range if((touch_info.x>=0 && touch_info.x<=239/2)&& (touch_info.y>=319-80 && touch_info.y<=319-40)) { LCD_color_2=BLUE; //fill color NT35310_Fill(0+1,319-80+1,239/2-1,319-40-1,BLUE); //display string NT35310_DisplayString(32,319-70,16,"next page"); //Wait for the touch screen to release while(TOUCH_PEN==0){} //Fill color - clear screen NT35310_Fill(0,18+16,239,319-80-1,WHITE); LCD_color_2=WHITE; if(read_cnt>=br) { read_cnt=0; } if(read_cnt==0) { if(br!=4096) { res=f_open(&text_file,(const TCHAR*)abs_path,FA_READ);//Open file if(res!=0) { printf("%s File open failed!\r\n",abs_path); return 1; //File open failed } printf("%s File opened successfully!\n",abs_path); } //Execute code res=f_read(&text_file,read_text_buf,4096,(UINT*)&br);//Read 4096 bytes read_text_buf[br]='\0'; printf("br=%d\r\n",br); if(br!=4096) { f_close(&text_file); } } //font size x=0; //Coordinate starting position y=17+16; //Coordinate starting position p=read_text_buf+read_cnt; while(*p!='\0') { if(*p>0x80) //Judge whether it is Chinese - coding rules start from 0X8140 { read_cnt+=2; if(x+size>239) { x=0; //Horizontal sitting return 0 y+=size; //Line feed if(y+size>=319-80-1)break; } NT35310_DisplayGBKData(x,y,size,p);//Show a Chinese x+=size; p+=2; //Offset by two bytes } else if(*p>=' ' && *p<='~') //Common ASCII codes { read_cnt+=1; if(x+size/2>239) { x=0; //Horizontal sitting return 0 y+=size; //Line feed if(y+size>=319-80-1)break; } if(size==16) { //Display English letters NT35310_DisplayData(x,y,size/2,size,(u8*)ASCII_8_16[*p-' ']); } else if(size==24) { //Display English letters NT35310_DisplayData(x,y,size/2,size,(u8*)asc2_2412[*p-' ']); } p+=1; x+=size/2; } else if(*p=='\n') { x=0; y+=size; p+=1; //Offset pointer read_cnt+=1; if(y+size>=319-80-1)break; } else { read_cnt+=1; p+=1; //Offset pointer } } //fill color NT35310_Fill(0+1,319-80+1,239/2-1,319-40-1,WHITE); LCD_color_2=WHITE; //display string NT35310_DisplayString(32,319-70,16,"next page"); } //Judgment range if((touch_info.x>=239/2 && touch_info.x<=239)&& (touch_info.y>=319-80 && touch_info.y<=319-40)) { LCD_color_2=BLUE; //fill color NT35310_Fill(239/2+1,319-80+1,239-1,319-40-1,BLUE); //display string NT35310_DisplayString(239/2+32,319-70,16,"Next book"); //Wait for the touch screen to release while(TOUCH_PEN==0){} LCD_color_2=WHITE; //Close the original file f_close(&text_file); //Trigger new page read_cnt=0; br=0; //Execute code res=f_readdir(&dir,&fno); if(fno.fname[0] == 0 || res!=0) { /*3. Close directory*/ f_closedir(&dir); /*1. Open Directory*/ res=f_opendir(&dir,path); if(res!=FR_OK)return res; res=f_readdir(&dir,&fno); } printf("File name: %s,file size: %ld byte\r\n",fno.fname,fno.fsize); LCD_color_1=BLACK; NT35310_DisplayString(0,17,16,fno.fname); if(abs_path) { free(abs_path); abs_path=NULL; } //Length of the name of the file to be stored abs_path=malloc(strlen(path)+strlen(fno.fname)+1); strcpy(abs_path,path); strcat(abs_path,"/"); strcat(abs_path,fno.fname); printf("abs_path=%s\n",abs_path); //fill color NT35310_Fill(239/2+1,319-80+1,239-1,319-40-1,WHITE); //display string NT35310_DisplayString(239/2+32,319-70,16,"Next book"); } //Judgment range if((touch_info.x>=0 && touch_info.x<=239/2)&& (touch_info.y>=319-40 && touch_info.y<=319)) { LCD_color_2=BLUE; //fill color NT35310_Fill(0+1,319-40+1,239/2-1,319-1,BLUE); //display string NT35310_DisplayString(32,319-30,16,"Font adjustment"); //Wait for the touch screen to release while(TOUCH_PEN==0){} if(size==16)size=24; else size=16; //Execute code //fill color NT35310_Fill(0+1,319-40+1,239/2-1,319-1,WHITE); LCD_color_2=WHITE; //display string NT35310_DisplayString(32,319-30,16,"Font adjustment"); } //Judgment range if((touch_info.x>=239/2 && touch_info.x<=239)&& (touch_info.y>=319-40 && touch_info.y<=319)) { LCD_color_2=BLUE; //fill color NT35310_Fill(239/2+1,319-40+1,239-1,319-1,BLUE); //display string NT35310_DisplayString(239/2+32,319-30,16,"Color adjustment"); //Wait for the touch screen to release while(TOUCH_PEN==0){} //Execute code //Foreground font color Toggle LCD_color_1=select_color[color_select_cnt++]; if(color_select_cnt>=12) { color_select_cnt=0; } //fill color NT35310_Fill(239/2+1,319-40+1,239-1,319-1,WHITE); LCD_color_2=WHITE; //display string NT35310_DisplayString(239/2+32,319-30,16,"Color adjustment"); } } } } } u32 gbk32_32_addr=1024*0; u8 font_buffer[4096]; //Update font --- read font from SD card to W25Q64 void FontUpdate_to_W25Q64() { u32 w_cnt=0; FILINFO fno; FIL fp; UINT br,res; /*1. Open font*/ f_open(&fp,"0:/font/gbk16.DZK",FA_READ); /*2. Cyclic read font updated to W25Q64*/ f_stat("0:/font/gbk16.DZK",&fno); printf("File size:%d\r\n",fno.fsize); while(1) { /*3. Read font file*/ res=f_read(&fp,font_buffer,4096,&br); /*4. Write to W25Q64*/ W25Q64_WriteData(gbk32_32_addr,br,font_buffer); gbk32_32_addr+=br; w_cnt+=br; printf("font16:%.f%%\r\n",(w_cnt*1.0/fno.fsize)*100); /*5. Determine whether the file ends*/ if(res!=FR_OK||br!=4096)break; } /*6. Close font file*/ f_close(&fp); }
5.2 sdcard. C SD card driver code
#include "sdcard.h" static u8 SD_Type=0; //Type of SD card /* Function function: the SD card bottom interface reads and writes a byte to the SD card through SPI timing Function parameter: data is the data to be written Return value: read data Note: timing is the second rising edge to collect data */ u8 SDCardReadWriteOneByte(u8 DataTx) { u8 DataRx; u8 i; for(i=0;i<8;i++) { SDCardSCLK(0); if(DataTx&0x80){SDCardOut(1);} else {SDCardOut(0);} DataTx<<=1; SDCardSCLK(1);//The second rising edge collects data DataRx<<=1; if(SDCardInput)DataRx|=0x01; } return DataRx; } /* Function function: initialization of underlying SD card interface SPI interfaces of this program are as follows: PC11 Film selection SDCardCS PC12 Clock SDCardSCLK PD2 Output SPI_MOSI -- master output slave input PC8 Input SPI_MISO -- master input and slave output */ void SDCardSpiInit(void) { RCC->APB2ENR|=1<<5; //Enable PORTD clock RCC->APB2ENR|=1<<4; //Enable PORTC clock GPIOD->CRL&=0XFFFFF0FF; GPIOD->CRL|=0X00000300; //PD2 GPIOD->ODR|=1<<2; //PD2 GPIOC->CRH&=0XFFF00FF0; GPIOC->CRH|=0X00033008; GPIOC->ODR|=0X3<<11; GPIOC->ODR|=1<<8; SDCardCS(1); } /* Function function: deselect and release SPI bus */ void SDCardCancelCS(void) { SDCardCS(1); SDCardReadWriteOneByte(0xff);//Provide additional 8 clocks } /* Function function: select sd card and wait for the card to be ready for OK Function return value: 0, successful; 1. Failure; */ u8 SDCardSelectCS(void) { SDCardCS(0); if(SDCardWaitBusy()==0)return 0;//Wait for success SDCardCancelCS(); return 1;//Wait failed } /* Function: wait for the card to be ready Function return value: 0, ready; Other, error code */ u8 SDCardWaitBusy(void) { u32 t=0; do { if(SDCardReadWriteOneByte(0XFF)==0XFF)return 0;//OK t++; }while(t<0xFFFFFF);//wait for return 1; } /* Function function: wait for SD card response Function parameters: Response:Response value to get Return value: 0,The response value was obtained successfully Other, failed to get response value */ u8 SDCardGetAck(u8 Response) { u16 Count=0xFFFF;//Waiting times while((SDCardReadWriteOneByte(0XFF)!=Response)&&Count)Count--;//Waiting for an accurate response if(Count==0)return SDCard_RESPONSE_FAILURE;//Failed to get response else return SDCard_RESPONSE_NO_ERROR;//Correct response } /* Function: read the contents of a data packet from sd card Function parameters: buf:Data buffer len:The length of data to be read Return value: 0,success; Others, failure; */ u8 SDCardRecvData(u8*buf,u16 len) { if(SDCardGetAck(0xFE))return 1;//Wait for the SD card to send back the data start token 0xFE while(len--)//Start receiving data { *buf=SDCardReadWriteOneByte(0xFF); buf++; } //Here are 2 dummy CRC s SDCardReadWriteOneByte(0xFF); SDCardReadWriteOneByte(0xFF); return 0;//Read successful } /* Function: write 512 bytes of a data packet to sd card Function parameters: buf Data buffer cmd instructions Return value: 0 indicates success; Other values indicate failure; */ u8 SDCardSendData(u8*buf,u8 cmd) { u16 t; if(SDCardWaitBusy())return 1; //Waiting for preparation to fail SDCardReadWriteOneByte(cmd); if(cmd!=0XFD)//Not an end instruction { for(t=0;t<512;t++)SDCardReadWriteOneByte(buf[t]);//Improve speed and reduce function parameter transfer time SDCardReadWriteOneByte(0xFF); //Ignore crc SDCardReadWriteOneByte(0xFF); t=SDCardReadWriteOneByte(0xFF); //Receive response if((t&0x1F)!=0x05)return 2; //Response error } return 0;//Write successful } /* Function function: Send a command to SD card Function parameters: u8 cmd command u32 arg Command parameters u8 crc crc Check value Return value: the response returned by the SD card */ u8 SendSDCardCmd(u8 cmd, u32 arg, u8 crc) { u8 r1; u8 Retry=0; SDCardCancelCS(); //Cancel last selection if(SDCardSelectCS())return 0XFF;//Film selection failure //send data SDCardReadWriteOneByte(cmd | 0x40);//Write command separately SDCardReadWriteOneByte(arg >> 24); SDCardReadWriteOneByte(arg >> 16); SDCardReadWriteOneByte(arg >> 8); SDCardReadWriteOneByte(arg); SDCardReadWriteOneByte(crc); if(cmd==SDCard_CMD12)SDCardReadWriteOneByte(0xff);//Skip a stuff byte when stop reading Retry=0X1F; do { r1=SDCardReadWriteOneByte(0xFF); }while((r1&0X80) && Retry--); //Wait for a response, or exit timeout return r1; //Return status value } /* Function: obtain CID information of SD card, including manufacturer information Function parameter: U8 * CID_ Data (memory for storing CID, at least 16Byte) Return value: 0: Success, 1: error */ u8 GetSDCardCISDCardOutnfo(u8 *cid_data) { u8 r1; //Send SDCard_CMD10 command, read CID r1=SendSDCardCmd(SDCard_CMD10,0,0x01); if(r1==0x00) { r1=SDCardRecvData(cid_data,16);//Receive 16 bytes of data } SDCardCancelCS();//Cancel film selection if(r1)return 1; else return 0; } /* Function Description: Obtain CSD information of SD card, including capacity and speed information Function parameters: u8 *cid_data(Memory for storing CID (at least 16Byte) Return value: 0: Success, 1: error */ u8 GetSDCardCSSDCardOutnfo(u8 *csd_data) { u8 r1; r1=SendSDCardCmd(SDCard_CMD9,0,0x01); //Send SDCard_CMD9 command, read CSD if(r1==0) { r1=SDCardRecvData(csd_data, 16);//Receive 16 bytes of data } SDCardCancelCS();//Cancel film selection if(r1)return 1; else return 0; } /* Function function: get the total number of sectors of SD card (number of sectors) Return value: 0 Indicates an error in capacity detection. Other values indicate the capacity of the SD card (number of sectors / 512 bytes) explain: The number of bytes per sector must be 512 bytes. If it is not 512 bytes, initialization cannot pass */ u32 GetSDCardSectorCount(void) { u8 csd[16]; u32 Capacity; u8 n; u16 csize; if(GetSDCardCSSDCardOutnfo(csd)!=0) return 0; //Get CSD information. If there is an error during the, return 0 if((csd[0]&0xC0)==0x40) //V2.00 card. If it is an SDHC card, calculate as follows { csize = csd[9] + ((u16)csd[8] << 8) + 1; Capacity = (u32)csize << 10;//Get the number of sectors } else//V1.XX's card { n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2; csize = (csd[8] >> 6) + ((u16)csd[7] << 2) + ((u16)(csd[6] & 3) << 10) + 1; Capacity= (u32)csize << (n - 9);//Get the number of sectors } return Capacity; } /* Function: initialize SD card Return value: non-0 indicates initialization failure! */ u8 SDCardDeviceInit(void) { u8 r1; // Store the return value of SD card u16 retry; // Used for timeout counting u8 buf[4]; u16 i; SDCardSpiInit(); //Initialize the underlying IO port for(i=0;i<10;i++)SDCardReadWriteOneByte(0XFF); //Send a minimum of 74 pulses retry=20; do { r1=SendSDCardCmd(SDCard_CMD0,0,0x95);//Enter IDLE state }while((r1!=0X01) && retry--); SD_Type=0; //Default no card if(r1==0X01) { if(SendSDCardCmd(SDCard_CMD8,0x1AA,0x87)==1) //SD V2.0 { for(i=0;i<4;i++)buf[i]=SDCardReadWriteOneByte(0XFF); //Get trailing return value of R7 resp if(buf[2]==0X01&&buf[3]==0XAA) //Does the card support 2.7~3.6V { retry=0XFFFE; do { SendSDCardCmd(SDCard_CMD55,0,0X01); //Send SDCard_CMD55 r1=SendSDCardCmd(SDCard_CMD41,0x40000000,0X01);//Send SDCard_CMD41 }while(r1&&retry--); if(retry&&SendSDCardCmd(SDCard_CMD58,0,0X01)==0)//Identify SD2 0 card version start { for(i=0;i<4;i++)buf[i]=SDCardReadWriteOneByte(0XFF);//Get OCR value if(buf[0]&0x40)SD_Type=SDCard_TYPE_V2HC; //Check CCS else SD_Type=SDCard_TYPE_V2; } } } else//SD V1.x/ MMC V3 { SendSDCardCmd(SDCard_CMD55,0,0X01); //Send SDCard_CMD55 r1=SendSDCardCmd(SDCard_CMD41,0,0X01); //Send SDCard_CMD41 if(r1<=1) { SD_Type=SDCard_TYPE_V1; retry=0XFFFE; do //Wait to exit IDLE mode { SendSDCardCmd(SDCard_CMD55,0,0X01); //Send SDCard_CMD55 r1=SendSDCardCmd(SDCard_CMD41,0,0X01);//Send SDCard_CMD41 }while(r1&&retry--); } else//MMC card does not support SDCard_CMD55+SDCard_CMD41 identification { SD_Type=SDCard_TYPE_MMC;//MMC V3 retry=0XFFFE; do //Wait to exit IDLE mode { r1=SendSDCardCmd(SDCard_CMD1,0,0X01);//Send SDCard_CMD1 }while(r1&&retry--); } if(retry==0||SendSDCardCmd(SDCard_CMD13,512,0X01)!=0)SD_Type=SDCard_TYPE_ERR;//Wrong card } } SDCardCancelCS(); //Cancel film selection if(SD_Type)return 0; //0 returned after successful initialization else if(r1)return r1; //Return value error value return 0xaa; //Other errors } /* Function: read SD card Function parameters: buf:Data buffer sector:a sector cnt:sector number Return value: 0,ok;Others, failed explain: SD The size of one sector of the card is 512 bytes */ u8 SDCardReadData(u8*buf,u32 sector,u32 cnt) { u8 r1; if(SD_Type!=SDCard_TYPE_V2HC)sector<<=9;//Convert to byte address if(cnt==1) { r1=SendSDCardCmd(SDCard_CMD17,sector,0X01);//Read command if(r1==0) //Command sent successfully { r1=SDCardRecvData(buf,512); //Receive 512 bytes } }else { r1=SendSDCardCmd(SDCard_CMD18,sector,0X01);//Continuous read command do { r1=SDCardRecvData(buf,512);//Receive 512 bytes buf+=512; }while(--cnt && r1==0); SendSDCardCmd(SDCard_CMD12,0,0X01); //Send stop command } SDCardCancelCS();//Cancel film selection return r1;// } /* Function: write data to SD card Function parameters: buf:Data buffer sector:starting sector cnt:sector number Return value: 0,ok;Others, failed explain: SD The size of one sector of the card is 512 bytes */ u8 SDCardWriteData(u8*buf,u32 sector,u32 cnt) { u8 r1; if(SD_Type!=SDCard_TYPE_V2HC)sector *= 512;//Convert to byte address if(cnt==1) { r1=SendSDCardCmd(SDCard_CMD24,sector,0X01);//Read command if(r1==0)//Command sent successfully { r1=SDCardSendData(buf,0xFE);//Write 512 bytes } } else { if(SD_Type!=SDCard_TYPE_MMC) { SendSDCardCmd(SDCard_CMD55,0,0X01); SendSDCardCmd(SDCard_CMD23,cnt,0X01);//Send instructions } r1=SendSDCardCmd(SDCard_CMD25,sector,0X01);//Continuous read command if(r1==0) { do { r1=SDCardSendData(buf,0xFC);//Receive 512 bytes buf+=512; }while(--cnt && r1==0); r1=SDCardSendData(0,0xFD);//Receive 512 bytes } } SDCardCancelCS();//Cancel film selection return r1;// }