Created
February 9, 2012 00:38
-
-
Save dccourt/1775920 to your computer and use it in GitHub Desktop.
Simple SPI multiplexed addressing demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Digital potentiometer (MSP4131) programming over SPI | |
// D. Court 8 Feb 2012. | |
// Pin assignments (arduino digital pin numbering) | |
#define SRCLK_PIN 4 | |
#define SPICLK_PIN 3 | |
#define DATA_PIN 2 | |
// /CS of each device goes to a (LSB-end) line of the shift reg D-outputs. | |
// Data line is connected to both SR and device | |
// SRCLK and RCLK are connected together on shift reg. | |
#define NUM_DEVICES 3 | |
#ifndef __AVR_ATtiny85__ | |
#define DEBUG_INIT Serial.begin(57600); | |
#define DEBUG_PRINT(A) Serial.print((A)); | |
#define DEBUG_PRINTLN(A) Serial.println((A)); | |
#define DEBUG_PRINTLN2(A,B) Serial.println((A), (B)); | |
#else | |
#define DEBUG_INIT | |
#define DEBUG_PRINT(A) | |
#define DEBUG_PRINTLN(A) | |
#define DEBUG_PRINTLN2(A,B) | |
#endif | |
byte commandData = 0; // Command to write to volatile wiper 0. | |
void setup() | |
{ | |
pinMode(SPICLK_PIN, OUTPUT); | |
pinMode(SRCLK_PIN, OUTPUT); | |
pinMode(DATA_PIN, OUTPUT); | |
// Disable programming until needed | |
load_shift_reg(0xFF); | |
DEBUG_INIT; | |
} | |
void load_shift_reg(byte value) | |
{ | |
DEBUG_PRINT("Load shift reg with "); | |
DEBUG_PRINTLN2(value, BIN); | |
shiftOut(DATA_PIN, SRCLK_PIN, MSBFIRST, value); | |
// Because we're driving the shift register with its two | |
// clocks tied together, we actually need to shift out one | |
// more bit to properly load the latches. We don't care | |
// about the value of this bit, so don't bother setting | |
// the data pin. | |
digitalWrite(SRCLK_PIN, HIGH); | |
delay(5); | |
digitalWrite(SRCLK_PIN, LOW); | |
} | |
// Otherbits must not clash with the lowest NUM_DEVICES bits, | |
// but otherwise can be anything to use the unused shiftreg lines. | |
void select_device(int devnum, byte otherbits) | |
{ | |
byte data = otherbits; | |
byte all_devs = (1 << NUM_DEVICES) - 1; // Set /CS high on all devices | |
byte dev_bits = all_devs ^ (1 << devnum); // except the one we want. | |
load_shift_reg(data | dev_bits); | |
} | |
void data_write(byte device, byte value) | |
{ | |
DEBUG_PRINT("Writing "); | |
DEBUG_PRINT(value); | |
DEBUG_PRINT(" to device "); | |
DEBUG_PRINTLN(device); | |
// reflect the value to write in the extrabits on the shift reg. | |
// Do this by having an RGB LED connected to MSBits 5, 6, 7 | |
// respectively. We encode values < 10 as red, 10-64 as yellow, | |
// 64-127 as green. We're using a common anode LED, so invert | |
// the bits. | |
byte extra_bits; | |
if (value < 10) | |
{ | |
extra_bits = 0b11000000; | |
} | |
else if (value < 65) | |
{ | |
extra_bits = 0b10000000; | |
} | |
else | |
{ | |
extra_bits = 0b10100000; | |
} | |
// enable the data interface via shift register | |
select_device(device, extra_bits); | |
shiftOut(DATA_PIN, SPICLK_PIN, MSBFIRST, commandData); | |
shiftOut(DATA_PIN, SPICLK_PIN, MSBFIRST, value); | |
} | |
void loop() | |
{ | |
for (int device = 0; device < NUM_DEVICES; device ++) | |
{ | |
data_write(device, 0); | |
delay(2000); | |
data_write(device, 64); | |
delay(2000); | |
data_write(device, 127); | |
delay(2000); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment