The example shows the initialization, writing, and reading data from the transmit and receive buffer register ofan I2C module, respectively. The example shows the connection of an I2C module to the serial EEPROM memory 24C02. The realization is carried out by using the mikroPascal compiler for dsPIC30F microcontrollers. Fig. 13-11 shows the electrical connection of an I2C module to the EEPROM memory 24C02. The example covers writing to the EEPROM memory, reading data, and data transfer to the PORTF.
Fig. 13-11 Electrical connection of an I2C module to the EEPROM memory 24C02.
program I2CEEPROM; var dAddr : word; begin ADPCFG := 0xFFFF; PORTB := 0; TRISB := 0; dAddr := 0x02; I2c_Init(0x000186A0); I2c_Start(); // issue I2C start signal I2c_Write(0xA2); // send byte via I2C (command to 24cO2) I2c_Write(dAddr); // send byte (address of EEPROM location) I2c_Write(0xF5); // send data (data to be written) I2c_Stop(); Delay_ms(100); I2c_Start(); // issue I2C start signal I2c_Write(0xA2); // send byte via I2C (device address + W) I2c_Write(0x02); // send byte (data address) I2c_Restart(); // issue I2C signal repeated start I2c_Write(0xA3); // send byte (device address + R) PORTB := I2c_Read(1); // Read the data (acknowledge) I2c_Stop(); end.
program RTCWrite; begin ADPCFG := 0xFFFF; I2C_Init(10000); // initialize full master mode I2C_Start(); // issue start signal I2C_Write(0xA0); // address PCF8583 I2C_Write(0); // start from word at address 0 (configuration word) I2C_Write(0x80); // write $80 to config. (pause counter...) I2C_Write(0); // write 0 to cents word I2C_Write(0); // write 0 to seconds word I2C_Write(0x30); // write $30 to minutes word I2C_Write(0x11); // write $11 to hours word I2C_Write(0x24); // write $24 to year/date word I2C_Write(0x08); // write $08 to weekday/month I2C_Stop(); // issue stop signal I2C_Start(); // issue start signal I2C_Write(0xA0); // address PCF8530 I2C_Write(0); // start from word at address 0 I2C_Write(0); // write 0 to config word (enable counting) I2C_Stop(); // issue stop signal end. program RTCRead; var sec, min1, hr, day, mn, year : byte; tnum, txt : array[6] of byte; procedure Zero_Fill(var value : array[10] of byte); // fill text repesentation begin if (value[1] = 0) then begin // with leading zero value[1] := value[0]; value[0] := 48; value[2] := 0; end; end; //-------------- Trims the leading spaces from array given with *pt procedure rtrim(var src, dest : array[10] of byte); var i, j : word; begin i := 0; j := 0; while (src[i] = ' ') do inc(i); while (src[i] <> 0) do begin dest[j] := src[i]; inc(i); inc(j); end; dest[j] := 0; end; //--------------------- Reads time and date information from RTC (PCF8583) procedure Read_Time(var sec, min, hr, day, mn, year : byte); begin I2C_Start(); I2C_Write(0xA0); I2C_Write(2); I2c_Restart(); I2C_Write(0xA1); sec := I2c_Read(0); min := I2c_Read(0); hr := I2c_Read(0); day := I2c_Read(0); mn := I2c_Read(1); I2C_Stop(); end; //-------------------- Formats date and time procedure Transform_Time(var sec, min, hr, day, mn, year : byte); begin sec := ((sec and 0xF0) shr 4)*10 + (sec and 0x0F); min := ((min and 0xF0) shr 4)*10 + (min and 0x0F); hr := ((hr and 0xF0) shr 4)*10 + (hr and 0x0F); year := (day and 0xC0) shr 6; day := ((day and 0x30) shr 4)*10 + (day and 0x0F); mn := ((mn and 0x10) shr 4)*10 + (mn and 0x0F); end; //-------------------- Output values to LCD procedure Display_Time( sec, min, hr, day, mn, year : byte); begin WordToStr(word(day), tnum); rtrim(tnum, txt); Zero_Fill(txt); Lcd_Out(1, 6, txt); WordToStr(word(mn), tnum); rtrim(tnum, txt); Zero_Fill(txt); Lcd_Out(1,9,txt); Lcd_Chr(1,15,52+year); WordToStr(word(hr), tnum); rtrim(tnum, txt); Zero_Fill(txt); Lcd_Out(2,6,txt); WordToStr(word(min), tnum); rtrim(tnum, txt); Zero_Fill(txt); Lcd_Out(2,9,txt); WordToStr(word(sec), tnum); rtrim(tnum, txt); Zero_Fill(txt); Lcd_Out(2,12,txt); end; //------------------ Performs project-wide init procedure Init_Main(); begin ADPCFG := 0xFFFF; TRISD := 0; // designate portd as output Lcd_Init_EasyDsPIC4(); I2C_Init(100000); // initialize I2C txt := 'Date:'; // prepare and output static text on LCD Lcd_Out(1,1,txt); Lcd_Chr(1,8,':'); Lcd_Chr(1,11,':'); txt := 'Time:'; Lcd_Out(2,1,txt); Lcd_Chr(2,8,':'); Lcd_Chr(2,11,':'); txt := '200'; Lcd_Out(1,12,txt); Lcd_Cmd(LCD_CURSOR_OFF); // cursor off end; //----------------- Main procedure begin Init_Main(); // perform initialization while true do begin Read_Time(sec, min1, hr, day, mn, year); // read time from RTC(PCF8583) Transform_Time(sec, min1, hr, day, mn, year); // format date and time Display_Time(sec, min1, hr, day, mn, year); // prepare and display on LCD Delay_ms(1000); // wait 1s end; end.