Hi friends,
Here is my project on interfacing of SD Card (microSD). microSD cards are available very cheap nowadays, a great option for having a huge memory in any embedded system project. It is compatible with SPI bus, so the interfacing is easy. SD card adapters are also easily available in market, one can easily make a bread-board adapter by soldering few pins on it. Following figures show the SD card pin-out & the bread-board adapter design by soldering 7-pins of a breakout header on the microSD adapter.
I had started this project with 1GB microSD card from SanDisk (later on tested with transcend cards also). The microcontroller is AVR ATmega8 or ATmega32 running at 8Mhz internal clock. MAX232 is used to interface the circuit with PC for monitoring the data. A 3.3v supply is used for powering the mega8, microSD and max232 (though the specified supply for max232 is 5v, it works comfortably at 3.3v).7 pins of the microSD are used here, shown in the figure of pin-out.
Schematic for ATmega8 is shown here (SD series resistors are removed, as they were limiting the speed of SPI bus. 51k pullups are added on CMD/DAT lines. This gives better stability with different cards. Also, two 3.6v zeners are added to protect SD in case when the ISP programmer voltage levels are of 5v. these diodes are not required if your programmer has settings for 3.3v output)
Note: VCC & GND pins of MAX232 are not shown in the schematic, but they must be connected in the actual hardware.
Following is the schematic for ATmega32, without RTC:
Following is the schematic for ATmega32, with RTC DS1307. Here two supplies are used, 3.3v for SD & 5v for remaining ICs.
The aim of this project was to learn interfacing of SD card and to understand the data transfer in raw format as well as in FAT32 format. I started with raw data transfer, sending some data to any block of the microSD, reading a block of it, reading and writing multiple blocks, erasing multiple blocks. All this in raw format. I used RS232 for viewing the data read by microcontroller from SD card. The uc sends the data to HyperTerminal. Similarly, to write data to card, the data was fed thru HyperTerminal, by typing some text.
Once raw data transfer achieved, I formatted the card with windowsXP (FAT32) and loaded it with some text files, directories and other files (all stored in root directory of the card). After that I wrote the FAT32 routines to read files, get file list (using HyperTerminal again), finding the total/free memory of card. All this data is sent to HyperTerminal by the uc.
Following is the HyperTerminal window showing different options:
Options 0 to 4 are low level functions dealing with raw data. If you use option 0, 1 or 3, you may have to reformat the card before using the FAT32 routines.
0: Erases selected number of blocks strating from selected block
1: Writes data to specified SD block address. Data to be entered in HyperTerminal using PC keyboard
2: Readss data of specified SD block address. Data is displayed on HyperTerminal window
3. Writes selected number of blocks strating from selected block
4. Reads selected number of blocks strating from selected block
Here, the multiple-block functions related to options 3 & 4 are disabled due to memory constraint of mega8 as those functions are not required for FAT32 testing. For enabling options 3 & 4, a macro defined in SD_routines.h (#define FAT_TESTING_ONLY) should be removed. And if you are using mega8, FAT32 library can be removed while testing these options for providing enough memory.
Options 5 to 9 are related to FAT32 . Only short file names are supported right now, 8byte name+3bytes extension. If you store a long name file in SD, it will be displayed by these routines in short name format only.
For testing these options, format the card with FAT32 file system and store some directories and text files (because text files can be read & checked thru HyperTerminal).
5: Displays list of available directories and files with size (in the root directory of the card)
6: Reads a specified file and displays the file contents on HyperTerminal
7: Create/Append file with specified name, enter text from HyperTerminal
8: Deletes any existing file with specified name
9: Displays total & free memory of the card (using FSinfo sector of the SD card)
Following figure show the HyperTerminal window when option 9 are selected:
Note: HyperTerminal is used here at 19200 baudrate, No parity, Flow Control 'none'.
Data transfer rate: 1 raw data block (512 bytes) takes 4.15ms for reading or writing (123.37 KBytes/s) at current 4 MHz SPI clock rate. If you have flash more than 8k, you can declare the SPI_receive() and SPI_transmit() functions as 'inline' functions. This will increase the transfer rate to 140 KBytes/s. These transfer rates can be further increased by using a 16MHz crystal (8 MHz SPI clock). FAT32 file reading is done at 78 to 91 KBytes/sec.
Updates in Ver 2.3 (for ATmega32):
- Support for SDHC cards added (tested with SanDisk & Transcend microSD and microSDHC cards). The initialization sequence and command formats are modified.
- A bug which was causing the program flow to go into infinite loop if the character number 512 in a sector was a CR (Carriage Return, ' '), in the writeFile function. Thanks to David & Piotr M. who pointed it out in the comments.
- Code is also tested successfully at 16MHz clock (8MHz SPI clock) with for SD/SDHC cards.
Follwing are the Hyper Terminal windows showing card detection (One window shows baudrate as 38400, that was while testing for higher clock speeds, current code still uses 19200 baud and 8MHz internal clock of Mega32).
Updates in Ver 2.4 (for ATmega32):
- Real Time Clock circuit support is added for time & date entries in the files. Now the current date of file creation and file update will be entered in the FAT table (can be viewed by checking file 'properties' using a PC)
(The RTC will also be useful in data-logging with time-stamp)
- Three more options added in the Hyper Terminal menu for displaying or updating RTC date & time. New menu is shown in the above figure.
(Note: Version 2.2, 2.3 & 2.4 are tested on ATmega32, but they can be adopted to any controller having RAM >= 1KB and Flash >= 16KB)
Download complete source code files:
Download here the zipped source code files modified for mega32, written in winAVR-AVRStudio.
Version 2.4 (RTC added for Date/Time entries) 17 May 2010
Version 2.3 (SDHC support added) 09 May 2010
Download/view source code files V2.1 (for ATmega8):
Following files are compiled using winAVR inside AVRStudio. This Version does not support SDHC cards. Also, append file feature is not available.
- SD_main.c
- SD_routines.c & SD_routines.h
- FAT32.c & FAT32.h (Ver 2.1, last updated-13 Sep 09)
- SPI_routines.c & SPI_routines.h
- UART_routines.c & UART_routines.h
- Makefile
- HEX file (Ver 2.1, last updated-13 Sep 09)