Discussion.
This discussion focuses on the
The DS1050 uses the Philips Inter IC (I2C) protocol and by strapping the A2, A1 and A0 leads, up to eight DS1050 devices may be accommodated on the same 2-wire bus consisting of SCL (clock) and SDA (data). In addition, such other devices as the PCF8574 IO expander, DS1803 or MCP42010 digital potentiometers, DS1307 RTC and 24LC256 may be accommodated on the same bus.
Typical applications include DC motor speed control with the PWM output driving a section of a ULN2803A, a TIP122 Darlington Power transistor, an IRLZ44 FET or an L293 H bridge controller.
Note that the source and sink capabilities of the PWM output is limited to 2.0 mA which is not a great deal of base current for a TPI41C NPN transistor.
The DS1050 may also be used with a series R, shunt C capacitor to generate a DC voltage. However, my feeling is that a MAX518 Dual D/A conveter is a wiser choice.
The packaging of the DS1050 is an 8-pin SOIC with the leads on 0.05 inch centers which is not readily ammenable for use by all-thumbs hobbyists. However, I have found that I can reliably mount these on Aires SOIC to DIP adaptors and we offer both the SOIC and the SOIC mounted on a DIP adaptor.
The factory assigned device code is 0101. The other three bits are set by strapping the A2, A1 and A0 leads on the device. I note that the MAX518 shares this same factory code. Thus, the command byte consists of;
0101 A2 A1 A0 R/Wwhere the R/W bit is a zero for a write command and a logic one for a read. In program DS1050, provison was made to address nay of eight DS1050 devices by passing a number in the range of 0 to 7 corresponding to the A2, A1, A0 strapping. Thus, for a write command, the byte is;
bx0101_0000 + (Dev * 2) followed by clock pulse for the DS1050 to acknowledgeFor a read command;
bx0101_0000 + (Dev * 2) + bx0000_0001 followed by a clock pulse for the DS1050 to acknowledge.The address byte (write) is followed by the the command byte;
Note that this might be restated as
Set PWM Duty bx00PP_PPPP where PP_PPPP is the PWM duty in range of 0 - 32.
The PWM duty may be read by sending the address byte (read) and then reading the duty from the DS1050. Note that BX24 does not bring the SDA lead low for one clock cycle to acknowledge the data to signal the DS1050 that the STOP sequence follows. I did find that if the duty is set to full one (32) the setting will not be read as 32, but rather 63.
One aspect of the DS1050 that I found troubling is that when turned on, the output runs at a 50 percent duty cycle. The ramifications are that until the BX24 sends a command to the DS1050, you may well have a motor turning that you just do not want turning. However, a separate output from the BX24 might be used as a Motor On control. This might be anded with the DS1050 PWM output using a section 74HC08. The 74HC08 then drives the FET or similar. I would pull-down each input of the 74HC08 to ground through 1K to guard against the condition where the BX24 is not powered and the input to the 74HC08 would otherwise be floating.
Note that Dallas offers the DS1050 with a number of standard frequencies including 1, 5 and 10 kHz.
Program DS1050_1.Bas
' DS1050_1.Bas ' ' Illustrates an interface with the Dallas DS1050 programmable 5-bit pulse width modulator ' using the Philips IC2 protocol. ' ' Illustrates the use of setting the PWM duty, reading the PWM duty, shutting down the DS1050 ' and recalling the device from shutdown. ' ' The program recalls the DS1050 from sleep and increases the duty cycle from 0/32 to 32/32 in ' half second intervals. The duty cycle is also read and displayed to the terminal. ' ' The DS1050 is then shutdwon for 15 seconds. The program continually loops. ' ' ' BX24 DS1050 ' ' Term 15 ------------------------ SDA (term 2) ----------- To other I2C devices ' Term 14 ------------------------ SCL (term 1) ----------- ' ' GRD --- A2 (term 6) ' GRD --- A1 (term 7) ' GRD --- A0 (term 3) ' ' PWM (term 5) --------- To FET driving motor ' or RC Network ' Compile with SerialPort.Bas. ' ' coyright, Peter H. Anderson, Baltimore, MD, May, '02 const SCL as byte=14 const SDA as byte=15 Sub Main() Dim Duty as Byte, DutyRead as Byte Call Sleep(1.0) ' to avoid download problems Call OpenSerialPort(1, 19200) ' if using functions in SerialPort.Bas Debug.Print "..............." ' to see that something is happening Do Call DS1050Recall(0) ' be sure it is not in shut down Call DS1050SetPWMDuty(0, bx0000_0000) ' set duty to 0 For Duty = 0 to 32 ' Note that 32 is full on Call DS1050SetPWMDuty(0, Duty) DutyRead = DS1050ReadPWMDuty(0) ' read back PWM duty and display Debug.Print CStr(Duty); " "; CStr(DutyRead) Call Sleep(0.5) Next Call DS1050Shutdown(0) Call Sleep(15.0) Loop End Sub Sub DS1050SetPWMDuty(ByVal Dev as Byte, ByVal Duty as Byte) ' 0 - 31. 32 for full on Call I2CStart() Call I2COutByte(bx0101_0000 OR (Dev * 2)) Call I2COutByte(Duty) Call I2CStop() End Sub Sub DS1050ShutDown(ByVal Dev as Byte) Call I2CStart() Call I2COutByte(bx0101_0000 OR (Dev * 2)) Call I2COutByte(bx1100_0000) Call I2CStop() End Sub Sub DS1050Recall(ByVal Dev as Byte) Call I2CStart() Call I2COutByte(bx0101_0000 OR (Dev * 2)) Call I2COutByte(bx1000_0000) Call I2CStop() End Sub Function DS1050ReadPWMDuty(ByVal Dev as Byte) as Byte Dim PWMSetting as Byte Call I2CStart() Call I2COutByte(bx0101_0000 OR (Dev * 2) OR bx0000_0001) PWMSetting = I2CInByte(0) ' no ack prior to stop Call I2CStop() DS1050ReadPWMDuty = PWMSetting End Function Sub I2CStart() Call PutPin(SCL,0) Call PutPin(SDA,2) Call PutPin(SCL,2) Call PutPin(SDA,0) Call PutPin(SCL,0) End Sub Sub I2CStop() Call PutPin(SCL, 0) Call PutPin(SDA, 0) Call PutPin(SCL,2) Call PutPin(SDA,2) End Sub Sub I2COutByte(ByVal X as Byte) Dim N as Integer For N=1 to 8 If((x AND &H80) <> 0) Then Call PutPin(SDA,2) ' Call PutByte(Asc("1")) ' used for debugging Else Call PutPin(SDA,0) ' Call PutByte(Asc("0")) ' used for debugging End If Call PutPin(SCL,2) Call PutPin(SCL,0) x=x*2 Next ' Call NewLine() ' used for debugging Call PutPin(SDA,2) Call PutPin(SCL,2) Call PutPin(SCL,0) Call PutPin(SDA,2) End Sub Function I2CInByte(ByVal Ack as Byte) as Byte Dim N as Integer Dim X as Byte FOR N=1 to 8 Call PutPin(SCL,2) If(GetPin(SDA)=1) Then X = X * 2 +1 Else X = X * 2 End If Call PutPin(SCL, 0) NEXT If (Ack <> 0) Then Call PutPin(SDA, 0) Else Call PutPin(SDA,2) End If Call PutPin(SCL,2) Call PutPin(SCL,0) Call PutPin(SDA,0) I2CInByte = X End Function