SD Card byte/sector read and write with PIC18F4550 – CCS C

Interfacing PIC18F4550 with SD card

With the help of the small driver of the MMC/SD cards we can easily read and write any sector and any byte located in the media. First download the SD card driver from the topic below and after the download put the file sdcard.c in the project folder:
MMC/SD Card driver for CCS PIC C compiler

In this project a 8 GB SDHC card is used (SD card capacity is not important), the SD card is connected to the PIC18F4550 microcontroller via hardware SPI and the microcontroller runs with a frequency of 48MHz (8MHz with PLL). Circuit schematic is shown below.

Hardware Required:

  • PIC18F4550 microcontroller
  • SD Card
  • AMS1117 3.3V voltage regulator
  • 8MHz crystal oscillator
  • 2 x 22pF ceramic capacitor
  • 3 x 3.3K ohm resistor
  • 3 x 2.2K ohm resistor
  • 10K ohm resistor
  • 100nF ceramic capacitor
  • MAX232
  • 5 x 10uF polarized capacitor
  • Female COM port
  • 5V Power source
  • Breadboard
  • Jumper wires
PIC18F4550 SD card interfacing circuit

As known the SD card voltage is 3.3V and the PIC18F4550 voltage is 5V, so AMS1117 3.3V is used to step down the 5V in order to supply our SD card. Also the outputs of the PIC18F4550 are logic 0 (0V) or logic 1 (5V) and connecting the microcontroller output pins (CS , SDO and SCK) directly to the SD card will damage it, here a voltage divider is used to get about 3V from the 5V which is enough for the SD card. The voltage divider consists of 3.3K and 2.2 K resistors. The MISO is connected directly to the SDI pin of the microcontroller because it is the data output pin of the SD card which is normally does not exceed 3.3V.
The MAX232 is used to interface our microcontroller with PC via serial port as what was done in this topic:
CCS C UART example for PIC18F4550 microcontroller

I used just one wire (RD2) to transmit data from the microcontroller to the PC (there is no need for the MCU to receive data so the receiving wire is not connected).
The chip select pin of the SD card is connected to pin RD3 (the SD card chip select pin is active low).
It is recommended to use voltage level translator (level shifter) instead of the voltage divider if it is available. The level translator translates the 5V to 3.3V for CS (SS), SDO (MOSI), and SCK and translates the 3.3V of MISO to 5V (PIC18F4550 SDI is an input with Schmitt buffer which needs 0.8VDD for high input). For example we can use chips like 74LVC04 (hex NOT) or 74LVC125A (quadruple buffer) to go from 5V to 3.3V and 74HCT245 to go from 3.3V to 5V.
For my hardware circuit I used both the level translator using 74LVC04 and74HCT245 and also the voltage divider using resistors as shown in the circuit schematic above, both circuits worked very well.

SD Card byte/sector read and write with PIC18F4550 microcontroller CCS C code:
This is our example C code, this code was tested with versions 5.051 and 5.070.
The microcontroller runs at 48MHz (8MHz + PLL).
The MMC/SD card driver file must be added as mentioned above. This example is tested in real hardware circuit as well as simulation using Proteus ISIS. After writing sectors or bytes you can check it with some softwares like: Hex Workshop, HxD Hex editor……
Before you test your hardware circuit make sure that your MMC/SD card does not contain any important files!

After building circuit and code I get a result as shown in this video:

I opened the SD card with HxD Hex editor and I found sector 0 and sector 3 as shown below.
This is sector 0:

SD card read sector PIC18F4550

And this is sector 3 where the underlined byte which has address 0x700 is caused by the write_byte function:

SD card write sector PIC18F4550

As we can see sector 0 and sector 3 data are the same except byte 0x700, so what I did is I read all sector 0 data (512 bytes) and then I wrote these data into sector 3 and finally I wrote byte 0x700 with the value of byte 0x00 which I read in the first function (read_byte).

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.