This note discusses how up to eight DS1050 5-bit PWM Converter may be interfaced with a PICAXE-18X or similar using two of the output terminals.
The Dallas DS1050 provides 5-bit programmable PWM. That is, the duty cycle may be adjusted from 0/32, 1/32, etc to 32/32. Dallas provides parts which operate at 1, 5, 10 and 25 kHz. The units I have on hand are 10 kHz. Unfortunately, the DS1050 is packaged in an 8-pin SOIC package and most hobbyists will probably want to use an Aires SOIC to DIP adaptor or similar.
The PWM output may be used to drive an L293 H bridge or a power FET or it may be used as an analog to digital converter by using a series R, shunt C on the output.
The DS1050 uses the Philips I2C protocol and although the PICAXE does include I2C write and read commands, the format used is amenable only to I2C devices which have command structures similar to an EEPROM or RAM. That is, specify an address on the slave device followed by the data to be written, or specify an address on the slave device and then read the data. The PICAXE approach is powerful and will work for many I2C devices. However, with the DS1050, there is no start address where data is to be written. Rather, the command is simply one byte, the three upper bits identifying the command and the lower five bits are used to specify the PWM duty.
Thus, I originally intended to write my own I2C routines, but to my chagrin discovered that there is no bidirectional data I/O on the PICAXE-18X and try as I might, trying to "poke" the TRISA and TRISB registers proved to no avail. The bidirectional aspect is important in that the SDA lead is used to both send data to and receive data from the slave. In addition, the two logic states on the SDA lead should be a hard ground (logic 0) and a high impedance (logic 1) and not having a bidirectional I/O makes this impossible.
However, although the DS1050 does permit one to read the current PWM duty cycle from a slave, there really is no great need to do so and thus there really is no need to read from the DS1050 slave. Further, as only the capability of writing to the slave is required, the high impedance really is not required. The same high impedance logic one may be facilitated by bringing the terminal to a hard +5 VDC though a series 4.7K resistor.
Thus, in the following routine, recognize that this does not use the PICAXE I2C commands and also recognize that this is not strictly in accordance with the I2C standard. As noted, up to eight DS1050 devices may be accommodated on the same two signal leads, but as there is no way to read the slave, devices such as the 24LC256 or similar EEPROMs and the DS1302 RTC should not be located on the two outputs used for the DS1050.
The factory assigned address is %0101. The other three bits are set using straps on the A2, A1, A0 terminals on the DS1050.
The sequence begins with the I2CStart sequence which is a matter of bringing SDA low while SCL is high. For normal operation, SCL is then brought low.
The specific device is then addressed by sending its unique address on the bus, in this case, %0101 0000, using subroutine I2COutByte. The least significant bit at zero indicates to the addressed slave that this is a write command. This byte is sent to the slave, most significant bit first, by setting the SDA lead to the appropriate state and bringing SCL high and then low. This is repeated for each of the eight bits. SDA is then brought high for one clock pulse. Note that in general, the full address byte is 2 * DevAdr + $50.
The command is then sent using subroutine I2COutByte. The three most significant bits are used to specify the command;
%000 ' set PWM to value specified in the lower five bits
%001 ' set PWM to full on
%110 ' shut down the DS1050
%100 ' recall. Take the DS1050 out of shutdown and begin PWM using the value in
' the least significant five bits.
The communications sequence is terminated using the I2CStop which brings SDA high while SCL is high.
' DS1050.Bas
'
' Illustrates an interface with the Dallas DS1050 5-bit PWM Controller
'
' Sets PWM Duty to 16 / 32 for 10 secs
' Sets to 4 / 32 for 10 secs
' Shuts down for 10 secs
' Recalls the 4/32 and runs for 10 secs
'
' Continually loops.
'
'
' PICAXE-18X DS1050
'
' Output0 (term 6) -------------- SCL (term 1) ---------- To other DS1050 devices
' Output1 (term 7) -- 4.7K ----- SDA (term 2) ---------- each with different A2, A1, A0 strapping
'
' Note that the strapping of A2, A1 and A0 on the DS1050 determine the DevAdr. This may
' be in the range of 0 to 7. Note that up to eight DS1050 devices, each having a different
' strapping, may be accommodated on the same two signal leads.
'
' Note that although the DS1050 uses the Philips I2C protocol. However, the nature of the
' PICAXE I2C commands is not ammenable to control of the DS1050.
'
' In addition, the lack of a bidirectional I/O on the PICAXE-18X precludes bringing SDA to
' a high impedance state. A series 4.7K resistor is used such that a logic one is +5 VDC
' through a 4.7K resistor. This is not in keeping with the I2C standard, but it does work
' in applications where it is not necessary to read from the I2C slave. Of course, I2C devices
' such as a 24LC256 EEPROM or DS1302 RTC where reads are required may not be used on these
' signal leads.
'
' copyright, Peter H Anderson, Baltimore, MD, Feb, '04, Mar, '04
Symbol SCL = Output0
Symbol SDA = Output1
Symbol SetPWMCommand = $00
Symbol ShutDownCommand = $c0
Symbol RecallCommand = $80
Symbol DevAdr = B0
Symbol PWMDuty = B1
Symbol OByte = B2
Symbol N = B3
Symbol MSBit = B4
TOP:
DevAdr = $00 ' A2, A1, A0 strapping
PWMDuty = %00010000 ' 16 / 32 = 50 percent duty cycle
GoSub I2CStart ' start a sequence
OByte = DevAdr * 2 + $50 ' address the device for the purpose of writing
GoSub I2COutByte
OByte = SetPWMCommand + PWMDuty ' send the SetPWM command in the high three bits
GoSub I2COutByte ' and the PWM duty in the low five bits
GoSub I2CStop
Sleep 10 ' let it run for 10 seconds
PWMDuty = %00000100 ' Duty = 4/32
GoSub I2CStart ' similar to the above
OByte = DevAdr * 2 + $50
GoSub I2COutByte
OByte = SetPWMCommand + PWMDuty
GoSub I2COutByte
GoSub I2CStop
Sleep 10 ' let it run for 10 seconds
GoSub I2CStart ' shutdown the DS1050 for 10 seconds
OByte = DevAdr * 2 + $50
GoSub I2COutByte
OByte = ShutDownCommand
GoSub I2COutByte
GoSub I2CStop
Sleep 10 ' stop for 10 seconds
GoSub I2CStart ' take out of shutdown
OByte = DevAdr * 2 + $50 ' the PWM will be the same as it was
GoSub I2COutByte ' when the DS1050 was shutdown
OByte = RecallCommand
GoSub I2COutByte
GoSub I2CStop
Sleep 10
GoTo TOP
I2CStart:
High SDA
High SCL
Low SDA ' bring SDA low when SCL is high
Low SCL
Return
I2CStop:
High SCL
High SDA ' bring SDA high when SCL is high
Return
I2COutByte:
For N = 1 to 8
MSBit = OByte / 128
If MSBit = 1 Then I2COutByte_1 ' most sign bit
Low SDA
GoTo I2COutByte_2
I2COutByte_1:
High SDA
I2COutByte_2:
High SCL
Low SCL
OByte = OByte * 2 ' shift byte such that next bit is in most sig bit position
Next
High SDA ' null clock pulse to allow for slave to acknowledge
High SCL
Low SCL
Low SDA
Return