Watch the video Tutorial: Connection

Memory Cards

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
–> Microdrive
–> 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 Cards                      

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.

SD Card pins

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.

SD cards can be interfaced to microcontrollers using two different protocols: The SD card protocol and the SPI protocol. The SPI protocol is the most commonly used protocol at the momemt. In this tutorial, we will use the SPI protocol.
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.

SD card connected in SPI mode to Port C of PIC Microcontroller

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). Figure 4 below shows an SD Card connected to PIC18F45K22

Interfacing SD Card to PIC18F45K22

Figure 4: Interfacing SD Card with PIC18F45K22

Chan’s FatFs Library 

Reading and writing onto SD cards is very complex and requires some complex functions and procedures to handle the card Input/Output operations correctly. For those who don’t want to fully understand the internal operation of SD cards, there are many SD card libraries that one can use. Microchip Libraries for Applications File I/O (Memory Disk Drive) is no longer supported for 8-bit PIC microcontrollers (PIC16F & PIC18F) at the moment version 1.02. This version is intended for 16-bit PIC microcontrollers (PIC24 & dsPIC33). The last 8-bit supported version (MDD v1.44) was in Microchip Libraries for Applications v2013-06-15. The problem this library files were made for the old MPLAB 8 compiler and it is a hassle to make them work with the new MPLAB X. In this article, we are going to use the popular Chan’s FatFs Generic FAT File System Module.

Watch the video Tutorial: FatFs Library

The FatFs is a generic FAT file system, is a fully free FAT implementation in the form of a library and application interface module, destined to small embedded systems. The FatFs module is written in compliance with ANSI C (C89) and completely separated from the disk I/O layer. Therefore it is independent of the platform. It can be incorporated into small microcontrollers with limited resource, such as 8051, PIC, AVR, ARM, Z80, 78K and etc. Also there is Petit FatFs module for tiny microcontrollers (RAM: 44 bytes work area + certain stack, code size: 2K-4K bytes).  Chan’s FatFs Generic FAT File System Module Website, has plenty resources that can help you understand this library: Examples for different microcontrollers, help files, functions description etc.

Description of Some FatFs functions

f_mount
This function Register/Unregister a work area (mount SD Card). This function must always be called before any other file functions except for f_fdisk function
Parameters:
File system object: Pointer to the file system object to be registered and cleared. Null pointer unregisters the registered file system object. example: FATFS FatFs
Logical drive number: Pointer to the null-terminated string that specifies the logical drive. The string without drive number means the default drive. example: “” for default driver.
Initialization option: 0: Do not mount now (to be mounted later), 1: Force mounted the volume to check if the FAT volume is ready to work.
Return Values: When a function succeeded, it returns zero, otherwise returns non-zero value that indicates type of error. FR_OK (0: The function succeeded.), FR_INVALID_DRIVE, FR_DISK_ERR, FR_NOT_READY, FR_NO_FILESYSTEM
Example:

f_open
This function Open/Create a file.
Parameters:
File object structure:Pointer to the blank file object structure. Example: FIL Fil
File name: Pointer to the null-terminated string that specifies the file name to open or create. Example: “test.txt”
Mode flags: specifies the type of access and open method for the file. It is specified by a combination of following flags:

  • FA_OPEN_ALWAYS: Opens the file if it is existing. If not, a new file will be created.
  • FA_READ: Data can be read from the file.
  • FA_WRITE: Data can be written to the file. Combine with FA_READ for read-write access.
  • FA_CREATE_NEW: Creates a new file. The function fails if the file is existing.
  • FA_CREATE_ALWAYS: Creates a new file. If the file is existing, it will be truncated and overwritten.
  • FA_OPEN_EXISTING: Opens the file. The function fails if the file is not existing. (Default)

Return Values: When a function succeeded, it returns zero, otherwise returns non-zero value that indicates type of error. FR_OK (0: The function succeeded.)
Example:

f_read
This function reads data from a file
Parameters: FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br);
File object: Pointer to the open file object.
buffer: Pointer to the buffer to store read data.
btr: Number of bytes to read in range of UINT type.
br: Pointer to the UINT variable to return number of bytes read. The value is always valid after the function call regardless of the result.
Return Values: When a function succeeded, it returns zero, otherwise returns non-zero value that indicates type of error. FR_OK (0: The function succeeded.)
f_write
This function writes data to a file.
Parameters: FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw);
fp: Pointer to the open file object structure.
buff: Pointer to the data to be written.
btw: Specifies number of bytes to write in range of UINT type.
bw: Pointer to the UINT variable to return the number of bytes written. The value is always valid after the function call regardless of the result.
Example:

f_lseek
This function moves the file read/write pointer of an open file object. It can also be used to expand the file size (cluster pre-allocation).
Parameters: FRESULT f_lseek (FIL* fp, DWORD ofs);
fp: Pointer to the open file object.
ofs: Byte offset from top of the file.
f_gets
This function reads a string from the file.
TCHAR* f_gets (
TCHAR* buff, /* [OUT] Read buffer */
int len, /* [IN] Size of the read buffer */
FIL* fp /* [IN] File object */
);
f_putc
This funciton puts a character to the file.
int f_putc (
TCHAR chr, /* [IN] A character to put */
FIL* fp /* [IN] File object */
);
f_puts
This function writes a string to the file.
int f_puts (
const TCHAR* str, /* [IN] String */
FIL* fp /* [IN] File object */
);
f_printf
This function writes formatted string to the file.
int f_printf (
FIL* fp, /* [IN] File object */
const TCHAR* fmt, /* [IN] Format stirng */

);
f_size
This function gets the size of a file.
DWORD f_size (
FIL* fp /* [IN] File object */
);
f_close
This function closes an open file.
FRESULT f_close (
FIL* fp /* [IN] Pointer to the file object */
);
More details can be obtained from the  popular Chan’s FatFs Generic FAT File System Module. website.

The Disk I/O Interface

Since the FatFs module is completely separated from the disk I/O layer, it requires at least the following
functions to access the physical media:
• disk_initialize – Initialize disk drive
• disk_status – Get disk status
• disk_read – Read sector(s)
• disk_write – Write sector(s)
• disk_ioctl – Control device dependent features
• get_fattime – Get current time
The low level disk I/O module is not a part of FatFs module so that it must be provided by user these are the SPI bus communication routines. These are configured in diskio.h file.
There are many options to configure the functions of FatFs for each project. The configuration options are defined in the ffconf.h.

Watch the video Tutorial: Code

The figure 5 below is shows the main.c file. A file “test.txt” is created, open and a text message is written into it: “Hello world! This is text message written to sd card” .

You can download the full project files (MPLAB XC8 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).

Download Mplab X Project: SD_Card_FatFs