Interfacing SD Card With PIC Microcontroller – MikroC
Watch the video Tutorial part 1:
A memory card (also called a flash memory card) is a solid-state electronic data storage device used for storing digital information. They are commonly used in many electronic devices, including digital cameras, mobile phones, laptop computers, MP3 players etc.
They are small, re-writable and are able to retain data without power.
This ability to retain data and the ability to re-write many times is the key for flash memory card applications, for example, in digital cameras, where the saved pictures are not lost after the memory card is removed from the camera.
There are many different types of memory cards available in the market today. Some of the most commonly known memory cards are:
- Smart media (SM) card
- Multimedia card (MMC)
- Compact flash (CF) card
- Memory stick (MS) card
- xD card
- Secure digital (SD) card: SD cards are the most widely used memory cards today. They are based on MMC and in terms of functionality they are the same ( except that the SD has an optional encryption feature). The SD are physically thicker than MMCs and would not fit into MMC slots. The MMC, on the other hand, can be easily inserted into SD card slots.
SD cards are available in three different sizes: normal SD, miniSD, and microSD as shown on figure 1 below:
SD Card MiniSD MicroSD
Figure 1: SD Cards
Table 1: Technical Properties of Memory Cards
Note: The new SDXC Cards have capacity up to 2TB.
Most SD cards and MMCs particularly those sized below 2 gigabytes (GBs), use the FAT16 standard.
The FAT32 standard can be used to address memory sized between 2 gigabytes and 2 terabytes.
SD Card Pin Configuration
The card has nine pins, as shown in the figure 2 below, and a write-protect switch to enable/disable writing onto the card.
Figure 2: SD Card pins
A standard SD card can be operated in two modes: the SD Bus mode and the SPI Bus mode.
In SD Bus mode, all the pins of the card are used, data is transferred using four pins (D0–D3), a clock (CLK) pin, and a command line (CMD).
In SPI Bus mode using a chip select (CS) and a CLK line. The following pins are used in SPI Bus mode:
- Chip select: Pin 1
- Data in: Pin 2
- Clock: Pin 5
- Data out: Pin 7
- Positive: Pin 4
- Ground: Pin 3 and 6
The Card operates with 3.3V supply voltage and these are the logic levels:
Maximum logic 0 output voltage, VOL = 0.4125 V
Minimum required logic 1 input voltage, VIH = 2.0625 V
Maximum logic 1 input voltage = 3.6 V
Maximum required logic 0 input voltage, VIL = 0.825 V
When connected to a PIC microcontroller, the output voltage (2.475 V) of the SD card to the PIC is enough to drive the input circuit of the microcontroller, but the typical logic 1 output voltage of a PIC microcontroller pin is 4.3 V, and this is too to apply to the card, where the maximum voltage should not exceed 3.6 V. As a result of this, it is required to use resistors at the inputs of the SD card to lower the input voltage.
Figure 3 below shows a typical SD card interface to a PIC microcontroller in SPI mode. In this figure, 2.2K and 3.3K resistors are used as a potential divider circuit to lower the SD card input voltage to approximately 2.48 V, as shown below.
SD card input voltage = 4.3 V × 3.3 K / (2.2 K + 3.3 K) = 2.48 V.
Figure 3: SD card connected in SPI mode to Port C of PIC Microcontroller.
SD cards can consume up to 100–200 mA while reading or writing onto the card. This is usually a high current, and an appropriate voltage regulator capable of supplying the required current must be used in the design.
The card consumes approximately 150 μA in sleep (the card goes automatically in sleep mode if it doesn’t receive any command in 5ms).
Watch the video Tutorial part 2:
MikroC Pro for PIC Multimedia Card Library
Reading and writing onto SD cards is very complex and requires some complex functions and procedures to handle the card I/O operations correctly. The great news is that MikroC Pro for PIC compiler provides all these for free in Multi Media Card Library. This library is for SD Cards/MMC formatted with FAT16 or FAT only (Cards with capacity of up to 2GB). FAT32 library (for cards with capacity higher than 2GB) can be downloaded from LibStock.
For SD Cards with capacity higher than 2GB, read the article:
Figure 4 below shows how to format your MMC/SD Card with FAT16 file system.
Figure 4: Formatting MMC/SD Card with FAT16
NB: Before using this library, you must note the following:
- Routines for file handling can be used only with FAT16 file system
- Library functions create and read files from the root directory only.
- Before write operation, make sure you don’t overwrite boot or FAT sector as it could make your card on PC or digital camera unreadable. Drive mapping tools, such as WinHex, can be of a great assistance.
- Library uses SPI module for communication. The user must initialize the appropriate SPI module before using the MMC Library.
- MMC FAT 16 Library works with PIC18 family only.
Once the MMC/SD card is initialized, SPI module can be reinitialized at higher speed through SPIx_Init_Advanced routine with the following parameters:
- SPI Master
- Primary prescaler 64
- Data sampled in the middle of data output time
- Clock idle low
- Serial output data changes on transition form low to high edge
External dependencies of MMC Library
The following variable must be defined in all projects using MMC library: extern sfr sbit Mmc_Chip_Select and extern sfr sbit Mmc_Chip_Select_Direction.
Chip select pin: sbit Mmc_Chip_Select at RC2_bit; //Select RC2 as Chip Select pin.
Direction of the chip select pin: sbit Mmc_Chip_Select_Direction at TRISC2_bit;
MikroC Language SD Card Library Functions
Below is the description of some MMC FAT16 Library functions, further information can be found from MikroC Multi Media Card Library.
|Mmc_Init||Initialize the card through hardware SPI interface.
Mmc_Init needs to be called before using other functions of this library. It returns 0 if the card was detected and successfully initialized or returns 1 otherwise.
|Mmc_Read_Sector||This function reads one sector (512 bytes) from MMC card. It requires 2 parameters:
sector: card sector to be read and dbuff: buffer of minimum 512 bytes in length for data storage.
|unsigned char data;
unsigned short Sect;
Sect = Mmc_Read_Sector(10,data);
|Mmc_Write_Sector||This function writes 512 bytes of data to one MMC card sector. It requires 2 parameters: sector: card sector to be written to and dbuff: data to be written (buffer of minimum 512 bytes in length).||unsigned char data;
unsigned short Sect;
Sect = Mmc_Write_Sector(10,data);
|Mmc_Fat_Init||Initializes MMC/SD card, reads MMC/SD FAT16 boot sector and extracts necessary data needed by the library.
It returns 0 if the card was detected and successfully initialized, 1 if FAT16 boot sector was not found and 255 if MMC/SD card was not detected
|// use fat16 quick format instead of init
routine if a formatting is needed
SAMPLE_MIDDLE,_SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH); }
|Mmc_Fat_QuickFormat||Formats to FAT16 and initializes MMC/SD card.
It takes 1 parameter: mmc_fat_label: volume label (11 characters in length max).
This routine can be used instead or in conjunction with Mmc_Fat_Init routine.
|// Format and initialize MMC/SD card andMMC_FAT16 library globals
|Mmc_Fat_Assign||Assigns file for file operations (read, write, delete…). Parameters:
filename: name of the file (with extension): example: Test.TXT that should be assigned for file operations.
file_cre_attr: file creation and attributs flags:
Bit Mask Description
0 0x01 Read Only
1 0x02 Hidden
2 0x04 System
3 0x08 Volume Label
4 0x10 Subdirectory
5 0x20 Archive
6 0x40 Device (internal use only, never
found on disk)
7 0x80 File creation flag. If file does not exist
and this flag is set, a new file with
specified name will be created.
|// create file if it does not already exist
|Mmc_Fat_Reset||Reset the file pointer; opens the currently assigned file for reading. It takes 1 parameter: size: buffer to store file size to. After file has been open for reading, its size is returned through this parameter.||unsigned long size;
|Mmc_Fat_Read||Reads a byte from the currently assigned file opened for reading. Upon function execution, file pointers will be set to the next character in the file. Parameter: bdata: buffer to store read byte to.
The file must be previously assigned and opened for reading.
|Mmc_Fat_Rewrite||Opens the currently assigned file for writing.
If the file is not empty its content will be erased.
|// open file for writing Mmc_Fat_Rewrite();|
|Mmc_Fat_Append||Opens the currently assigned file for appending. Upon this function execution file pointers will be positioned after the last byte in the file, so any subsequent file write operation will start from there.||// open file for appendingMmc_Fat_Append();|
|Mmc_Fat_Write||Writes requested number of bytes to the currently assigned file opened for writing. Parameters: fdata: data to be written.
data_len: number of bytes to be written.
The file must be previously assigned and opened for writing.
|unsigned char txt = “Writing to SD Card…”;
Mmc_Fat_Write(“Writing to SD Card…”,22);
|Mmc_Fat_Delete||Deletes currently assigned file from MMC/SD card. The file must be previously assigned||// delete current file
This program opens a file called Test.TXT on the SD card and writes the string “Writing to SD Card….” to this file.
Figure 5: Interfacing SD Card with PIC18F45K22
The circuit diagram above on figure 5 shows an SD Card interfaced with PIC18F45K22.
The CS pin of the card is connected to RC2 of the PIC, Din of card to Do1 (RC5) of PIC, Do of card to Di1 (RC4) of card and CLK of card to CLK1 of PIC (RC3).
The power connections of the card are not shown here, but should be connected to the 3.3V variable regulator (U2). VDD and VSS of the pic microcontroller are not shown in the circuit diagram. VDD should be connected to +5V and VSS to GND. The MCLR is disabled in software. An 8MHz crystal oscillator is connected OSC1 and OSC2 of the PIC.
MikroC Source Code
char filename = "Test.TXT";
unsigned char txt = "Writing to SD Card...";
// MMC module connections
sbit Mmc_Chip_Select at LATC2_bit; // for writing to output pin always use latch (PIC18 family)
sbit Mmc_Chip_Select_Direction at TRISC2_bit;
ANSELC = 0; // Configure AN pins as digital
SLRCON = 0; // Configure all PORTS at the standard Slew Rate
// Initialise the SPI bus
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV16,_SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
if (Mmc_Fat_Init() == 0)
// reinitialize spi at higher speed
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
Mmc_Fat_Assign(&filename, 0x80); // Find existing file or create a new one
Mmc_Fat_Rewrite(); //Opens the currently assigned file for writing.
Mmc_Fat_Write(txt,21); //Write "Writing to SD Card..." into the file (Test.TXT)
You can download the full project files (MikroC source code and Proteus Schematic design) below here.
All the files are zipped, you will need to unzip them (Download a free version of the Winzip utility to unzip files).