Tuesday, August 22, 2017

Read text file from SD card with FAT16 file system using PIC16F877A


Interfacing PIC16F877A with FAT16 SD card
Using MMC/SD card driver and FAT16 library for CCS C compiler we can read files from FAT16 formatted SD card using SPI protocol.
This topic shows how to read and display a text file from SD card using PIC16F877A microcontroller and CCS PIC C compiler.
UART protocol will be used to display the content of the text file. Simply the text file which I'm going to display is the source code of this project.
First we need the SD card driver which can be downloaded from the following topic:
MMC/SD Card driver for CCS PIC C compiler
and FAT16 file system library can be downloaded from this topic:
FAT16 Library for CCS C compiler

Hardware Required:
  • PIC16F877A microcontroller
  • FAT16 Formatted SD card (<= 2 GB) with text file
  • ASM1117 3.3 voltage regulator
  • 20 MHz crystal oscillator
  • 2 x 22pF ceramic capacitors
  • 3 x 3.3K ohm resistor
  • 3 x 2.2K ohm resistor
  • 2 x 10K ohm resistor
  • 5 x 10uF polarized capacitor
  • 100nF ceramic capacitor
  • MAX232 chip
  • Female COM port
  • 5V Power source
  • Breadboard
  • Jumper wires
The circuit:
Interfacing PIC16F877A with FAT16 SD card circuit

The AMS1117 3.3V voltage regulator is used to supply the SD card with 3.3V. Also 3 voltage dividers are used to step down the 5V which comes from the microcontroller to about 3V which is sufficient for the SD card. Each voltage divider consists of 2K2 and 3K3 resistors.
MAX232 integrated circuit is used to interface the microcontroller with the PC, I connected just one wire (RD2) because I need to transmit data from the SD card to the microcontroller and then from the microcontroller to the PC, there is no need to connect the second wire because I don't have to send data from the PC to the microcontroller.
Hardware SPI is used by the microcontroller to read data from the SD card, the SPI pins of the PIC16F877A are:
  • SCK (RC3): connected to pin SCK of the SD card
  • SDI (RC4): connected to pin MISO of the SD card
  • SD0 (RC5): connected to pin MOSI of the SD card
and there is an other pin which is CS (Chip Select) can be connected to any digital output pin (defined in the code), this pin is connected to SS pin of the SD card.

Read text file from SD card with FAT16 file system using PIC16F877A C code:
The code used for this example is shown below. It was tested with CCS PIC C compiler versions 5.051 and 5.070.
The text file which I used is just the code below, I named it in Windows "mytext" (basically it is mytext.txt) but in the CCS C code we've to add the extension of the file which becomes "mytext.txt".
I used a read buffer of 10 bytes ( file_data[10] ), so the microcontroller reads the text file 10 bytes by 10 bytes, it reads 10 bytes and send it to the PC via RS232 then the second 10 bytes and so on until the function fat16_read_data(10, file_data) returns 1 which means we're at the end of the file.
I used the command printf("%s", file_data) to display file data as string.
// Read text file from SD card with FAT16 file system CCS C code.
// Used microcontroller: PIC16F877A
// Fat16 library and MMC/SD card driver for CCS C compiler must be installed!
// Use at your own risk!
// http://ccspicc.blogspot.com/
// electronnote@gmail.com

// SD Card module connections
#define   SDCARD_SPI_HW
#define   SDCARD_PIN_SELECT  PIN_D3
// End SD card module connections

#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP                       
#use delay(clock = 20000000)
#use fast_io(D)
#use rs232(xmit = PIN_D2, rcv = PIN_D1, baud = 9600)
#include <sdcard.c>                              // SD card diver source code
#include <fat16.c>

int8 file_data[10];
void open_file(){
  const int8 *txt = "mytext.txt";                // File name 'mytext.txt'
  if(fat16_open_file(txt) == 0){
    printf("OK!");
    printf("\n\r");                              // Start new line
    while(fat16_read_data(10, file_data) == 0)   // Read file data
      printf("%s", file_data);                   // Print file data as string
    return;
  }
  printf("\n\r");                                // Start new line
  printf("File opening error!");
}
void main(){
  set_tris_d(0);                                 // Configure PORTD pins as outputs
  delay_ms(2000);
  printf("\n\r");                                // Start new line
  printf("*** Read text file from FAT16 SD card using PIC16F877A ***");
  delay_ms(2000);
  printf("\n\r");                                // Start new line
  printf("Initializing FAT16 library ...... ");
  if(fat16_init() == 0){                         // If FAT16 file system and SD card were successfully initialized
    printf("OK!");
    delay_ms(2000);
    printf("\n\r");                              // Start new line
    printf("Opening file: 'mytext.txt'...... ");
    open_file();
  }
  else {                                         // Problem occured while the initialization
    printf("\n\r");                              // Start new line
    printf("Initialization error!");
  }
  printf("\n\r");                                // Start new line
  printf("*** END ***");
  while(TRUE) ;                                  // Endless loop
}
The following video shows the output:


If there is no card inserted I got the following result:
PIC16F877A with FAT16 SD card - No card inserted
and if there is no "mytext.txt" file in the SD card I got this result:
PIC16F877A with FAT16 SD card - File not found