#!/usr/bin/perl -w ################################################### # I2C über I2C-RS232 Koppler von horter.de # Jörg Brune joergbrune.de ################################################### use constant false=>0; use constant true=>1; $PortName="COM1"; # verwendete serielle Schnittstelle $t_bps=1000; # Bits pro Sekunde $debug=false; # true/false true: Busverkehr anzeigen print "Content-Type: text/html\n\n"; print "<htm><head><title>i2c test</title></head><body bgcolor=cornsilk>"; use Time::HiRes qw(usleep); use Win32::SerialPort; # Linux Device::SerialPort # SerialPort gibts hier: http://www.bribes.org/perl/ppm/ $t_bt=1000000/$t_bps/4; $startdelay=20; ## port öffnen $quiet=0; $PortObj = new Win32::SerialPort ($PortName, $quiet) || die "kann $PortName: $^E nicht öffnen\n"; sub i2cout { $cl=shift;$dt=shift; $PortObj->dtr_active($dt);$PortObj->rts_active($cl); usleep $t_bt; } sub i2cstart { if($debug){print "<br><font size=2><> 76543120 ack dez<br>";} ## for($i = 1; $i <= $startdelay; $i++) { i2cout(1,1); } i2cout(1,1);i2cout(1,0);i2cout(1,0);i2cout(0,0); } sub i2cstop ##stopbit schreiben { i2cout(0,0);i2cout(1,0);i2cout(1,0);i2cout(1,1); for($i = 1; $i <= $startdelay; $i++) { i2cout(1,1); } } sub i2cwt ## bit schreiben { $bit=shift; i2cout(0,$bit);i2cout(1,$bit);i2cout(1,$bit);i2cout(0,$bit); } sub i2crb { i2cout(0,1);i2cout(1,1); $r = $PortObj->modemlines & 32; ## ist 32 richtig? oder 16? if($r>0){$r=1;} i2cout(1,1);i2cout(0,1); return($r);} sub ic2_wb ## byte schreiben { $by=shift; $by0=$by; if($debug){print "-> ";} ## for($i=1;$i<=8;$i++) { $bt=0;if(($by & 128)>0){$bt=1;} $by=($by << 1); i2cwt($bt); if($debug){print "$bt";} ## } $ack=i2crb(); if($debug){print " $ack $by0<br>"}; ## return($ack); } sub ic2_rb ## byte lesen { $by=0; if($debug){print "<- ";} ## for($i=1;$i<=8;$i++) { $bt=i2crb(); $by=($by << 1)+$bt; if($debug){print "$bt";} ## } $ack=i2crb(); if($debug){print " $ack $by<br>";} ## return($by); } ############################## # Funktionen für I2C Bausteine sub pcf8574wt { $adr=shift;$dat=shift; i2cstart(); $err=-ic2_wb(64+$adr+$adr); $err=-ic2_wb($dat)+2*$err; i2cstop(); return($err);} sub pcf8574rd { $adr=shift; i2cstart(); ic2_wb(64+$adr+$adr); ic2_wb(255); ic2_wb(65+$adr+$adr); $dat=ic2_rb(); i2cstop(); return($dat); } sub pcf8591rd { $adr=shift;$ain=shift; i2cstart(); ic2_wb(144+$adr+$adr); ic2_wb($ain); i2cstop(); i2cstart(); ic2_wb(144+$adr+$adr+1); $dat=ic2_rb(); i2cstop(); i2cstart(); ic2_wb(144+$adr+$adr+1); $dat=ic2_rb(); i2cstop(); return($dat); } sub pcf8591wt { $adr=shift;$dat=shift; i2cstart(); ic2_wb(144+$adr+$adr); $err=-ic2_wb(64); $err=-ic2_wb($dat)+2*$err; i2cstop(); return($err); } ############################################ ## beispiel für pcf8574 # schreiben $res=pcf8574wt(0,254); # a:0-7, out:0-255 # lesen $res=pcf8574rd(0); # a:0-7 print " ....$res<br><br>"; ## beispiel für pcf8591 # lesen $res=pcf8591rd(0,0); # a:0-7, in:0-3 print " ....$res<br><br>"; # schreiben $res=pcf8591wt(0,20); # a:0-7, out:0-255 print " ....$res<br><br>"; print "</body></html>\n";