Mit dem folgenden Programm kann man eine 8-stellige 7-Segmentanzeige (wahlweise stattdessen einen ganzen Haufen LEDs) per MAX7219 mit dem Arduino via SPI ansteuern.
#define OP_DECODEMODE 9
#define OP_INTENSITY 10
#define OP_SCANLIMIT 11
#define OP_SHUTDOWN 12
#define OP_DISPLAYTEST 15
struct max_ctx {
uint8_t devices;
uint8_t spi_data;
uint8_t spi_clk;
uint8_t spi_cs;
};
max_ctx mx;
void max7219_init(uint8_t dataPin, uint8_t clkPin, uint8_t csPin, uint8_t numDevices)
{
uint8_t i;
mx.spi_data=dataPin;
mx.spi_clk=clkPin;
mx.spi_cs=csPin;
if(numDevices<=0 || numDevices>8) {
numDevices=8;
}
mx.devices=numDevices;
pinMode(mx.spi_data, OUTPUT);
pinMode(mx.spi_clk, OUTPUT);
pinMode(mx.spi_cs, OUTPUT);
digitalWrite(mx.spi_cs, HIGH);
for(i=0; i<mx.devices; i++) {
max7219_out(i, OP_DISPLAYTEST, 0);
max7219_out(i, OP_SHUTDOWN, 1);
max7219_out(i, OP_SCANLIMIT, 7);
max7219_out(i, OP_DECODEMODE, 0);
max7219_clrdisp(i);
}
}
void max7219_out(uint8_t addr, uint8_t reg, uint8_t data)
{
uint8_t i, k, offset, maxbytes;
uint8_t buf[16];
offset=addr*2;
maxbytes=mx.devices*2;
for(i=0; i<maxbytes; i++) {
buf[i]=0;
}
buf[offset+1]=reg;
buf[offset]=data;
digitalWrite(mx.spi_cs, LOW);
for(i=maxbytes; i>0; i--) {
for(k=0; k<8; k++) { /* now shift out data */
digitalWrite(mx.spi_data, !!(buf[i-1] & (1<<(7-k))));
digitalWrite(mx.spi_clk, HIGH);
digitalWrite(mx.spi_clk, LOW);
}
}
digitalWrite(mx.spi_cs, HIGH);
}
void max7219_clrdisp(uint8_t addr)
{
uint8_t i;
if(addr>=mx.devices) {
return;
}
for(i=0; i<8; i++) {
max7219_out(addr, i+1, 0);
}
}
void max7219_setdigit(uint8_t addr, uint8_t digit, uint8_t value, boolean dp)
{
const static uint8_t charTable[16] = {
B01111110,B00110000,B01101101,B01111001,
B00110011,B01011011,B01011111,B01110000,
B01111111,B01111011,B01110111,B00011111,
B00001101,B00111101,B01001111,B01000111
};
uint8_t offset, v;
if(addr>=mx.devices || digit>7 || value>15) {
return;
}
offset=addr*8;
v=charTable[value];
if(dp) {
v|=B10000000;
}
max7219_out(addr, digit+1, v);
}
max7219_init(12,11,13,1);
max7219_clrdisp(0);