211 lines
6.5 KiB
C++
211 lines
6.5 KiB
C++
/*
|
||
* Max7219.cpp - A library for controling Leds with a MAX7219/MAX7221
|
||
* Copyright (c) 2007 Eberhard Fahle
|
||
* Max7219<31><39><EFBFBD><EFBFBD>
|
||
* 7219<31><39><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD>
|
||
* 1<><31>spi<70><69><EFBFBD>߷<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4>MISO<53><4F>
|
||
* 2<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4>з<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȳ<EFBFBD><C8B3>ķ<EFBFBD>ʽ<EFBFBD>ڼ<EFBFBD><DABC><EFBFBD>оƬ<D0BE><C6AC><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD>4<EFBFBD><34>оƬ<D0BE><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD><34><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD>Ϳղ<CDBF><D5B2><EFBFBD><EFBFBD>룬<EFBFBD><EBA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD><34>оƬ<D0BE><C6AC>
|
||
* 3<><33>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ16λ<36><CEBB><EFBFBD><EFBFBD>8λΪ<CEBB><CEAA><EFBFBD><EFBFBD><EFBFBD>룬<EFBFBD><EBA3AC>8λΪ<CEBB><CEAA><EFBFBD>ݡ<EFBFBD><DDA1><EFBFBD>λ<EFBFBD><CEBB>ǰ<EFBFBD><C7B0><EFBFBD>䡣
|
||
* <20><><EFBFBD><EFBFBD>ʹ<EFBFBD>ã<EFBFBD>
|
||
* 1<><31>
|
||
*/
|
||
|
||
|
||
#include "DuinoplusMax7219.h"
|
||
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> the opcodes for the MAX7221 and MAX7219
|
||
#define OP_NOOP 0
|
||
#define OP_DIGIT0 1
|
||
#define OP_DIGIT1 2
|
||
#define OP_DIGIT2 3
|
||
#define OP_DIGIT3 4
|
||
#define OP_DIGIT4 5
|
||
#define OP_DIGIT5 6
|
||
#define OP_DIGIT6 7
|
||
#define OP_DIGIT7 8
|
||
#define OP_DECODEMODE 9
|
||
#define OP_INTENSITY 10 //<2F><><EFBFBD><EFBFBD>
|
||
#define OP_SCANLIMIT 11
|
||
#define OP_SHUTDOWN 12
|
||
#define OP_DISPLAYTEST 15
|
||
|
||
Max7219::Max7219(int csPin, int dataPin, int clkPin, int numDevices) {
|
||
SPI_MOSI=dataPin;
|
||
SPI_CLK=clkPin;
|
||
SPI_CS=csPin;
|
||
maxDevices=numDevices;
|
||
pinMode(SPI_MOSI,OUTPUT);
|
||
pinMode(SPI_CLK,OUTPUT);
|
||
pinMode(SPI_CS,OUTPUT);
|
||
digitalWrite(SPI_CS,HIGH);
|
||
for (int i = 0; i < maxDevices; i++){
|
||
digitalWrite(SPI_CS, LOW);
|
||
for (int i = 0; i < maxDevices; i++){
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, OP_DISPLAYTEST); //<2F><><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EEA3AC>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, 0);
|
||
}
|
||
digitalWrite(SPI_CS, HIGH);
|
||
}
|
||
for (int i = 0; i < maxDevices; i++){
|
||
digitalWrite(SPI_CS, LOW);
|
||
for (int i = 0; i < maxDevices; i++){
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, OP_DECODEMODE); //<2F><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, 0); /*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܶ<EFBFBD><DCB6><EFBFBD><EFBFBD>Ƿ<EFBFBD>ʹ<EFBFBD><CAB9>CODE B<><42><EFBFBD>룬<EFBFBD><EBA3AC><EFBFBD>ﲻ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>Ϊ0*/
|
||
}
|
||
digitalWrite(SPI_CS, HIGH);
|
||
}
|
||
setScanLimit(7); /*<2A><><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>һ<EFBFBD><D2BB>оƬ<D0BE>ɽ<EFBFBD>8λ<38><CEBB><EFBFBD><EFBFBD><EFBFBD>*/
|
||
clearDisplay();
|
||
shutdown(true); /*<2A>ر<EFBFBD>*/
|
||
}
|
||
|
||
int Max7219::getDeviceCount() {
|
||
return maxDevices;
|
||
}
|
||
|
||
void Max7219::shutdown(bool b) {
|
||
uint8_t state;
|
||
if(b)
|
||
state = 0;
|
||
else
|
||
state = 1;
|
||
|
||
digitalWrite(SPI_CS, LOW);
|
||
for (int i = 0; i < maxDevices; i++){
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, OP_SHUTDOWN); //<2F><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, state);
|
||
}
|
||
digitalWrite(SPI_CS, HIGH);
|
||
}
|
||
|
||
void Max7219::setScanLimit(int limit) {
|
||
if(limit>=0 && limit<8){
|
||
digitalWrite(SPI_CS, LOW);
|
||
for (int i = 0; i < maxDevices; i++){
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, OP_SCANLIMIT); //<2F><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, limit);
|
||
}
|
||
digitalWrite(SPI_CS, HIGH);
|
||
}
|
||
}
|
||
|
||
void Max7219::setIntensity(int intensity) {
|
||
if(intensity>=0 && intensity<16){
|
||
digitalWrite(SPI_CS, LOW);
|
||
for (int i = 0; i < maxDevices; i++){
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, OP_INTENSITY); //<2F><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, intensity);
|
||
}
|
||
digitalWrite(SPI_CS, HIGH);
|
||
}
|
||
}
|
||
|
||
/*clearDisplay()
|
||
<09><><EFBFBD><EFBFBD>
|
||
*/
|
||
void Max7219::clearDisplay(void) {
|
||
int j;
|
||
for (j = 0; j < 8; j++){
|
||
//enable the line
|
||
digitalWrite(SPI_CS, LOW);
|
||
//Now shift out the data
|
||
for (int i = 0; i < maxDevices; i++){
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, j + 1); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ַָ<D6B7><D6B8>
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, 0);
|
||
}
|
||
//latch the data onto the display
|
||
digitalWrite(SPI_CS, HIGH);
|
||
}
|
||
}
|
||
|
||
/*setDigit()
|
||
<09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>
|
||
<09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
int addr<64><72>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>оƬ<D0BE><C6AC>ַ
|
||
int digit<69><74><EFBFBD>ڼ<EFBFBD>λ<EFBFBD><CEBB>һ<EFBFBD><D2BB>оƬ֧<C6AC><D6A7>8λ<38><CEBB><EFBFBD><EFBFBD><EFBFBD>
|
||
byte value<75><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
boolean dp<64><70><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ʾС<CABE><D0A1><EFBFBD><EFBFBD>
|
||
*/
|
||
void Max7219::setDigit(int addr, int digit, byte value, boolean dp) {
|
||
int offset;
|
||
byte v;
|
||
|
||
if(addr<0 || addr>=maxDevices)
|
||
return;
|
||
if(digit<0 || digit>7 || value>15)
|
||
return;
|
||
offset=addr*8;
|
||
v=pgm_read_byte_near(charTable + value);
|
||
if(dp)
|
||
v|=B10000000;
|
||
status[offset+digit]=v;
|
||
spiTransfer(addr, digit+1,v);
|
||
}
|
||
|
||
void Max7219::setChar(int addr, int digit, char value, boolean dp) {
|
||
int offset;
|
||
byte index,v;
|
||
|
||
if(addr<0 || addr>=maxDevices)
|
||
return;
|
||
if(digit<0 || digit>7)
|
||
return;
|
||
offset=addr*8;
|
||
index=(byte)value;
|
||
if(index >127) {
|
||
//no defined beyond index 127, so we use the space char
|
||
index=32;
|
||
}
|
||
v=pgm_read_byte_near(charTable + index);
|
||
if(dp)
|
||
v|=B10000000;
|
||
status[offset+digit]=v;
|
||
spiTransfer(addr, digit+1,v);
|
||
}
|
||
|
||
/*update()
|
||
<09>ѻ<EFBFBD><D1BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><CDB8><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ͵<C9BA><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>оƬ8<C6AC><38><EFBFBD>ֽڣ<D6BD>
|
||
Ϊ<><CEAA><EFBFBD>Ч<EFBFBD>ʣ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>оƬ<D0BE><C6AC>ͬһ<CDAC><D2BB>
|
||
*/
|
||
void Max7219::update(byte *buff){
|
||
int j;
|
||
for (j = 0; j < 8; j++){
|
||
//enable the line
|
||
digitalWrite(SPI_CS, LOW);
|
||
//Now shift out the data
|
||
for (int i = 0; i < maxDevices; i++){
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, j + 1); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ַָ<D6B7><D6B8>
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, *(buff + (maxDevices - 1) * 8 - i * 8 + j));
|
||
}
|
||
//latch the data onto the display
|
||
digitalWrite(SPI_CS, HIGH);
|
||
}
|
||
}
|
||
|
||
/*spiTransfer()
|
||
<09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>оƬ<D0BE><C6AC>ij<EFBFBD><C4B3>оƬ<D0BE><C6AC><EFBFBD><EFBFBD>
|
||
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ʹ<EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD>ʽϵ<CABD>
|
||
<09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
int addr<64><72>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>оƬ<D0BE><C6AC>ַ
|
||
volatile byte opcode<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
volatile byte data<74><61><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
*/
|
||
void Max7219::spiTransfer(int addr, volatile byte opcode, volatile byte data) {
|
||
//Create an array with the data to shift out
|
||
int offset = addr * 2;
|
||
int maxbytes = maxDevices * 2;
|
||
|
||
for (int i = 0; i<maxbytes; i++)
|
||
spidata[i] = (byte)0;
|
||
//put our device data into the array
|
||
spidata[offset + 1] = opcode;
|
||
spidata[offset] = data;
|
||
//enable the line
|
||
digitalWrite(SPI_CS, LOW);
|
||
//Now shift out the data
|
||
for (int i = maxbytes; i>0; i--)
|
||
shiftOut(SPI_MOSI, SPI_CLK, MSBFIRST, spidata[i - 1]); /*<2A><><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>δβоƬ<D0BE><C6AC><EFBFBD><EFBFBD>*/
|
||
//latch the data onto the display
|
||
digitalWrite(SPI_CS, HIGH);
|
||
}
|