
The example shows the connection of a compact flash (CF) memory card to a dsPIC30F micocontroller. The CF memory cards are often used as the memory elements in digital video cameras. The memory capacity is high, from 8MB up to 2GB even more, and the read/write time is typically of the order of µs. Application of CF memory cards in microcontroller systems is quite widespread.
In the CF memory cards data are split into sectors (usually of 512 bytes, in earlier models 256 bytes). Reading or writing is not performed directly byte after byte, but data are blocked per sectors through a 512 byte buffer. Fig. 13-7 shows the electrical connection of a CF memory card to a device of the dsPIC30F family. The realization is carried out by using the mikroPascal compiler for dsPIC30F microcontrollers. The example covers, writing and reading one byte from a CF memory card.
program compact_flash_test;
var
i : word;
ddata: array[512] of byte;
//** It is adviceable to initialize dsPIC in one routine. In this way
//** the code is easier to read and well organized.
procedure Init;
begin
ADPCFG := 0xFFFF; // portb all digital
TRISB := 0; //** make portf to be output
LATB := 0; //** initilize portf
//** dsPIC30F601x, dsPICPro3
Cf_Init(PORTG, 0, 1, 2,
PORTG, 9,
PORTG, 8,
PORTG, 7,
PORTG, 6,
PORTG, 3,
PORTD);
//**
Uart1_Init(19200);
//--- CD1 does not work on non-TTL inputs
//** When CF is inserted CF_Detect will return 1.
//while CF_Detect = 0 do
// begin // do nothing
// end;
//**
//** Some time is needed for the card to make good contacts
delay_ms(100);
//**
end;
procedure WriteByte;
begin
CF_Write_Init(123, 1); //** Initialize write to sector 590
Delay_ms(50);
i := 0;
while i < 512 do //** We will write 512 bytes to CF card
begin
Cf_Write_Byte(i); //** Write one byte
Inc(i);
end;
end;
procedure ReadByte;
var tmpRead: word;
begin
CF_read_Init(123, 1); //** Initialize read from sector 590
Delay_ms(50);
i := 0;
while i < 512 do //** We will read 512 bytes from CF card
begin
tmpRead := CF_read_Byte; //** Read one byte
//Delay_ms(100);
//LATB := tmpRead; //** Write readings to PORTF
Uart1_Write_Char(tmpRead);
i:=i+1;
end;
end;
procedure WriteSectors;
begin
for i := 0 to 511 do
ddata[i] := i;
CF_Write_Sector(590, ddata);
Delay_10ms;
Uart1_Write_Char('s');
for i := 0 to 511 do
ddata[i] := 511-i;
CF_Write_Sector(591, ddata);
Uart1_Write_Char('e');
end;//~
procedure ReadSectors;
begin
CF_Read_Sector(590, ddata);
for i := 0 to 511 do
Uart1_Write_Char(ddata[i]);
Delay_10ms;
CF_Read_Sector(591, ddata);
for i := 0 to 511 do
Uart1_Write_Char(ddata[i]);
end;//~
//** main program starts here
begin
Init;
LATB := $AA;
Delay_ms(500);
//** first set of tests
WriteByte;
LATB := $CC;
Delay_ms(500);
ReadByte;
//**
//** second set of tests
WriteSectors;
LATB := $BB;
ReadSectors;
LATB := $FF; //** Signalize the end of writes
//**
end.