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.