News:

Let's find out together what makes a PIC Tick!

Main Menu

MCP4551 anyone?

Started by TimB, Feb 27, 2021, 08:56 PM

Previous topic - Next topic

TimB

Hi all

First off I'm taking a longshot in the attempt to not reinvent code if I some on else has it already.

The device is a i2c digital pot made by Mchip the MCP4551    https://ww1.microchip.com/downloads/en/DeviceDoc/22096b.pdf

Before I spend hours figuring out how to use it, any one have some code already?

Thanks

Tim



John Drew

Tim,
I've used a ds18030-010 if that is of any use.
John

normnet

I have used the MCP41010 10K as follows:

vCOMMAND_BYTE = %00010001  ' %00010001 WRITE DATA POT 0

Low sPOT_CS
SSPBUF = vCOMMAND_BYTE ' SEND DATA BYTE
While SSPSTAT.0 = 0: Wend ' WHILE TX/RX COMPLETES
vDUMMY = SSPBUF

SSPBUF = vPOT_SET ' SEND DATA BYTE
While SSPSTAT.0 = 0: Wend ' WHILE TX/RX COMPLETES
vDUMMY = SSPBUF             
High sPOT_CS

top204

#3
I don't have an MCP4551 device, so I looked in the datasheet and it seemed like a standard I2C device.

I've just knocked up this piece of, untested, code for the control of the MCP4551 chip. I hope it will help:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Routines to talk to an MCP4551 digital potentiometer
'
' Written by Les Johnson for the Proton8 and Proton24 BASIC compilers.
' https://sites.google.com/view/rosetta-tech/home
'
    Device = 18F26K40
    Declare Xtal = 16
'
' Define the pins to use for the I2C interface to the MCP4551 device
'
$define MCP4551_SDA_Pin PORTC.3
$define MCP4551_SCL_Pin PORTC.4
'
' I2C Address of device
'
    Symbol MCP4551_cADDRESS_A0_VCC = ($2F << 1)     ' A0 is connected to VCC
    Symbol MCP4551_cADDRESS_A0_GND = ($2E << 1)     ' A0 is connected to GND
'
' Command definitions (Sent to the Wiper register)
'
    Symbol MCP4551_cCMD_WRITE = $00
    Symbol MCP4551_cCMD_INC   = $04
    Symbol MCP4551_cCMD_DEC   = $08
    Symbol MCP4551_cCMD_READ  = $0C
'
' Control bit definitions (Sent to the TCON register)
'
    Symbol MCP4551_cTCON_GC_EN  = $0100
    Symbol MCP4551_cTCON_R0_EN  = $0008
    Symbol MCP4551_cTCON_A_EN   = $0004
    Symbol MCP4551_cTCON_W_EN   = $0002
    Symbol MCP4551_cTCON_B_EN   = $0001
    Symbol MCP4551_cTCON_ALL_EN = $01FF
'
' Register addresses
'
    Symbol MCP4551_cRA_WIPER = $00
    Symbol MCP4551_cRA_TCON  = $40

'-------------------------------------------------------------------------
' Set the Wiper value
' Input     : pValue holds the value to set the Pot too (0 to 256)
' Output    : None
' Notes     : None
'
Proc MCP4551_SetWiper(pValue As Word)
    pValue.Byte1 = ((pValue.Byte1 & $01) | MCP4551_cCMD_WRITE)
    I2COut MCP4551_SDA_Pin, MCP4551_SCL_Pin, MCP4551_cADDRESS_A0_GND, [pValue.Byte1, pValue.Byte0]
EndProc

'-------------------------------------------------------------------------
' Increment the Wiper
' Input     : None
' Output    : None
' Notes     : The MCP4551 will not increment past 256
'
$define MCP4551_IncWiper() I2COut MCP4551_SDA_Pin, MCP4551_SCL_Pin, MCP4551_cADDRESS_A0_GND, [MCP4551_cCMD_INC]

'-------------------------------------------------------------------------
' Decrement the Wiper
' Input     : None
' Output    : None
' Notes     : The MCP4551 will not decrement below 0
'
$define MCP4551_DecWiper() I2COut MCP4551_SDA_Pin, MCP4551_SCL_Pin, MCP4551_cADDRESS_A0_GND, [MCP4551_cCMD_DEC]

'-------------------------------------------------------------------------
' Read the Wiper value
' Input     : None
' Output    : Returns the wiper value
' Notes     : None
'
Proc MCP4551_GetWiper(), Word
    I2CIn MCP4551_SDA_Pin, MCP4551_SCL_Pin, MCP4551_cADDRESS_A0_GND, [MCP4551_cCMD_READ, Result]
EndProc

'-------------------------------------------------------------------------
' The main test program starts here
' Cycle the potentiometer from low to high value
'
Main:
    Dim wWiperValue As Word

    Do                                      ' Create an infinite loop
        For wWiperValue = 0 To 256          ' Create a loop for the potentiometer resolution
            MCP4551_SetWiper(wWiperValue)   ' Set the potentiometer
            DelayMS 200                     ' A small delay so we can see the changes on a multi-meter
        Next
    Loop                                    ' Do it forever

The routines are missing a write to the TCON register within the device, but I couldn't work out if it needed it for standard operation, or if it needs a write for "ALL ON" with a single pot device. Please let me know if it works Tim, or if not, what had to be changed to get it to work. I can then place it in the compiler samples folder, and the forum's WIKI.

TimB


Brilliant Les

Cannot thank you enough. It worked right of the box, unlike my PCB wiring. Fixed now and moving onto the next stage

No changes were needed and ran at 64mhz.

Tim

top204

#5
Excellent news Tim.

I have the timings within the software I2C commands increased, as set by the speed of the microcontroller, so the I2COut and I2CIn routines will work at approx 100KHz to 200KHz. The same for the Busin/Busout commands etc...

Can you try the MCP4551_GetWiper() procedure please, and see what it returns?

Procedures within the 8-bit compiler have made such a difference, and the good thing is that they are not mandatory as in most other procedure based languages. We still have the compiler's commands to fall back on and place within the procedures to enhance them. :-) It was a huge amount of work to add them, but it was more than worth it to bring the compiler into the 21st Century.

TimB


Hi Les

Yes the MCP4551_GetWiper() works

I really like being able to have the best of both worlds with built in commands like Bin16 without loads of separate libs and pulling in more peripheral centric commands as needed.

 
Tim

top204

I've just ordered a few samples of the MCP4551 device so I can extend the library to also control the TCON register within it and add it to my site as an article.

I have quite a few digital pot devices, but no MCP4551 types. I've always went with the SPI types because they operate faster.

I remember when they first came out and I added a section in my book about controlling them for audio work. I also created a, complex, project that would read and program "any" device using digital pots to control the voltage of any pin going to a device via an addressed SPI network, which fed a high power Op-Amp so the voltage could range from 0 to 12 Volts etc... And it worked really well.

I've also made some ADSR circuits using them and they work really well.

John Drew

Looking forward to the book Les. How's progress?
John

RayEllam

Just what im looking for, many thanks Les.