================================================================================================================================================

Saturday, January 31, 2009

SD/SDHC Card Interfacing with ATmega8 /32 (FAT32 implementation)


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 (Click on images for larger view).












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 (updated on 10 May 2010, 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 (updated on 10 May 2010):


Following is the schematic for ATmega32, with RTC (added on
17 May 2010; CS pin correction, PB4 instead of PB1, done in Mar 2014). Here two supply voltages 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 as that time mega8 was used for testing and these functions are not required for FAT32 testing. While testing with mega32, options 3 & 4 can be enabled by removing a macro (#define FAT_TESTING_ONLY) defined in SD_routines.h.

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 figures show the HyperTerminal window when options 5 & 9 are selected:
(These figures show menu from Ver2.3 or earlier. Menu style is changed from Ver_2.4 onwards, which is shown in the update history)

Note: HyperTerminal is used here at 19200 baudrate, No parity, Flow Control 'none'.

This project needs very few components and can be done easily at home. Try it out!











Download the source code files from here:Download here the zipped source code files modified for mega32, written in winAVR-AVRStudio.

Version 2.4.1 (RTC added for Date/Time entries) 17 May 2010/24 Apr 2011
Version 2.3 (SDHC support added) 09 May 2010
Version 2.2 (No SDHC support) 13 Sep 2009

Download EAGLE schematic file of Ver 2.4

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.
1. SD_main.c
2. SD_routines.c & SD_routines.h
3. FAT32.c & FAT32.h (Ver 2.1, last updated-13 Sep 09)
4. SPI_routines.c & SPI_routines.h
5. UART_routines.c & UART_routines.h
6. Makefile
7. HEX file (Ver 2.1, last updated-13 Sep 09)

Please put up a comment or mail me if you find a bug in the code. The updates are because of valuable suggestions & comments from the users of this code. Thanks a lot!!


Buy from Farnell (Element14): ATmega32 (India), ATmega32 (USA)


Related posts:
You can visit my post of microSD ATmega32 Data-Logger, which uses modified FAT32 library for automatically creating files without using hyper terminal.
If you want to test FAT32 functions or learn more without making the microcontroller hardware, you can visit my post here: microSD-FAT32 using Visual C++)

Update History-----------------------------------------------------------------------------
Version 2.4:

- 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.

Ver 2.4.1:
- Same as 2.4, with a bug fix for RTC: 'twi_init' function added to define I2C clock freq. 100K@ 16MHz (50k@8MHz). This was taking default values earlier, which was as high as 500K@8MHz, not desirable

(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)
Current memory usage (Ver_2.4): Flash: 12908 Bytes; RAM: 700 Bytes (appx.);

Version 2.3:
- 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, '\r'), 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).








Version 2.2:
- Append file feature added. 'createFile' function replaced with writeFile, which looks for the filename first, if the given file name doesn't exist then it creates new file and writes data, but if the file already exists, then it opens it and appends the entered data.
- A bug removed which was giving error related to use of 'LONG'
- The FAT32.c & .h files are updated on 13 Sep 09 to remove a bug which was limiting file size to 32MB (Thanks to Kun-Szabo Marton who pointed it out)

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.

Version 2.1:
- A bug removed which stopped creating new files after 32*8 files in the root directory
- The root directory was unnecessarily getting expanded by one cluster whenever a file was created. Fixed in the new version
- Also, the fixed cluster size of 8 sectors is removed, this version will support other cluster sizes as well

Version 2.0:
- Support added for SD cards having first sector as MBR rather than the boot sector
- createFile and deleteFile functions added
- A bug fixed in reading files stord at far locations in memory also correction made to accept 8+3 char file name (by mistake, it was taking 7+3 earlier)
- FSinfo sector used for storing total free cluster count &
next free cluster number for faster file access
- Instant freeMemory display (earlier it was taking more than 30secs) using FSinfo sector. FSinfo sector is updated now whenever a file is created or deleted
- File memory size display in decimal, like windows (earlier it was in hex)
- Raw SD functions multiple block read and write, which are not required for FAT32, are disabled using FAT32_TESTING_ONLY macro for getting extra space required by createFile & deleteFile changes (you can activate it if you have more than 8k flash) Right now flash is 99.9% full
- Clock speed raised from 1Mhz to 8 MHz, new SPI speed (after SD initialization): 4MHz instead of 500K & baudrate: 19200 (for HyperTerminal) instead of 4800
-------------------------------------------------------------------------------

References:
1. Microsoft's FAT32 specification document
2. SD-Simplified Physical Layer Specifications
4. F. Foust's Application Note on SD
5. FAT32 Structure info, includes MBR details
6. Simple FAT32 Structure explanation
 
7. Chan's FAT library
8. SD Association's Website for further info

Regards,

CC Dharmani
ccd@dharmanitech.com

699 comments:

«Oldest   ‹Older   401 – 600 of 699   Newer›   Newest»
CC Dharmani said...

To Ravindra:
Some of the people have already used this code for two cards! You'll need to modify most functions a little bit so that you can specify which card you're referring to when you call the function. Basically, adding one more argument in function calls. Also, you need two separate 512 byte buffers, in case you want to transfer data between them.

To Chillance:
I've kept this project as open source. You don't need to pay any license fees to me, use it freely!!
Though, you can acknowledge me by keeping the file headers as they are, which include authors name and website address.

Priyank Bolia said...

Getting error with WinAVR and AVRStudio:

../FAT32.c:739: internal compiler error: Segmentation fault

Anonymous said...

Hai friends im doing my project on digital display, in this im making ring tranducer to produce strain in terms of voltage(mv), after that im keeping ATMEGA32 microcontroller,the input voltage can be connect to ADC then according to my programme it can goes to LCD(16X2character), for amplifing the signal im connecting oscillator, so please provide the schematic diagram for this connections.

Anonymous said...

hello i run it but gives error fat32 not found help me thank you

Anonymous said...

hello to mr dharmani .

i run your simulation in protues

but gives this error:fat 32 not

found.please help me and answer me as soon as.

thank you.

Anonymous said...

hi how can i format sdcard in protues v7.6 in fat32
thank you

CC Dharmani said...

Hi,
quite a long time ago when I was writing the code, I tried to simulate but the version of Proteus was having only MMC card and my code is not compatible with them. I then tried on actual circuit. So, not much of experience on Proteus with these cards.
I hope someone else who has tried it successfully can throw some light here..
Or else, you may try to build the circuit!!

Anonymous said...

thanks.if you could correct the problem of proteus simolation say me to.realy thanks for your projects mr dharmani.

Anonymous said...

hi, thanks for the code. It works great. I have only one question, I'm working with bmp images in black and white in an LCD, when I read the file is correct and it is displayed on the LCD. But when I log back into the same image, does not recognize. Only the back to recognize when the program starts from the beginning. Any idea why this happens?

!¡!¡!¡!¡! said...

Hi, I had de same "FAT 32 not found" problem but it solved adding a 150k pull ups on clock and miso lines in adition to mosi and CS already included in schematic. I dont know if 150k is the optimal value, but i didnt have any others at the moment.

Id like to suggest to separate serial (uc to pc) communications away of the sd and fat functions due to it takes quite a lot of work to isolate those functions to create a more generical sd-fat library.

Anyway, it works pretty nice and it s an excellent work.

Regards.

!¡!¡!¡!¡! said...

Ive realized that pull ups where only a temporal solution and "FAT NOT FOUND" appeard again.
i used a voltage div. on mosi and clock lines, left chip select with zener and pullup as shown in schematic and miso directly connected to uc. Now it works perfectly altough not the best solution.

Harish said...

Hello Dharmani,
Thanks for sharing your knowledge. Not many people do this.
I have a few questions for you.
1) I am getting error : card initialisation failed with version2.4 of your code.
But I changed the do while loop condition in the function sd_init() of sd_routines.c file from while(response != 0x00) to while(response != 0x01)for the 3rd and 4th do while loops and this fixed the error and I am able to see the options. Not sure if this is correct or not.
2) FAT32 options are not available because of "FAT32 not found error" even though I re-formatted the card with FAT32 file system while the raw data options are working perfectly.
I am using Kingston 512MB SD card.
As I see your code, I figure out that this error is caused because getbootsectordata() function in the fat32.c file is returning 1. Do I need to change anything in this function (may be for this sd card) so as to get rid of this error??
3) Is there any way that I can view the raw data from the sd card using my pc??
As I saw some earlier posts suggesting to use winhex s/w to do so, I downloaded that s/w but could not figure out how to view raw data using this.
Any help regarding this is highly appreciated.
Thank you and waiting for your reply.
Harish.

Harish said...

Hello Dharmani,
I got rid of all the problems in my previous post. Please ignore it.
Now all the options are working for me except option 7 which is "write file".
when I enter '~' character at the end of my text, the screen hangs up there and does nothing, until I re-run the program and the file is also not created.
If anyone else faced the same problem, please send suggestions on this.
Thank you,
Harish.

Anonymous said...

wonderfull work,
it's possible to read a file located in folder?

best regards
jerry owens

Harish said...

Hello friends,
Does writefile() function work for anyone in version 2.4 code?? If so please let me know if you had made changes to FAT32.c

Thanks and Regards,
Harish.

honey said...

Wow thats a cool little gadget! I’ve never seen anything like that before I will definitely check out the website… I think we are often too lazy to monitor our health but there is hardly any excuse with something like this, thanks for sharing!

Anonymous said...

Thank you!!!
This is really great, i am doing a project using a SD card and your source will help me very much. Thank you again!

Саня said...

Hello comrades. How does your software receives information from real-time clock (RTC)? This feature is in the library? If so, what conclusions should connect the microcontroller RTC?

CC Dharmani said...

Hi mate,
the RTC library is included in ver2.4 of the source code. Just connect the circuti as per the schematic (Ver2.4 of schematic which includes the RTC chip) and try it out after loading the code into ATmega32.

zeeshan said...

dear sir

i have tested ur micro sd card project it really works well and its well coded
sir i want to learn its basics so can u plz send me the code that can handle only raw data not the fat32 formatted

regards
zeeshan (zeeshan2029@yahoo.com)

sumit said...

Hello,
We successfully compiled this program but we are not being able to work the hexfile in atmega 32 using serial or parallel port...
will u plz suggest us any burner or direct any other procedure to do the same



hope u will reply soon...........
Sumit..

kishore said...

Hi I am kishore from Bangalore, Planning to have SD card interface in my project. I need your help.

lam said...

thanks a lot for your help

Jeny said...

nice code...
i have success try your code..
do you have any solution for compress the data? like winzip?
couse i have about 1Gb data to transmit using RS232 11.500kbps.
is have long time if not compreesing the data

Anonymous said...

we want to make a music player with this project!can u help us,as in we want to read sd card contents like mp3 or wav. files!we are 3rd year extc students,so have no clue about it!

pratibha said...

can u send us the details on twinkle.pratibha@gmail.com..we really need help!we are implementing ur AtMEGA 32 interfacing..is it ok!

Anonymous said...

Hi, I would be grateful if someone tell me how to rename a file and how to create a folder and then create files on the new created folder in this project

jadin jousche said...

Thank you so much for this code! Ive used this with ATMega128 16PU and Im using 3 voltage dividers on the CS,SCK and MOSI lines with 10k pullups on CS and MOSI lines..

jadin jousche said...

By the way, is there any routines for formatting the SD card within the device in FAT32 FS?

wulan said...

hai dharmani,,
opportunately, i have the similar project with yours. I wanna make an MP3 Player and using MMC as the memory.

I had downloaded your source code file containing SD Card interfacing with 32. that's really match with mine.:) thank you
but when i read the Version 2.2, SD_main.c, I cant find "the define" for variable "totalBlocks".

so,,what should I put as "the define" of "totalBlocks"? And where should I put it?

sorry,,I'm not very good in english and I'm just a beginner. I hope you will give me some help for this. thank you dharmani... :)

swati said...

hello
sir
Is that possible to use this code on lpc2148 ARM7.please guide me.

Abbet said...

Hi CC Dharmani ,

I'm a student and I would like to use a SD card in my project. But when I try to connect the SD card, the HyperTerminal writes: "FAT32 not found". I can't read and write any blocks.
I've formated my SD card with Windows XP in FAT32 mode. I use a ATmega32 and SD Card from Sand Disk.

Chris

CC Dharmani said...

@ Wulan:
totalBlocks is defines in sd_routines.h

@ Swati:
I'm not experinced in ARM, but yes, with some modifications, you can use it. You'll need to change the SPI & UART routines completely as they are hardware specific.

@Abbet
Try to run with reduced SPI clock speed. The problem also comes due to arrangement of pull-up resistrs or the conversion of voltage levels (5v to 3.3v)on SD data lines. You can refer to previous comments for more info.
If you still get the problem, try using microSD card instead of SD.

kishore said...

Hi CC Dharmani,

Thanks for your code on SD card, i made only one change while implementing it on my driver

varl = ((addr & 0x003F) << 9);
varh = ((addr & 0xFFC0) >> 7);


with the above change it worked ...

now i have problem in reading FAT entries, i am able to read the Boot sector information, and i stored manually one file on microSD card.. I tried finding the file ...

but when it entered into findFiles function .. it unable to get the root directory information..

According to the formula, root directory = reservedsector+no.of FATS* FATSize.

Rootdirectory = 0x26+ 0x02 * 0x00000EE5 = 0x1DF0

But when i read on that address, i am getting all 000s ...

instead i am getting some data 0x1E00...

Can you please help...

Chrsitian said...

Hi,

Thanks a lot!
The system works correctly. Your help was very useful !

Qasim said...

hi i want to write the data continously without closing the conenction can u pelase tell me how i can do that

Qasim said...

hi,
your library works fine
i want to write the data continopusly in the same text file can u pelase tell me how i can do that using ur code please help

ASHISH said...

Helo sir,
i am curently working on this kind of project where i need to transfer the image stored in the micro sd card to PC. so i need to just read the image and after reading i have to delete the image so that i can use the same memory location for different image stored at different time.
please gide me for this .
please send me appropriate coad for this . My Email Id is
aashish.garv@gmail.com

ASHISH said...

hello sir,
i discussed you about my project but i am still worried about the programming part.i also want to know how much time will it take to transfer 600 KB data to another terminal? kindly help me as soon as possible.

Jerry Owens said...

Hi
it's possible to read a file located in folder?

best regards
jerry owens

CC Dharmani said...

Hi Jerry, the library doesn't support reading from folders right now. That feature will be added in the coming versions.

madhu said...

hello Mr.Dharmani,

i'm using u'r code with Infineon micro controller. but i'm hanging in receiving mbr data from sd card. could you please suggest me, how can i get over this.

Thanks,
Madhu

Anonymous said...

Hi,

I'm trying to write or read any file but I don't knon how to put a file name into HyperTerminal. I see "enter file name" and when I enter it (f.e. test.txt) nothing happens. Should I enter a special file name format?

Krzysiek

Anonymous said...

All works fine. My fault:)

Krzysiek

Anonymous said...

Dear Dharmani,

I used your great code with a 1GB Kingston uSD and everything was fine.

But when I insert a 2GB uSD it says "SD Init Failed.." after about 10 CRLFs.

Can U PLZ help me to solve the issue?

Sincerely yours

CC Dharmani said...

Hi, you can check the card on PC, if not done. Also, if you have changed the SD card adapter, you can try with the old adapter which worked for the 1GB card. SD init fail comes mainly due to hardware problems. You can recheck the connections also.

Anonymous said...

Sorry that I border U,

but I made this breakout board:
http://i51.tinypic.com/316qf54.jpg
for uSD connectors like http://www.google.com/images?um=1&q=microsd+connector
and I'm using it.

I double checked connections and everything is fine.

Even I change the default FAT32 allocation unit sizes of uSD while formatting but it doesn't work.

Best Regards

Anonymous said...

Dear Dharmani,

I've tried one of my friend's 8GB Silicon Power Class4 microSD HC and it also works!
But my own 2GB doesn't work!

http://img109.imageshack.us/img109/1725/21556287.jpg

the right uSD is mine and it doesn't work.

Nobody knows why? :(

Luciano said...

Hi,
i try your wounderful project.
Some improvment: using cmd 7 (write file) for 19200 baud-rate have more overflow errors.
I made a circular buffer and work rx0 in interrupt that write in buffer.
For every 256 block writed, tx0 send string "Enter text (end wit......) . Delete repetition that cause overflow error or make a tx0 circular buffer and use txo in interrupt.
In any case it is a big work!
Congratulations.
Luciano

CC Dharmani said...

Thanks, man!! I appreciate any encouraging words at this time!! I'm stuck up with some studies which consume all my time.. There may be many people out thr whom I cudn't respond.. I'll be able to devote my time fully here after six months, at max..

Kindly put up all the questions here, as I'm looking into all of them. I'm already in process to procure all major AVR controllers. I'm gonna start a new post which will discuss examples of the usage of this code for various applications, like data logging, timers, etc.. I'm gonna post all the downloadable codes here.

If anyone of you, who has already used this library successfully & wanna share the code, is most welcome.. The code will be displayed with your name & website address if you want.. Pls send me the details on ccd@dharmanitech.com

kuzmich said...

Hi all!
My Hyper Terminal sends me the following lines:

?oaoo`aiu`eaunnn

~`p`z`…oaoa`‚iiaeo
~`q`z`—oeoa`oeicia`‚iiae
~`r`z`’aaa`oeicia`‚iiae
~`u`z`‡ao`?eia`ieoo
~`v`z`’aaa`†eia
~`w`z`?oaaoa`†eia
~`x`z`„aiaoa`†eia
~`y`z`’aaa`“„`?aiiou`?a?aaeou`h”ioaio†oaai

~`“aiaao`??oeii`hpmyiz`p

`‰ioaiea`i?oeiia



This is not ASCII. What is it? With what it could be linked?

CC Dharmani said...

Hi Kuzmich, I think you should have a re-look at your hyper terminal settings: 19200 baud, No parity, flow control 'none'. If the terminal settings are ok, make sure you have UART settings at microcontroller side same as given in the code. The controller should be running at 8MHz, for the given settings.

Wazz said...

Hi, thanks ever so much for your code. I am owrking on a different project, but for my test circuit I require an avr interfacing through spi bus to a sd card to write and read a file. I cam upon your code and I ran it in Gcc mode in Avr studio for stimulation. It complied properly however I got an error when I try to build/run it. The error says:
c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/bin/ld.exe: SD_main.elf section .text will not fit in region text
c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/bin/ld.exe: region text overflowed by 420 bytes

I am assuming it is running out of program memory.. But can seem to fix the problem, can you please help.

Anonymous said...

I have ported your FAT32 code to Visual C++, so that I can test it fully before porting it to my Motorola microcontroller. I don't know if this is a bug in your code. In function freeMemoryUpdate,

if((size % 8) == 0)
size = size / 8;
else
size = (size / 8) + 1;

The '8' should be changed to sectorPerCluster.

I have other improvement and suggestion on the FAT32 code. Let me know if you want to discuss further.

Anonymous said...

Does your FAT32 code deal with fragment files? From the look at the searchNextFreeCluster function, it seems that it only goes to higher address to get free clusters, but if there are free clusters at the lower address, it cannot find it. Is it correct?

BR - Henry

CC Dharmani said...

@Wazz:
I don't have much idea about it, but looks like while compilation, you might have selected a controller which doesn't have enough RAM/Flash. Try to select mega32 or other controller with atleast 1K RAM & 16K flash

@Anonymous:
That's correct. In that function, instead of 8, it should be sectorPerCluster. And also, instead of 512, it should be bytesPerSector. Though the current function will not give any problme for most of the cards, this will improve compatibility with some cards which don't use 512B sectors & 4KB clusters.
You are welcome to suggest any improvements you would like to mention.

@Anonymous
The code deals with fragmented files. When a fresh card is used, the code keeps track of the next free cluster. If any file is deleted, the first sector of the deleted file is stored as next-free cluster. This means, after deleting a file, if you create or append a file, the sectors which are freed by deleting a file will be used first to store new data. Hence, the file will be fragmented.
If you use a card which already contains some files, then this code relies on the next-free cluster stored in fsInfo sector of the card by the operating system which you used, and it starts storing data from that sector onwards.

karthikeyan said...

hi great work from u. iam trying to interface microsd card with ATMEGA32, but iam not successful in interfacing it. iam not comfortable with avr studio and i also have codevision avr original software. so can u please send me the source code for cvavr to skarthikeyanme@gmail.com

thanks

Anonymous said...

Hi CC Dharmani,

Thanks for your reply. It is a very well written and easy to follow piece of code. Now I undertand that your FAT32 code will work properly with fragmented files also. Is it okay to post your FAT32 code, which has been ported to Visual C++ on the internet? I think it will benefit many who wants to learn FAT32 system without the need to have actual hardware. I add to your writeFile function to check available free clusters before proceeding. Otherwise, it will eat up the free clusters without being able to write the whole file if there is not enough disk space.

BR - Henry

Anonymous said...

Hi CC Dharmani,
I found another bug in the writeFile. If the number of files in the directory is 32, 64, etc, it finished fulling up the directory entry and link a new cluster to the rootCluster. But it does not initialize the new link with dir->name[0]=EMPTY, so if view the directory in Windows, it will show many garbage directories. This bug will not show up if the card initially is filled with all zeros. I have rewritten the structure completely. Let me know if you want me to upload to you.
BR - Henry

CC Dharmani said...

Hi Henry,

thanks for the updates on the code. You can send me the modified function, I'll test it on AVR controller. My email id is: ccd@dharmanitech.com

You can post the Visual C++ code on internet, it'll be really helpful for many. Do send me the link where you post it, I'll also try it out!

Anonymous said...

Hi CC Dharmani,
I have sent you the FAT32 program ported to Visual C++. I think the best place to put this code on the internet is in your web page. So please help to post this software for eveyone use. Your code is very useful for me to learn the FAT32. My bug fix is also there with the code.
BR - Henry

mr aurangozeb said...

Hi Dharmanitech,
I want to rewrite content of a file. How can I do this?
For Example: i have a file naming "track.txt" and the content of this file is a 100. I want to make it 101 without appending. I want to just edit the content o the file. My email aurangozeb@gmail.com

Anonymous said...

Sir,
i am interfacing sd card with 89v51rd2.i included code for fat32. but the file i created from pc can'be read by the mcu. and the file i created therough the mcu cannot be read by the pc.
give me a solution for this

Anonymous said...

hello sir,

I am using the program sent by you for AVR.I d coverted it for 89V51RD2. i had changed SPI function and serial functions.FAT32, SD_ROUTINES as same that of your code.
I am using KINGMAX 2gb SD CARD ,formatted with FAT32

Row read,write operations are working fine for me.And read file,write file operations are also working fine with MCU.i read block 0 , i am able to get the fat32 structure.
After the row read/write operation i formatted the card .
After formating the CARD i create a txt file to sd card through PC.
But i am not able to detect the file through MCU.
And the file created through MCU can't be detected through PC.
Can you suggest me a way to solve this problem?

CC Dharmani said...

Hi, if possible, you may send the code to me, I'll have a look, though the code may not have a problem.
Are you formatting the card with the in-built function of the operating system (windowsXP or vista, etc) or are you using a separate software for formatting? The problem looks like the FAT table location detected by the MCU is different from the actual FAT generated by the PC, so the files generated by MCU are invisible to PC and vice versa, though each one finds find files generated by itself.
It needs some more analysis of the fat data by reading the raw sectors.
You may try with another card.

Anonymous said...

Hi CC,
I have posted the FAT32 code on this web page:
http://bytes.com/topic/c/insights/903644-understanding-fat32-format
Sorry I have rewritten many of your code. It wasn't bug problem. I only try to make it more readable and logical.

Anonymous said...

hai sir,
Thak you for your reply.

i sent my code to your mail id "ccd@dharmanitech.com "

please have a look at my code and tell me the neccsarry corrections.

I formatted the card in XP. and i tried in VISTA also.In both the case the files created through PC cannot be detected by MCU.
So please give your valuable suggestion.

Anonymous said...

Thank you for this wonderful job. Appreciated. Great documentation also.

Anonymous said...

How fast the speed for atmega128/Atmega32 to Read & write text on a file.txt.
if xtall used is 16Mhz. ...megabyte/sec or ...kb/sec?
i need to play a .wav

Thanks, u done a WONDERFULL Project! im very Amaze.

Anonymous said...

ok, u just write it on:
Extra updates in Ver 2.1 & 2.2 section above...
my mistake.

how can i do a RAW Read&Write to
a 2GB MMC special formated, just for RAW data on whole MMC.
so we would gain more Speed instead
dealing with file system.

with available speed, i would need to have 2 MMC, 1 with File System, other 1 for big MEM. to play .Wav or even .MP3

Anonymous said...

hai sir,
i had mailed you my code. but no reply..
i am waiting for yor reply.
please heil me

CC Dharmani said...

Hi, I've mailed you the procedure to trace the error using HxD editor

Sakibnaz said...

Hello.
Really its very nice tutorial for learning FAT with AVR.
Anybody have experience in Proteus simulation with this project? I have tested with Proteus but AMega32 UART returns "SD init fail..FAT32 not found!" for the version Version 2.2.
The "cardimage.mmc" I have loaded is working with other simulation. Any idea please???

James said...

Hi, CC Dharmani,
I hijacked your code and changed it little bit to my current project, I sample the data by ADC and intend to write all the data into SD card. The sample rate of ADC could approach 1000 per second, however, the writing rate of SD card is only 6 per second, and will be much slower if several sectors have been taken, like 1 per second, do you think is it too slow? how to make it faster? I am using the 14.7456MHZ crystal and the spi_init speed is fclk/64.

matej said...

Any chance that this project would work with ATXMEGA MCUs?

Anonymous said...

hello.
i simulating your project with avr studio & proteus.

but it was stop in spi transmit function & not running complete.

why ?!
m.y@inbox.com

CC Dharmani said...

@Sakibnaz:
I think the proteus is using the simulation of MMC card, not an SD or microSD card. MMC card has a little different initialization sequence and this code doesn't include that, which must be the reason for the error messages during simulation.

@James:
It's better to store data in 512byte buffer and only when the buffer is full, access the card write functions. This will make it much faster.
Also, low spi speed is required only during card initialization, after which you can raise the speed to fclk/2 (the maximum allowed).

@matej:
Certainly it would. These libraries will work for any controller with SPI bus, with little modifications related to the change of registers/ compilers related to that controller.

@m.y:
You need to manually clear the spi flags during the avr-studio simulation (also, you can read the above comment related to problem during simulation in proteus)

James said...

Cool, problem sorted as your mentioned, talent you are.

mr aurangozeb said...

Hi Dharmanitech,
I want to rewrite content of a file. How can I do this?
For Example: i have a file naming "track.txt" and the content of this file is a 100. I want to make it 101 without appending. I want to just edit the content o the file. My email aurangozeb@gmail.com.
Please suggest me how can i do this?

Anonymous said...

hi there
i want to interface SDHC card with ATmega32U4. how can i compatible this code(ver.2.4) to this micro controller's pin?

reza said...

Dear CC Dharmani
i want to interface SDHC card with ATmega32U4. how can i change this code (ver.2.4) for this micro?

CC Dharmani said...

@Aurangozeb:
Modifying text in a file is easier if you already know the text location in file.
Once the text location (in terms of the character no.) in the file is known, you can easily obtain the sector you need to read, by simply dividing the character no. with the 512 (or bytesPerSector).

Well, once you know the sector, get the starting cluster of the file from FAT (which we are already doing in writeFile function), find the sector in the file, load it into buffer, modify the content whichever yu like and rewrite the buffer. Done!

You just need to modify the writeFile function a little for doing this. In fact, if you look closely at how we are obtaining the last sector of the file for appending it, you'll get the clue for doing this.

Now, if you don't know the text location, then just read the file's every sector, keep comparing the text which you want to replace and replace it wherever you find it.
You will need to read every sector and write it back if you modify it, otherwise cntinue reading till end of the file. It's like combination of readFile & writeFile.

@Reza:
ATmega32U4 has the SPI bus, so you don't need to change much. Just change the pin numbers which you are going to use for 'card select'. Also define the data direction for SPI pins correctly and you should be able to get the code working!
Though I've got the Teensy board with the same controller, due to other work I've not been able to work on it so far. I'll post the code when I'm done with it.
Meanwhile, you can give it a try!

Marcin said...

I am very grateful to you for your code! But I have one question: if I use Your writeFile function with the same file name, data should be appended. So I used it like this writeFile(fileName); writeFile(fileName) with some delay between and only first data has been written. Second write file action just do nothing.

reza said...

Hi CC Dharmani
thanks for reading my post.i have teensy2 board with SD adaptor too, but i don't want be work like flash memory. i want to read/write and access to my data look up table via micro. if you have idea, please help me and answer me as soon as possible.

thank you again.

CC Dharmani said...

@Marcin:
Ya, that's right, if you call writeFile function with the same filename, it will append the data, that's exactly what the code is doing when writeFile fucntion is called for an existing file.
Have you done any change in the fat32.c?

@Reza:
If you need to read/write the look-up table only with micro, you may not need the FAT32 file functions. You can just go ahead with raw read/write functions, it'll save some time in troubleshooting.

reza said...

hi CC Dharmani
i need memory more than micro's capacity, i want to store my data in look up table look like small database, so using flash memory is necessary. also, i need file system to access to these data through micro.

John King said...

Hey dude... The code the is working fine but I am not using UART and I want to read a file readerme.txt from the uSD card. So I stored the file name in fileName like this:
fileName[0]='r';
fileName[1]='e';
fileName[2]='a';
fileName[3]='d';
fileName[4]='e';
fileName[5]='r';
fileName[6]='m';
fileName[7]='e';
fileName[8]='.';
fileName[9]='t';
fileName[10]='x';
fileName[11]='t';
fileName[12]=0x00;
But the programme tells me that no such file exists :(
What could be the problem?

Nikolaj said...

Has anybody tried simulate it on proteus, I have some errors, with Uart.. Here is some screen

http://img218.imageshack.us/f/errorlq.jpg/

CC Dharmani said...

@Reza:
Looks like you are storing the lookup table file using PC and then reading it using the micro. In that case, you don't need to chnage the readFile function a little, as the readFile function is getting data and sending it to UART, while in your case you'll be using it for some other way.

@John King:
Can't be said much without seeing the other changes you might have made in the code, as the way you are storing filename doesn't spoil anything here!

Few things to check:
- make sure that the file 'readerme.txt' is stored on the uSd card
- the file should not be in any folder, it should be in root directory only
- you should be forming that file name first and then calling readFile function, you should not attempt to form file name after the converFileName function is called (inside the readFile function)

@Nikolaj:
that looks like error in terminal settings. Use baudrate '19200', no parity, flow-control 'none', and while simulating, select the clock frequency of AVR as 8 MHz. I think that should solve the problem with UART.
(But still you may get problem with the MMC card read/write simulation, as the library on this blog doesn't support MMC cards)

John said...

Hi CC Dharmani,

Thank you so much! The code is very efficient and very professional!

I encountered a few problems when adapting to SiLabs 8051 MCU. First (#1), if SPI was driven by slow clock (350KHz) for initialization, the system would keep timing out in the GO_IDLE_STATE block. If driven by fast clock (12.25MHz), the system initializes fine.

Second (#2), in the "write single block" routine, the MCU receives correct response 0xXXX00101 *after* it is compared in the if-block, so the system keeps on saying write error even when the write was successful.

What could have caused this? (#3) I am guessing it is because I declared buffer buffer[512] as xdata. If I don't declare it as xdata, the compiler would complain that the data segment is too large.

Also (#4), is it okay if I transmit one more 0xFF after the write, like:

SPI_transmit(0xFE); //start token
for(i=0; i<512; i++) SPI_transmit(buffer[i]);

SPI_transmit(0xFF); //dummy CRC
SPI_transmit(0xFF);
SPI_transmit(0xFF); //added

Thanks!

Anonymous said...

Hi,

Can this FAT32 driver read/write to FAT16 or FAT formatted drives?

Thanks!

John King said...

Dear Dharamani,
When I formatted the uSD to FAT32 with my linux box, it shows the error that I mentioned in my previous comment ("file not found" when I attempted a read from the file readerme.txt)... But when I formatted my uSD on XP to FAT32 it worked perfectly...

Wonder what happened... but it works perfectly... Thanks a lot.

But how come FAT32 on linux is different from FAT32 on windows???

Anonymous said...

hi dharmani,,
Really great work! thank's a lot.. it works for my final project,
but i have some problem, the code is not compatible with MMC Card, I used micro SD Card (it works well).
The MMC initialisation is OK, but when i want to read or write the system is hang..
i try to debug, but i could not found the reason, below is slice of your code in FindFiles():
"firstSector = getFirstSector (cluster);

for(sector = 0; sector < sectorPerCluster; sector++)
{
Read1Block(firstSector + sector);
..................
"
after read1block the system hang..
do you know the reason?
using micro SD Card is ok
but this problem just happen when i used MMC Card..

thank's in advance..

CC Dharmani said...

@Anonymous:
This library works with only FAT32, it doesn't support FAT (FAT12) or FAT16

@John:
I've never tried formatting with Linux. Great that you found it, would be helpful to others.
And ya, we need to check out what's the difference in FAT32 formats of XP & Linux, as actually both should be same since both should be following the FAT32 structure defined by Microsoft in the specification document.
Meanwhile, if any problem, follow formatting by XP. After all, FAT is created by Microsoft! ;)

Acceph:
The initialization command sequence of MMC is little different as compared to SD.You need to change that part in this library. That must be reason for the hanging, as the global variables will not get correct values without proper initialization.
You can refer to some of the MMC initialization sequences available in the avrfreak's projects

Anonymous said...

hi dharmani..
thank's for your suggest..
i will check in the AVRFreaks

Anonymous said...

hi dharmani..
the MMC card have response with give me 0x00 (ready status)..
but when i execute this code :

FAT32_active = 1;
if (getBootSectorData())
{
FAT32_active = 0;
}
if (FAT32_active)
{
writeFile(namafile);
}

the system is hanging..
is the write command for SD Card compatible also with MMC?
if there is any differences, please tell me..
i have read many ebook, but mostly of them just said the Initialisation sequence is differ both MMC and SD Card..
and I have followed this MMC sequence..

Anonymous said...

Sir
Will it work for for SDSC? More specifically I am talking about Toshiba 128MB memory card. Thanks

Anonymous said...

Sir
I did almost exactly same, only change is, I dont have 3.6 regulator. I did with voltage divider.


If the sd card (Toshiba 128MB ) is present in the circuit, Hyper terminal shows

""Card Initialization failed..""


If it not present in the circuit,
"SD card not detected.. "


Serial communication and Hyper Terminal running well. Where should the probable problems? Thank You Sir.

Anonymous said...

Sir
I did almost exactly same, only change is, I dont have 3.6 regulator. I did with voltage divider.


If the sd card (Toshiba 128MB ) is present in the circuit, Hyper terminal shows

""Card Initialization failed..""


If it not present in the circuit,
"SD card not detected.. "


Serial communication and Hyper Terminal running well. Where should the probable problems? Thank You Sir.

CC Dharmani said...

You can try again with a 3.3v regulator like LM1117-3.3 or you can make one with easily available LM317 variable regulator. A power supply using voltage divider can make a good reason for card initialization failure.

Anonymous said...

Sir
Thanks for your response.
I am trying for 4 days, came to a conclusion that Regulator is not the problem in my circuit. I have tried with different sources, battery at different volt. (also tried separate source of power for card, off-course ground common, used Atmega32l )

Memory card is ok, can be read by card reader/pc.

hyper terminal is ok too. I have just trapped! cant understand why it is not happening!
any other tips?

CC Dharmani said...

If the power supply is clean, next thing you can try is to use pull-up resistors on data lines of the SD card. Also, use pull-ups on all the unused pins of the SD, too. You can use resistor values of 10k to 100k.

Henry said...

Well, I don't know about the Toshiba 128MB SCSD card, but what I found is that for some card, I have to assert and deassert the CS SD_CS_DEASSERT within the loop of
CMD55 and ACMD41. And according to the SD spec, this retry needs to be a 1 second long retry.

James said...

Hi,Dharmani, I found there is a bug in your code, if I unsigned char data[m]= {0,1,2,3......510,511,'~'}; buffer[i++]=data[m]; m++;
fileSize++; then at the end of this file, it always shows "error in getting cluster".
Then I tried another way, unsigned char data[m] = {0,1,2,3.....510,'~'}; buffer[i++]=data[m]; m++; fileSize++; and change the code a little bit to be if (data[m]== '~') {fileSize++, error = SD_writeSingleBlock(startBlock);
it also shows "error in getting cluster".
Do you know how to fix this problem?

James said...

Continue, Last time I consult with you how to increased the writting speed of FAT32, U told me write more data instead of just one piece once, I format 2G normal SD card into 512 and I intend to fill full of 512 buffer and transfer to SD card, however, if buffer[511] is '~', since ur code '~' will fileSize--; so only 510 bytes are recorded into SD once, and takes long time to setNextCluster if there is more and more data, the writting speed will slow down. so I changed it to be fileSize++ instead of --, however, in your code, the last one cannot be the writeSingleBlock function, otherwise, the file cannot be opened because error in getting cluster, really wish to solve this problem, Cheers

AX said...

Hi CC Dharmani,

This is a fantastic project! I am trying to adapt the writeFile function to write special files that is composed of a file descriptor at the beginning, followed by the data chunk. How can the function be modified so that the file can be appended (for the file descriptor that requires total bytes of the whole data) after the data chunk is written? The file descriptor has a set amount of say 44 bytes, so no data shifting is required.

Thanks in advance!
~AX

James said...

Ok, Dharmani, I found the way out, I fill 512 buffer up and then at the first byte of next coming buffer I use data = '~'; buffer[i++]= data; fileSize++; it works well. much faster than it was.

lucho said...

Hi man, great job in this matter..Just have to ask if I can use this with Atmega88?

SohaIb said...

hi CC Dharmani

hopefully u r enjoying good health :)

I found ur article on it...its impressive also said by most of ur readers.

Now, i am skipping the USART interface as i m using the graphic LCD(128*64) for user display, because i am working on hand held device so i can't connect to PC for Hyper Terminal.
I edited ur code, included LCD library & header files. Right now i m just trying to initialize the SD card successfully and after that i want to access a txt file, as i have to manage a sort of database type thing. So, i have to work on FAT32 system. The problem started when i tried to initialize 2GB SD card.
When i put 2GB card, its is not working at all, means....there is no response shown on LCD....even no initialization. :(
But later on when i put 512MB card, it is initialized successfully, then displaying "Std Cap Card v1" but then its is displaying the msg "FAT32 not found".
When there is no card, its fine that it is showing the msg "SD card not found".
I am mailing you my main C file, which is edited file of yours project.

The 2 GB card i inserted was FAT32 formatted containing no files at all.

any help regarding my problem will be really appreciated :)


Regards
SohaIb Qamar

Sagar Sojitra said...

HI....

mr.dharmani ur article is too good for us.
but i want to interface a 20*4 lcd and a 4*4 keypad with atmega 32 and i want to store the data so can u help me with schematic ......
plz sir help me....

SohaIb said...

hi all....is there anybody to help regarding my above mentioned problem...m still stuck there....

Regards
SohaIb Qamar

CC Dharmani said...

Hi Sohaib,

was little busy, hence late response.

the problem which you are facing comes mainly from the hardware side, as I've heard about the same problem faced by some other people, too.

What you can try is:

- Do not leave any pin of the SD card unconnected, use pull-up resistors on any unused pin (resistor value can be around 50k)

- Try to use reduced clock speed first. Initially you can use 1MHz clock for the microcontroller, which can be increaded to 16MHz once you solve the hardware problems

- If you are using any interrupts, which can disturb SPI communication, disable them while data transfer on SPI bus

- If you are using any series resistors on SPI bus, try to access card without them. For example, if you are using voltage divider for 5v-3.3v conversion, try to use 3.3v supply for controller and card both, to get rid of those resistors. Alternatively, you can use a buffer IC for level conversion. As per my experience, the resistors on the SPI lines limit the speed and may result in failure of card initialization at higher clock frequency

- don't use voltage divider resistors for VCC of the card, use a stable power supply instead (like a voltage regulator chip)

- If you still get problem, try to use microSD card instead of SD, as most users who use microSD cards have not faced such problems

Do let us know the progress.

NIkunj said...

thnks for th sharing of this important link but i want to display th performance on GLCD.. can you pl help me..

SohaIb said...

@CC Dharmani thanks for the reply ....

also its a good news for me....:)
i used dual power supply, 5V for ATMEGA32 & graphic lcd & 3.3V for micro SD card...& it works...
512MB card is detected, RAW data write successfull...also if i format the card, its not showing the msg "FAT32 not found" which means FAT32 is working fine....but 2GB card is detected as High Cap Card...i have plugged in the FAT32 formatted 2GB micro SD card, RAW data write operation is also failed & its is showing the msg that "FAT32 not found"....

i need some more suggestions for the 2 GB card to work successfully :)
thanks again for ur precious time to spare for my problem & giving the detailed reply. looking forward for the positive response.

Regards
SohaIb Qamar

Sagar Sojitra said...

hi mr. dharmani and evryone

i want to interface a 20*4 lcd ,4*4 keypad with atmega 32.and i want to store inputs given by keypad to sd card with time and date so pls help me for that this is very imp for my semester project.........

Alexandre said...

Thank you very much for your work
I have a question:
Have you any idea how to use long names from your software?
thank you in advance

Eliza said...

Hi,
Dharmani Sir
Like "Bharat",I am also doing a project in which I am interfacing a microSD card with ATMEGA32 to store the on field data.
But instead of using a Hyperterminal to enter data I am trying to give the input from the microcontroller itself.You have said in the reply to Bharat's post that you are soon going to modify your code for that purpose.I want to ask have you uploaded it here?If not please mail it to me at
eliz12330@yahoo.com
Thanks a lot.

Eliza said...

Hi,
I had some other queries too.
1.I am confused whether Atmega32 has an internal crystal of 1MHz or of 8MHz?
2.What should be the voltage at the four SPI lines(MOSI,MISO,SCK,SS) while SD card is being read or written?
Thanx.

Eliza said...

Hi,
What does this instruction do?
#define SD_CS_ASSERT PORTB |=~0x02
I am rite guessing that it is assigning PB.2 of ATmega8 as SS pin?
If so this would be
#define SD_CS_ASSERT PORTB |=~0x04
for ATmega32 in which SS is atPB.4?
I hope I am not irritating you with my repeated posts...
Waiting for your reply
Thanx.

jadin jousche said...

@eliza :if you want to enter your field by the microcontroller itself,you can modify the writeFile() function and edit the portion where it prompts for the data from the hyperterminal.i did a similar project by removing thia portion of the code and inserting my data here in this function and including a "~" (end of file) character after every data logging..i hope you got my idea.

for the voltage levels in the SPI ports,only the SS,MOSI and CLK pins to be at the 3v3 level..

CC Dharmani said...

@Eliza:
Sorry for delayed response.

I've modified the FAT library to make it independent of hyper terminal. User can decide what to use for data entry in the main function itself. It's found working perfectly in my initial testings. I didn't post it here as I wanted some more tests to complete, but got little too busy to do it. I'll mail the library to you with an example project.
Other way is to modify the writeFile function as suggested by Jadin in the previous comment.

Regarding your queries:
1. Mega32 has internal oscillator which can be set to any of these four values depending on the fuse settings: 1MHz, 2MHz, 4MHz & 8MHz. Refer to the datasheet's 'memory programming' section for more details on fuse settings.
2. During the card read/write, the SPI pins' voltage levels can vary depending on the data, as the multimeter shows only an averaged DC value and all the SPI pins keep changing the values too fast to observe on a multimeter. Oscilloscope would be better for monitoring these signals as it gives the details of the signals (and hence, the data)
3. It is not mandatory to use SS pin of the controller for CS (chip select) signal of the card. Any port pin can be used, including SS. I've given two options in header files: either PB1 or SS pin can be used and relevent macro should be selected, as mentioned in the comments above each of the SD_CS_ASSERT / DEASSERT sets of mcaros.

Sameer said...

Thanks for sharing :)

Anonymous said...

Hi Dharmani,
How to read Raw Data off an SD card using PC(windows)?
Thanks.

CC Dharmani said...

You can use HxD Hex Editor for viewing raw data from any card or disk using a PC. It can be downloaded from this link: http://mh-nexus.de/en/hxd/

eliza said...

Hi,
Dharmani sir,
As I have described in my email to you(from eliz12330@yahoo.com)that I am working on a project in which I have to write to SD card the data which is present in the data registers of ATmega32 i.e. without using Hyperterminal or any other input device like Matrix.
I have modified the code accordingly.I have deleted the FAT32 and UART portion of the project.
The main issue is in the SD_init() function.The issue is that when I debug it in AVR studio 4 using single step, it does not read the lines of code after the line
"response = SD_sendCommand(GO_IDLE_STATE, 0);"
It immediately finishes and comes out of the program.
I am sending you the code at your email address.Please have a look at it.
Waiting for your reply.
Thanks.

Gregi P. said...

Like the others, I like this project, too.
But I haven't found the eagle shematic-files.

Do you have any download for them or do we have to redraw it from the jpgs?

Thanks in advance.

CC Dharmani said...

@Gregi: Thanks for the suggestion, EAGLE schematic added now!

Anonymous said...

Dear sir,
I am using your code with msp430x1611 and it works fine for 1GB card.If i use the same code with 2GB card (Sand disk / Transcend) it is responding with '1' for GO_IDLE_STATE command and for SEND_OP_COND command it is responding with higher value other than zero.If you use SEND_IF_COND,then 1 is not returned ,254 ...etc are received even after trying multiple times.Kindly respond.My mail id is
madhurao1@indiatimes.com

Thomas said...

Hi Mr Dharmani,

your code works fine: Everything is connected and I can read and write single blocks. Given files are displayed correctly. But when it comes to writing a file the routine gets stuck after entering the escape character. Any hints for me?

FYI: It's the original 2.4.1 code, just the CS-pin has been altered to B2. It's an Atmega32 at 8 Mhz and 2 gb uSD.

PS: I read all comments and also found this question before, but no answer to it :( Maybe I overread it, but I tried hard :)

CC Dharmani said...

Hi Thomas,
the main reason I've found for getting stuck up in the writeFile function is the RTC routines. If the RTC hardware is not connected or not working, the function gets stuck up while trying to receive the date/time for writing in the FAT.
You can confirm this by just removing the following lines:

error = getDateTime_FAT();
if(error) { dateFAT = 0; timeFAT = 0;}

and instead of them, simply use this one:
dateFAT = 0; timeFAT = 0;

this will stop the function calling RTC routine (due to this the file creation time will not be recorded, but the file will be created and can be seen using PC).

Thomas said...

It worked. Thank you very much for your response and help! Awesome work! Thanks

Anonymous said...

Hi Mr. Dharmani

My ATMega8L would not work on 3.3 volts. But when power is raised to 5 volts I can see your name and the options on Hyper Terminal.

bil_gato1357 said...

Thanks for the code.I was able to make it work on 3.3 volts ATMega8L using external oscillator.

Anonymous said...

Hi...
I constructed the circuit and loaded atmega32 with ver2.4.1. I tried it out with a new 2GB card formatted and loaded with a text file. The card is Sandisk make. It always says SD card not detected.I have a small project in hand which requires SD card interface. Im looking for somebody who can help me.It would be great if u could contact me through mail/ phone.mail id is miclub@rediffmaii.com

Anonymous said...

Hello Dharmani,

I formatted SD Card, as per FAT32, i tested the code on AtMega1284, but i am getting an error FAT32 not found. The card is definately getting initiated.

Please suggest, what could be the cause!

Varun said...

Mr Dharmani,
I am very inspired by your work(I have worked on SD card and RTC interfacing described by you) and I wanted to make my own board(through proper pcb manufacturing)...I have the schematics and gerber files with me...I wanted to know if there are any small scale PCB manufacturers who could take orders of 3-5 pcbs..

CC Dharmani said...

Hi Varun, it depends on your location. In Chennai, I've been using services of "Printed Circuit Boards" at Thiruvanmiyur, near IIT-Chennai. They take small orders of 2-3 PCBs, too.

Varun said...

Sir what is the pricing for these developement boards if i get only the pcbs made and solder the components by myself...give me a rough idea..please..

CC Dharmani said...

Well, it depends on size of the PCB and layers. A double layer PCB with 3"x4" size costs around 600-700 Rs. for 3 PCBs. Any subsequent PCB of the same gerber files would usually cost 50-100 Rs. per PCB.

Monty said...

Hello!

I've been trying to get my ATMEGA16 to work with your code Version 2.2. So far, the card initializes correctly but it never finds FAT32. The card I'm using is a 2GB SD, which I've reformatted with different sector sizes but it's always the same. I have wired my SD card socket exactly the same as on your scheme - the only difference is, that my pull-up resistors are of value 51.7k. Oh, my multimeter shows, that voltage level on PIN 4 of SD card is around 3.26V - could this be the problem?

I've found out, that function SD_readSingleBlock(0) in getBootSectorData() always returns value 1 instead of 0. It seems as reading is not working at all.

I'd be very glad if you could give any advice. Thanks.

CC Dharmani said...

Hi Monty, the pull-ups you have are ok, you can also try without any pull-up resistors, as most microSD cards work without them, too. They are necessary mainly for SD cards.
Format the card with default windows settings (FAT32, sector size of 512 bytes, cluster size can be variable - default is 4096 bytes), as this code is written for sector size of 512 bytes.
You can also try the version 2.3 code.

Monty said...

Thank you for your reply.

I've tried using version 2.3 of your code, reconnected the MISO connection (since reading doesn't work) and I still haven't had any success.

I have successfully written data on sector 1 and checked it with hex editor, therefore only reading from the card is an issue.

Do you have any other suggestions? Should I try with another size/type/brand of SD card?

Thank you.

Monty said...

Can really no one help me?

I've found out that the card responds to READ_SINGLE_BLOCK command with 0x00, so that's okay. Then, it's stuck in a loop waiting for response 0xFE...but the response is always 0xFF. Please help.

CC Dharmani said...

Give it a try with another card and see if it works.

Monty said...

I've tried just that.

SanDisk microSD 1GB - card not initialized

Transcend microSDHC 8GB - everything worked just fine.

Thanks for help.

amitpj said...

HI

I am working with Freescale 68HC12 using your code ...
i have read sector and also able to write but i am not able to write in fat32 so help me please
this is my email id amit.pujar@st.com

Avni said...

can we use ATmega32A inplace of Atmega32L


Ashish

CC Dharmani said...

@Ashish:
ATmega32a is a drop-in replacement for ATmega32. This code will definitely work for ATmega32a without any change in the software or hardware.

Avni said...

Hello,
Mr. Dharmani


ATmega32 operating at 5v and we have to use 3v operated controller for for that we have used Atmega31A in place of Atmega32L

I doing project Using TFT lcd and we have to store immage into sd card.
And your project is very usefull for us.
First we are new one for AVR controller before this one we have used 8051 controller Atmel and Philips make.
so for that i m using your source code v2.3 for interfacing sd card.
we have Atmega32A chip.
Also we are using ELNEC programmer and that have ISP facility.
But during Download *.hex file geeting error.
All circuit connection are same but just we have open sd card portion and Max 232 chip.

Can we use ATmega32A inplace of ATmega32L?

Avni said...

Also one more point we have connect +3v supply for 6pin Isp connector.

V2.3 circuit Diagram showing only Gnd connection and using 5 pin.

so, how can we solve error?
we are waiting for your reply.

Ashish

Avni said...

Hello,Sir


I m new one for Avr controller.So confused and there is no response from the hyperterminal even only INT0 Pin LED is going ON.In Hyperteminal first we have selected port setting option bit per rate is 19200,data bit 8,
parity none,stop bits 1,flow control none.

We have used your make *.Hex file from Version 2.3 source code.

so, Where is my mistake?


Ashish




Ashish

CC Dharmani said...

Hi Aniket,
one of the purpose of SPI bus itself is to support many devices on a single bus. You can control SD card and Nokia LCD both using the same SPI signals (MISO, MOSI & SCK) of the microcontroller, just make sure you use two different port pins for Chip-Select signals of both the devices. When you want to transfer data to a device, enable only that chip-select pin. This way you can connect multiple SPI devices on the same bus.

You can go thru any nice article on net about SPI bus, you'll get this thing discussed in detail.

Anonymous said...

Hello sir,
Can I use 10uf capacitors in the rs 232 interface...please advice!

Avni said...

Thanks for your fevourable reply to Ashish at first point.

And we have done successfully.
Also hardware is working with Hyperterminal.There was little mistake at our hand.
we have used 16MHZ crystal And set boudrate level 19200.so didn't do.
And then after we change crystal oscillator 8MHZ And connected.

now a days we have to store *.JPEG Image file into sdcard.
is it possible?

Regards,
Avni Modi

amitpj said...

hi cc dharmani...
my project is working but the problem is when i write with using fat32 it will write in memory and when i read it.it will read correctly

but when i remove that card from my hardware and put to pc there i will get that text but when i click on that it will say the file or directory is corrupted and unreadable .......so please help me..

Binod said...

hello sir,
I am try to read a txt file from mmc card and and record a voice and play it.But I have a problem in simulation in proteus.I didn't get what is "card image file".what is to be loaded in proteus card image file.what should the card image file must contain..
hope to get your answwer

santhosh said...

hi CC Dharmani sir,
this is santhosh from singapore
i want to interface a sd card to the temperature data logger using PIC12f683.
can you guid me on it
the data logger is working ok but i want to know how to interface the PIC12f683 with SD card

below ling shows my circuit link

http://embedded-lab.com/blog/wp-content/uploads/2011/04/DataLoggerPIC12F683.png

Anonymous said...

Hi CC Dharmani,

thank you very much for your work, it helped me very much with my project.

I now tried to update to SDHC support and have a question on your SD card initialisation:

In line 102 in "SD_routines.c", you check the SDHC flag, but I can not find the line, where you possible set the flag to 1. Before the loop, you set the flag to 0 and never change it, or do I forget anything?

I hope, you can help me
Greetings, Balder

gaja said...

hi SIR,
I am interfacing my SDHC card with PIC16F876A controller.I am not coming out of idle state means not getting 0x00 response to ACMD41 command so cant proceed further.Please help me to get of it. please.

Iqbal Habibie said...

hi nice to meet you. well i have EMS SD/MMC FARM is it the same used as you using with? I'm trying to use SD Card in this modul to DT AVR Low Cost Micro System. Can you help me?

- Paul said...

Thanks so much for posting all this. I'm having some problems with a larger embedded project that uses SD as a file system, based Chan's code. The volume opens but it can't find files. All the signals look clean on a scope, so I'm planning to add terminal output to help track that problem down. Your design will help me accomplish that and I may just switch to your FAT library as well. Wish I had thought of the trick of modifying an SD adapter as a connector! I was silly and bought an SD push/pop connector instead. Surface mount. Not easy to work with, especially in a breadboard. :-)

Paul said...

I forgot I had a question. Can I talk you into posting either a higher res picture of the Atmega8 schematic, or maybe an EAGLE or EXPRESS file?

NIkunj said...

sir i had read the file using your code but i could not write the file in to MSD. my main purpose is to make a file without using keyboard, content of the file i am giving directly from the program.
please if you can tell the points of which must be taken care during writing file.
waiting for your reply
thanks in advance.

NIkunj said...

i'm getting CRC error.. please if you can let me know what shoud i do..?

NIkunj said...

i'm getting th error of time out for some card and some times flags are not set.. can you please tell me what can be the problem.. let me know ASAP..

yogesh gupta said...

sir, i am making a project and i am using the sd card interfacing along with the LCD DISPLAY .BUT SIR . IN ATMEGA32 there is only one SPI . AND we need atleast three spi . tell me sir, how can i do this possible . your suggestion will be very helpful for me.
hope for ur answer.

NIkunj said...

thank you sir for providing such a useful information..
it worked..

NIkunj said...

to yogesh gupta,
use different chip select pin for the three pin and u will be able to perform..
best luck..

krp.eee said...

Error to simulate your hex in proteus,

it said "Error at 507 line it expect 0xFF but there is 0xFE"

did anyone used this hex successfully?

krp.eee said...

i download your code for m32 and
I tried to simulate it in proteus for mega32 but it traped here infinitely

while(!(SPSR & (1<<SPIF)));


i think then will not run in real circuit.
any solution?

krp.eee said...

then please inform me

krp.eee@gmail.com

krp.eee said...

i download your code for m32 and
I tried to simulate it in proteus for mega32 but it traped here infinitely

while(!(SPSR & (1<<SPIF)));


i think then will not run in real circuit.
any solution?
besides circuit diagram has crystal of 16Mhz, and in code it is internal 8Mhz, whic is true?

Ryan Carvalho said...

I would like to know how to set the time in 12 hrs format in the RTC library. Then i need to diplay am or pm accordingly. Im actually just trying to display time from the RTC only.Dont need any other hardware like the MMC card etc. Ive looked up all the libraries you have but its not implemented. Can you kindly help? .
I understand that we need to set Bit 6 in the HRS register for the DS1307 but somehow i cant get it to work

Monkey D luffy said...

thank you...Just in time for me..

Anonymous said...

Really great job!

I've got two questions. First, maybe trivial - can I read files (list files) inside directories? And second - is there any chance to handle long file names?

thanks again
best regards

bil_gato1357 said...

Thank you very much Mr. Dharmani for your works and links. I learned a lot and able to read files from SD card. This is my project:

http://www.youtube.com/watch?v=7HYUhdOpEIM

Anonymous said...

This is good

For micro-controller program and experiment follow me also @

www.pradipyadav.com

rinki arora said...

how to calculate the value of variable for delay tht u used in ur every program in this case value of j
for(i=0;i<millisec;i++)//16Mhz
{
for(j=0;j<1550;j++)
{
asm("nop");
asm("nop");
}


}

torenz said...

can I ask for examples sdcard datalogger program with cvavr?

or can I ask for references for it?

thanks

Anonymous said...

I use HyperTerminal. Hardwear is work fine but i have problem with save data to memory card. I pick number 7 and write FILETEST.TXT ... and i have something like that:

"Enter file name: FILETEST.TXT
FILETEST.TXT
"
i push enter button and nothing happend.
Is any commend to close file name procedure ?

marek said...

I made something like that:

...

unsigned char fileName[]="INDIE.TXT";

....
while(1)
{

writeFile(fileName);
_delay_ms(2000);

}


In terminal:

appending data..
Enter text (end with ~):TestText~
File appended!
Invalid fileName..Invalid fileName..Invalid fileName..

What's wrong?

Anonymous said...

I want to interface SD card to replace e2prom for my project.So,I need to know difference between sd card and e2prom interfacing API's.and I,also want it with/without using bat32.It will be so great if you help me.

Mas Sandi said...

great job....mr...

i`ll try to do it...completly..

Mas Sandi said...

great job....mr...

i`ll try to do it...completly..

abhilash bidari said...

hi,

i have interfaced this sd card code to LPC1227. Iam able to detect the sd card, I can create the file, i can write. But when i connect this sd card my laptop/pc. it is not showing any file in the sd card. Please help me

abhilash bidari said...

hi,

BS_Structure will create one hole in the structure after the below two variables.
unsigned char jumpBoot[3]; //default: 0x009000EB
unsigned char OEMName[8];

Because last element of OEMName ends with even address. So the next variable "unsigned int bytesPerSector; //default: 512" wont start in next odd address. It will start at even address (known thing). So this will create the hole in the structure.

You wont get proper values after calling "getBootSectorData" function.

So it is better to pack the structure properly by giving the compiler related #pragma.

Nhivekar said...

When i compile the given code for Atmega8 then compiler-Vmlab give error device memory exceed.

Asif said...

Hi Dharmani,

Hope so you are best of your health and job.
Currently i have only one problem that the file i write does not exceed in size more than 4KB by writing data into it.
Can u please help me where i need to focus to solve this problem..
YOUR help in this regard will be highly appropriated.

Thanking YOU in anticipation.

Kind Regards
Asif

Raquelle said...

I find your work really great which i can use for my project.. Im also new with this so thanks for providing everything.. Further question, Do you think it is feasible if im going to use PIC18F rather than atmeg? and also, trying to keep track of what's happening in an LCD together with push buttons for input rather than connecting it to PC.. well the focus of my project is make a stand alone device for file transfer in SD cards.. Thank you in advance.. Hope to hear from you asap..

Phuc Nguyen Cong said...

This is very useful. it run okie with my AVR 128 Chip. Thanks you so much.
. But i have a problem with the readFile () function. Is it possible the file in a folder. I want to read file like this : "Sdcard/Fonts/fontA.txt" . How can i do this with readFile function. I try readFile(READ, "Fonts/fontA.txt") but it not work.
Please give me some idea to do. Thanks again.

dinesh said...

i make this n wonder when this is working goooooooooooooooooooood
realy heartly thankful for u
i salute your work
from dinesh

Anonymous said...

Here is a uSD card adaptor working on 5v.
Could be of some help on many projects.
http://www.pjrc.com/store/sd_adaptor.html

jd said...

what is that max. size of sd card that sported by spi protocol?

rogwil said...

Excellent explanation. Thanks for providing code and schematics.

ishwar padasalagi said...

hi i am working on lpc 2148 board.i want write in to 2 gb memory card .if sample program is please send my mail igp.krg@gmail.com

ROBOTRONICS with AVI said...

hi CC
your code is great. please help me with some problem.
please tell me what changes in the code i need to make if i am using a 16 MHz external crystal with atmega16.
I am ok with the fuse bit. I want to know for the changes in the code (especially in UART.c) i will have to make

CC Dharmani said...

for 16 MHz, no need to change anything in the code. Just double the baudrate in the HyperTerminal which you are using to communicate. i.e. it's 19200 with 8 MHz, make it 38400 when you use 16 MHz. Rest of the things will fit in automatically.

Hüseyin Taşdöven said...

Hi CC,
I have encountered a problem with writing to file.
File corrupts when after writing to start of a new cluster.
I tested cluster size of 1024.

Can you look the code in the FAT32.c?

Hüseyin Taşdöven said...

The problem is solved...
Your original code is right and reliable.
Thanks a lot Dharmani...

Hüseyin Taşdöven said...

Hi Dharmani,
when filesize get bigger it takes long time to write to file. what is it's cause? Is there any solution for this?

«Oldest ‹Older   401 – 600 of 699   Newer› Newest»