MAX7219 am Arduino

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);