Sie sind auf Seite 1von 4

picprojects.

net | SD-Card with CCS C Compiler

1 of 4

http://www.picprojects.net/sdcard_demo/index.html

PICPROJECTS.NET
HOME

PROJECTS

DEVELOPMENT TOOLS

PIC Microcontroller Projects

BOOTLOADER

FORUM

DISCLAIMER

PIC PROGRAMMER

SEARCH

SD-Card with CCS C Compiler


Description
Hardware

Search
Custom Search

Software
Links
PIC PROJECTS

Description

RS232 Communication

This project shows how to use a SD-Card with FAT16 file system. It is based on the example MMC/SD-Card driver

DS1820 Temperature Sensor

(mmcsd.c) and FAT file system driver (fat.c) delivered with the CCS C compiler.

DS2482 1-Wire bridge


RFM12 Module

Unfortunately, the example didn't work properly for me. So I searched the web and found some required changes to

DCF77 Time Signal Decoding

make it work. All modifications are described in the following article.

SD-Card and FAT16 Demo


RC5 Decoder

Hardware

HARDWARE PROJECTS

SD-cards can be interfaced to a microcontroller via SPI-Bus, hence only 4 I/O pins (SDI, SDO, SCK, CS) are required to

PIC16F/18F Experiment Board

connect the SD-card to the PIC.

ENC28J60 Modul
RS232 Module

SD-cards operate at 2.7V .. 3.6V while the 18F PICs usually operate at 5V. Hence a voltage level translation is required

LCD Adapter

for the SD-card inpus (SDI, SCK, CS). There are a lot of examples available in the web where a voltage divider with
resistors is used to translate the 5V signals to 3.3V. This will work, but at higher SPI speeds this might cause problems.
Due to that, I used a 74AC125 buffer to do the level translation which works more reliable than the voltage divider.

SD-Card Module

DEVELOPMENT TOOLS
PIC C Compiler Overview
PIC Programmer

Here the schematic of the SD-Card module with the voltage level translation. The pins on the connector SV1 need to be
connected to the microcontroller pins.
BOOTLOADER
Important: SDO and SDI are the pin names from the SD-card point of view, i.e. SDO needs to be connected to SDI on
Serial PIC Bootloader

the microcontroller and SDI needs to be connected to SDO in the microcontroller!


USB PIC Bootloader

3/17/2015 4:07 PM

picprojects.net | SD-Card with CCS C Compiler

2 of 4

http://www.picprojects.net/sdcard_demo/index.html

Here some pictures of the SD-card module which I have build on a breadboard and the experimental setup. I used the
PIC1618Exp-28d experiment board assembled with a PIC18F2620 for the experimental setup.

Software
As mentioned in the description for this article, I used the ex_fat.c example which is delivered with the CCS C compiler.

Unforunately, when I run the demo and created some files with the demo, I was not able to see the files when I pluged
the SD-card into my PC. After some investigations I found a solution for this problem in the CCS forum which I will
summarize here.

Modifications in mmcsd.c
Search for

uint32_t g_mmcsdBufferAddress;
and add under it:

uint32_t g_mmcsdPartitionOffset;
Next, just before the "mmcsd_init" function add a new function:

void mmcsd_check_part(uint16_t off)


{
if (g_mmcsd_buffer[off + 0] == 0x80)
{
// active partition

3/17/2015 4:07 PM

picprojects.net | SD-Card with CCS C Compiler

3 of 4

http://www.picprojects.net/sdcard_demo/index.html

uint8_t t;
t = g_mmcsd_buffer[off + 4];
if (t == 0x04 || t == 0x06 || t == 0x0B)
{
// FAT16 or FAT32 partition
g_mmcsdPartitionOffset = make32(
g_mmcsd_buffer[off + 11], g_mmcsd_buffer[off + 10],
g_mmcsd_buffer[off + 9], g_mmcsd_buffer[off + 8]) * MMCSD_MAX_BLOCK_SIZE;
}
}
}
In the "mmcsd_init" function, right after the line:

r1 = mmcsd_load_buffer();
Add the lines:

g_mmcsdPartitionOffset = 0;
mmcsd_check_part(0x1EE);
mmcsd_check_part(0x1DE);
mmcsd_check_part(0x1CE);
mmcsd_check_part(0x1BE);
Finally, in the function "mmcsd_move_buffer", after the line:

new_block = new_addr - (new_addr % MMCSD_MAX_BLOCK_SIZE);


Add the line:

new_block += g_mmcsdPartitionOffset;

Modifications in mmcsd.c
The CCS "fat.c" functions "get_next_addr" and "get_prev_addr" do not correctly handle cluster transitions. The following
are corrected functions, so replace the function with the following code:

signed int get_next_addr(int32* my_addr)


{
int32 temp;
#ifdef FAT32
int32 c;
#else
int16 c;
#endif
// check to make sure that the next iteration will give us a contiguous address
temp = *my_addr + 1;
if((temp > Data_Start) && ((temp - Data_Start) % Bytes_Per_Cluster == 0))
{
// convert the current address into the address of where information about
// the address is stored in the FAT, and put this value into the current address
c = addr_to_cluster(temp - 1);
if(get_next_cluster(&c) == EOF)
return EOF;
if (c >=
#ifdef FAT32
0x0FFFFFF8
#else
0xFFF8
#endif
)
return EOF;
temp = cluster_to_addr(c);
}
*my_addr = temp;
return GOODEC;
}
Further, get_prev_addr() needs to be updated:

signed int8 get_prev_addr(int32* my_addr)


{
int32 temp;
#ifdef FAT32
int32 c;
#else
int16 c;
#endif
temp = *my_addr;
// if we're trying to go backwards one entry from the beginning of the root,
// we won't be able to...
if(temp <= Root_Dir)
return GOODEC;
// check to make sure that the next iteration will give us a contiguous address
if((temp >= Data_Start) && ((temp - Data_Start) % Bytes_Per_Cluster == 0))
{
c = addr_to_cluster(temp);
if(get_prev_cluster(&c) == EOF)
return EOF;
temp = cluster_to_addr(c) + Bytes_Per_Cluster;
}
*my_addr = temp - 1;
return GOODEC;
}

3/17/2015 4:07 PM

picprojects.net | SD-Card with CCS C Compiler

4 of 4

http://www.picprojects.net/sdcard_demo/index.html

In fat_init() function search for the following lines

#ifdef FAT32
Data_Start = Bytes_Per_Cluster + Root_Dir;
#else // FAT16
and replace it with the following code (i.e. remove "Bytes_Per_Cluster +"):

#ifdef FAT32
Data_Start = Root_Dir;
#else // FAT16
And finally, get_short_file_name() needs to be replaced with the following code:

signed int get_short_file_name(int32 file_entry_addr, char sname[], int8 type)


{
int
buf,
i,
j = 0;
// one short file name has, at the most, 11 characters
for(i = 0; i < 11; ++i)
{
// read in a character
if(mmcsd_read_data(i + file_entry_addr, 1, &buf) != GOODEC)
return EOF;
// convert the character
if(buf != ' ')
{
if (i == 8 && type != 0x10) sname[j++] = '.';
sname[j++] = tolower(buf);
}
}
if (sname[j - 1] == '.') --j;
sname[j] = '\0';
return GOODEC;
}
With this modifications everything worked fine. But currently, the changes have only been verifed with FAT16 enabled,
i.e. I have enabled FAT16 support and disabled FAT32 in fat.c:

/// Define your FAT type here ///


#define FAT16
//#define FAT32

Links
Here some usefull links:

http://www.ccsinfo.com/forum/viewtopic.php?t=43402: CCS SD/MMC driver MBR support


http://www.ccsinfo.com/forum/viewtopic.php?t=43417: CCS FAT driver bugfix!

picprojects.net
PIC microcontroller hardware and
software projects with description,
schematics and source code!

Development Tools

Latest Articles

PICPgm PIC Programmer

LCD Adapter

PIC Compiler Overview

RS232 Communication

USB Bootloader

RC5 Decoder

picprojects.net

Serial Bootloader

2011 picprojects.net. Design by Free CSS Templates and Free Web Templates

3/17/2015 4:07 PM

Das könnte Ihnen auch gefallen