

program electronique_pic_tuto_base_i2c_pcf8591_001a;
const
cPCF8591_W = $90;
cPCF8591_R = $91;
var
Values: array[0..3] of byte;
i, iConf, iVal: byte;
LCD_RS : sbit at LATA4_bit;
LCD_EN : sbit at LATA5_bit;
LCD_D4 : sbit at LATA0_bit;
LCD_D5 : sbit at LATA1_bit;
LCD_D6 : sbit at LATA2_bit;
LCD_D7 : sbit at LATA3_bit;
LCD_RS_Direction : sbit at TRISA4_bit;
LCD_EN_Direction : sbit at TRISA5_bit;
LCD_D4_Direction : sbit at TRISA0_bit;
LCD_D5_Direction : sbit at TRISA1_bit;
LCD_D6_Direction : sbit at TRISA2_bit;
LCD_D7_Direction : sbit at TRISA3_bit;
procedure Main_Init;
begin
CMCON := $07; // turn off comparators
INTCON2.NOT_RBPU := 0; // activate pullup
ADCON1 := ADCON1 or $0F; // turn off analog inputs
TRISA := $00; // outputs
TRISB := $FF; // inputs
PORTA := $00;
PORTB := $00;
// I2C comm init
I2C1_Init(100000);
// LCD init
Lcd_Init;
Lcd_Cmd(_LCD_CURSOR_OFF);
end;
procedure Display_Refresh;
var
sVal, sIdx: string[3];
s: string[20];
begin
Lcd_Cmd(_LCD_CLEAR);
for i := 0 to 3 do
begin
ByteToStr(Values[i], sVal);
ByteToStr(i, sIdx);
s := sIdx + ' : ' + sVal;
LCD_Out(i + 1, 1, s);
end;
end;
procedure PCF8591_Write;
begin// config CAN
iConfig := $40;
iVal := PORTB;
I2C1_Start; // signal START
I2C1_Wr(cPCF8591_W); // Addresse PCF8591
I2C1_Wr(iConf); // envoi configuration générale
I2C1_Wr(iVal); // envoi valeur sortie analogique
I2C1_Stop; // signal STOP
end;
procedure PCF8591_Read_All;
begin
// config CAN
iConf := $44;
I2C1_Start; // signal START
I2C1_Wr(cPCF8591_W); // addresse PCF8591
I2C1_Wr(iConf); // envoi configuration générale
I2C1_Stop; // signal STOP
// read analog Values
I2C1_Start; // signal START
I2C1_Wr(cPCF8591_R); // addresse PCF8591
Values[0] := I2C1_Rd(1); // lecture entree analogique "prev"
Values[0] := I2C1_Rd(1); // lecture entree analogique #0
Values[1] := I2C1_Rd(1); // lecture entree analogique #1
Values[2] := I2C1_Rd(1); // lecture entree analogique #2
Values[3] := I2C1_Rd(0); // lecture entree analogique #3
I2C1_Stop; // signal STOP
end;
procedure PCF8591_Read_One(idx: byte);
begin
// config CAN
iConf := $40;
iConf := iConf xor idx; //
I2C1_Start; // signal START
I2C1_Wr(cPCF8591_W); // addresse PCF8591
I2C1_Wr(iConf); // envoi configuration générale
I2C1_Stop; // signal STOP
// read analog value
I2C1_Start; // signal START
I2C1_Wr(cPCF8591_R); // addresse PCF8591
iVal := I2C1_Rd(1); // lecture entree analogique
iVal := I2C1_Rd(0); // lecture entree analogique
I2C1_Stop; // signal STOP
Values[idx] := iVal;
end;
procedure PCF8591_Read;
begin
// sample values on analog inputs
if 1 = 1 then
begin
PCF8591_Read_All;
end
else
begin
PCF8591_Read_One(0);
PCF8591_Read_One(1);
PCF8591_Read_One(2);
PCF8591_Read_One(3);
end;
// show sampled Values on LCD display
Display_Refresh;
end;
begin
Main_Init;
delay_ms(500);
while true do
begin
// read PCF8591 analog inputs
PCF8591_Read;
Delay_ms(250);
//write to PCF8591 analog output
PCF8591_Write;
Delay_ms(250);
end;
end.
const
cPCF8591_W = $90;
cPCF8591_R = $91;
| A2 | A1 | A0 | PCF8591 Ecriture |
PCF8591 Lecture |
| 0 | 0 | 0 | $90 (144d) | $91 (145d) |
| 0 | 0 | 1 | $92 (146d) | $93 (147d) |
| 0 | 1 | 0 | $94 (148d) | $95 (149d) |
| 0 | 1 | 1 | $96 (150d) | $97 (151d) |
| 1 | 0 | 0 | $98 (152d) | $99 (153d) |
| 1 | 0 | 1 | $9A (154d) | $9B (155d) |
| 1 | 1 | 0 | $9C (156d) | $9D (157d) |
| 1 | 1 | 1 | $9E (158d) | $9F (159d) |