PICAXE-18X - Interfacing with a Dallas DS1050 5-bit PWM Controller

copyright, Peter H Anderson, Baltimore, MD, Feb, '04


This note discusses how up to eight Dallas 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