Poti digital

MCP4261 und "Familie"

Früher habe ich mit aufwendigen Transistorschaltungen Differenzverstärker gebaut, um Audio-Signale zu regeln.
Heute gibt es digitale Potis. Mit denen kann man Audiosignale schalten, Fade-In - Fade-Out oder auch Hüllkurven wie ADSR oder Filterbewegungen (im Analog-Synthi z.T. vorhanden) realisieren.
Keine OPVs und keine Transistoren sind mehr nötig.
Aus irgendwelchen Gründen habe ich mich für die MCP-"Familie" entschieden.

Laut Datenblatt: MCP4261

Vdd bis 7V --- Empfohlen: 2,7V .. 5,5V. Auch 1,8V.
Die Spannung an den Potipins können bis 12,5V hoch sein.

Pins:
SHDN auf Low = sleep, also SHDN auf Vdd schalten
WP Pin auf Vdd = keine Daten können in den EEPROM geschrieben werden
WP Pin auf GND = Schreiben auf internen EEPROM möglich

Ich benutze den internen Eeprom nicht, sondern lasse alle Werte am Anfang (Init) durch den uC in das Poti einschreiben.

Poti / Rheostat

Typen Auswahl
Bez
Beschreibung
Steps
MCP4141
Singel Poti - Eeprom - 2,7..5,5V
129
MCP4142
Singel Rheostat - Eeprom - 2,7..5,5V
129
MCP4151
Singel Poti - kein Eeprom - 1,8..5,5V
257
MCP4152
Singel Rheostat - kein Eeprom - 1,8..5,5V
257
MCP4161
Singel Poti - Eeprom - 2,7..5,5V
257
MCP4162
Singel Rheostat - Eeprom - 2,7..5,5V
257
MCP42xx
Dual Poti...
...
MCP4261
Dual Poti - Eeprom - 2,7..5,5V --- bevorzugt
257
MCP4262
Dual Rheostat - Eeprom - 2,7..5,5V
257
Adresse z.B.:

0000 = Platz für Potiwert Poti0 (Flüchtiger Speicher)
0001 = Platz für Potiwert Poti1 (Flüchtiger Speicher)

0100 = Platz für Potiwrt Poti0 (ROM, wird nach Einschalten geladen)
0101 = Platz für Potiwrt Poti1 (ROM, wird nach Einschalten geladen)

Kommando z.B.

Schreiben 00
Lesen 11

Daten:

9Bit lang (Bit10 wird ignoriert)

Kommunikation

Bit 15 --- Adresse 3
Bit 14 --- Adresse 2
Bit 13 --- Adresse 1
Bit 12 --- Adresse 0

Bit 11 --- Command 1
Bit 10 --- Command 0
Bit 9 --- x

Bit 8 .. 0 --- D8, D7 .. D0 (9Bits)

Lesen - Schreiben - Command 1 und 0
00 = Write Data
01 = Inc
10 = Dec
11 = Read Data

C-Code

z.B.:
#define
PotiCS 2
#define
PotiSCK 3
#define
PotiSDI 4

#define
DDRPotis DDRD
#define
PortPotis PORTD




DDRPotis |= (1<<PotiCS) | (1<<PotiSCK) | (1<<PotiSDI);

#define
  SCKLo   PortPotis &= ~(1<<PotiSCK)
#define
  SCKHi   PortPotis |= (1<<PotiSCK)
#define
  SDIHi   PortPotis |= (1<<PotiSDI)
#define
  SDILo   PortPotis &= ~(1<<PotiSDI)



void
TxPotAddrAndCommand(
uint8_t
d)
// 7 Bit

{
uint8_t
i;
SCKLo;
// Mode 0,0

SDILo;

for
(i=0;i<7;i++)
{
// Datenausgang entsprechend dem Wert d -- Lo oder Hi setzen

if
(d & 0b10000000) SDIHi;
// hochwertiges Bit zuerst

else
SDILo;

SCKHi;
// Pulse, Daten werden von Poti übernommen

SCKLo;

d <<= 1;
}
}


void
TxPotData(
uint16_t
d)
// 9 Bit

{
uint8_t
i;

for
(i=0;i<9;i++)
{
if
(d & 0b100000000) SDIHi;
else
SDILo;

SCKHi;
SCKLo;

d <<= 1;
}
}


void
TxValueToPoti(
uint8_t
PotNr,
uint16_t
Data)
// PotNr = Poti 0 oder 1, Data = Potiwert

{
PortPotis &= ~(1<<PotiCS);
//Ein


//Bit15..Bit9

TxPotAddrAndCommand(PotNr << 4 );
// 0 oder 1 = Adresse für Poti0 oder Poti1

// <<4 = 0000 0000 oder 0001 0000

// Bit 3 und 2 sind Command 00 = write


TxPotData(Data);
// 9 Bit


PortPotis |= (1<<PotiCS);
//Aus

}