fl { A/D D/A Converter(PCF8591) PropForth 5.5 2015/05/04 13:16:09 PCF8591 Propeller AN0 ------- Analog In0 AN1 ------- Analog In1 AN2 ------- Analog In2 AN3 ------- Analog In3 A0 ------- GND A1 ------- 3.3V A2 ------- GND SDA ------------------------ SDA SCL ------------------------ SCL OSC EXT ------- GND AGND ------- GND VREF ------- 3.3V AOUT ------- Analog Out VDD ------- 3.3V } \ =========================================================================== \ Constants \ =========================================================================== \ Slave addres h4A for PCF8591 h94 wconstant PCF8591 \ --- control byte --- \ channel 0 wconstant ch0 1 wconstant ch1 2 wconstant ch2 3 wconstant ch3 \ Auto increment flag 4 wconstant auto_act 0 wconstant auto_inact \ Analog input programming 0 wconstant 4ch_single h10 wconstant 3ch_diff h20 wconstant mix h30 wconstant 2ch_diff \ Analog out enable flag h40 wconstant analog_enab 0 wconstant analog_disab \ =========================================================================== \ slow i2c \ =========================================================================== \ slow _eeread (9.09kHz) \ ( t/f -- c1 ) flag should be true if this is the last read : _slow_eeread _sdai 0 8 0 do 1 lshift _scli _sda? _sclo if 1 or then loop swap if _sdai else _sdao then _scli _sclo ; \ slow _eewrite (6.25kHz) \ ( c1 -- t/f ) write c1 to the eeprom, true if there was an error : _slow_eewrite h80 8 0 do 2dup and if _sdai else _sdao then _scli _sclo 1 rshift loop 2drop _sdai _scli _sda? _sclo _sdao ; \ Write data to register in i2c_device \ ( n1 n2 n3 -- t/f ) n1:data n2:register n3:slave_address t/f:true if there was an error : i2c_wr \ Start I2C _eestart \ Write slave address[wr], then receive Acknowledge-bit(ACK:Lo NACK:Hi) _slow_eewrite \ ( n1 n2 t/f ) \ Write register swap _slow_eewrite or \ ( n1 t/f ) \ Write data swap _slow_eewrite or \ ( t/f ) \ Stop I2C _eestop ; \ Read data (SCK:400kHz) \ ( n1 -- n2..nn t/f ) n1:number n2..nn:data t/f:true if there was an error : PCF8591_rd \ Start I2C _eestart \ Write slave address[rd], then receive Acknowledge-bit(ACK:Lo NACK:Hi) PCF8591 1 or _slow_eewrite \ ( n1 t/f ) \ Read (n1-1)bytes >r \ Push flag ( n1 ) dup 1 > if 1 - 0 do 0 _slow_eeread \ ( n2..nn-1 ) loop else drop then \ Read 1byte ,then set sda to Hi(NACK:master->slave) -1 _slow_eeread \ ( n4..nn ) r> \ Pop flag ( n2..nn t/f ) \ Stop I2C _eestop \ ( n2..nn t/f ) ; \ =========================================================================== \ Main \ =========================================================================== \ control byte \ ( n1 n2 n3 n4 -- n5 ) n1:Analog out enable flag n2:Analog input programming n3:Auto increment flag n4:channel \ n5:combined byte : control or or or ; \ D/A out input to A/D channel ANIN0 \ ANIN1=ANIN2=0V ANIN3=3.3V \ ( -- ) : demo d256 0 do \ Output D/A to analog-output i analog_enab 4ch_single auto_act 0 control PCF8591 i2c_wr err? ." Setting[D/A]:" i . 2 spaces 5 PCF8591_rd err? ." ch3:" . ." ch2:" . ." ch1:" . ." ch0:" . ." previous-ch0:" . cr d10 delms loop ; : test 10000 0 do h45 _slow_eewrite drop loop ; : test1 20000 0 do 0 _slow_eeread drop loop ;