Files
2024-07-20 22:09:06 +08:00

271 lines
5.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* MaxMatrix
* Version 1.0 Feb 2013
* Copyright 2013 Oscar Kin-Chung Au
*/
#include "Arduino.h"
#include "MaxMatrix.h"
MaxMatrix::MaxMatrix(byte _data, byte _load, byte _clock, byte _num)
{//_num为LED矩阵个数
data = _data;
load = _load;
clock = _clock;
num = _num;
for(int i=0;i<64;i++)
status[i]=0x00;
for (int i=0; i<80; i++)
buffer[i] = 0;
}
void MaxMatrix::init()
{
pinMode(data, OUTPUT);
pinMode(clock, OUTPUT);
pinMode(load, OUTPUT);
digitalWrite(clock, HIGH);
setCommand(max7219_reg_scanLimit, 0x07);
setCommand(max7219_reg_decodeMode, 0x00); // using an led matrix (not digits)
setCommand(max7219_reg_shutdown, 0x01); // not in shutdown mode
setCommand(max7219_reg_displayTest, 0x00); // no display test
// empty registers, turn all LEDs off
clear();
setIntensity(0x0f); // the first 0x0f is the value you can set
}
void MaxMatrix::setIntensity(byte intensity)
{
setCommand(max7219_reg_intensity, intensity);
}
void MaxMatrix::clear()
{
for (int i=0; i<8; i++)
setColumnAll(i,0);
for (int i=0; i<80; i++)
buffer[i] = 0;
}
void MaxMatrix::setCommand(byte command, byte value)
{
digitalWrite(load, LOW);
for (int i=0; i<num; i++)
{
shiftOut(data, clock, MSBFIRST, command);
shiftOut(data, clock, MSBFIRST, value);
}
digitalWrite(load, LOW);
digitalWrite(load, HIGH);
}
/***************************************************************************
Function: setRow()
Description: 更新一行LED状态
Calls:
Called By:
Input: 1.int addr : 级联中的max7219地址
2.int row LED所在行
3.byte value 该行LED状态
Output:
Return:
Others:
***************************************************************************/
void MaxMatrix::setRow(int addr, int row, byte value) {
int offset;
if(addr<0 || addr>=num)
return;
if(row<0 || row>7)
return;
offset=addr*8;
status[offset+row]=value;
spiTransfer(addr, row+1,status[offset+row]);
}
void MaxMatrix::setColumn(byte col, byte value)
{
int n = col / 8;
int c = col % 8;
digitalWrite(load, LOW);
for (int i=0; i<num; i++)
{
if (i == n)
{
shiftOut(data, clock, MSBFIRST, c + 1);
shiftOut(data, clock, MSBFIRST, value);
}
else
{
shiftOut(data, clock, MSBFIRST, 0);
shiftOut(data, clock, MSBFIRST, 0);
}
}
digitalWrite(load, LOW);
digitalWrite(load, HIGH);
buffer[col] = value;
}
void MaxMatrix::setColumnAll(byte col, byte value)
{
digitalWrite(load, LOW);
for (int i=0; i<num; i++)
{
shiftOut(data, clock, MSBFIRST, col + 1);
shiftOut(data, clock, MSBFIRST, value);
buffer[col * i] = value;
}
digitalWrite(load, LOW);
digitalWrite(load, HIGH);
}
void MaxMatrix::setDot(byte col, byte row, byte value)
{
bitWrite(buffer[col], row, value);
int n = col / 8;
int c = col % 8;
digitalWrite(load, LOW);
for (int i=0; i<num; i++)
{
if (i == n)
{
shiftOut(data, clock, MSBFIRST, c + 1);
shiftOut(data, clock, MSBFIRST, buffer[col]);
}
else
{
shiftOut(data, clock, MSBFIRST, 0);
shiftOut(data, clock, MSBFIRST, 0);
}
}
digitalWrite(load, LOW);
digitalWrite(load, HIGH);
}
void MaxMatrix::writeSprite(int x, int y, const byte* sprite)
{
int w = sprite[0];
int h = sprite[1];
if (h == 8 && y == 0)
for (int i=0; i<w; i++)
{
int c = x + i;
if (c>=0 && c<80)
setColumn(c, sprite[i+2]);
}
else
for (int i=0; i<w; i++)
for (int j=0; j<h; j++)
{
int c = x + i;
int r = y + j;
if (c>=0 && c<80 && r>=0 && r<8)
setDot(c, r, bitRead(sprite[i+2], j));
}
}
void MaxMatrix::reload()
{
for (int i=0; i<8; i++)
{
int col = i;
digitalWrite(load, LOW);
for (int j=0; j<num; j++)
{
shiftOut(data, clock, MSBFIRST, i + 1);
shiftOut(data, clock, MSBFIRST, buffer[col]);
col += 8;
}
digitalWrite(load, LOW);
digitalWrite(load, HIGH);
}
}
void MaxMatrix::shiftLeft(bool rotate, bool fill_zero)
{
byte old = buffer[0];
int i;
for (i=0; i<80; i++)
buffer[i] = buffer[i+1];
if (rotate) buffer[num*8-1] = old;
else if (fill_zero) buffer[num*8-1] = 0;
reload();
}
void MaxMatrix::shiftRight(bool rotate, bool fill_zero)
{
int last = num*8-1;
byte old = buffer[last];
int i;
for (i=79; i>0; i--)
buffer[i] = buffer[i-1];
if (rotate) buffer[0] = old;
else if (fill_zero) buffer[0] = 0;
reload();
}
void MaxMatrix::shiftUp(bool rotate)
{
for (int i=0; i<num*8; i++)
{
bool b = buffer[i] & 1;
buffer[i] >>= 1;
if (rotate) bitWrite(buffer[i], 7, b);
}
reload();
}
void MaxMatrix::shiftDown(bool rotate)
{
for (int i=0; i<num*8; i++)
{
bool b = buffer[i] & 128;
buffer[i] <<= 1;
if (rotate) bitWrite(buffer[i], 0, b);
}
reload();
}
/***************************************************************************
Function: spiTransfer()
Description: 数据发送
Calls:
Called By:
Input: 1.int addr : 级联中的max7219地址
2.byte opcode :操作码
3.byte data :操作数
Output:
Return:
Others:
***************************************************************************/
void MaxMatrix::spiTransfer(int addr, volatile byte opcode, volatile byte data) {
//Create an array with the data to shift out
int offset=addr*2;
int maxbytes=num*2;
for(int i=0;i<maxbytes;i++) //所有级连的MAX7219先设置为无操作
spidata[i]=(byte)0;
//put our device data into the array
spidata[offset+1]=opcode; //要操作的芯片设置操作码
spidata[offset]=data; //操作数据
//enable the line
digitalWrite(load,LOW);
//Now shift out the data
for(int i=maxbytes;i>0;i--) //发送数据
shiftOut(data,clock,MSBFIRST,spidata[i-1]);
//latch the data onto the display
digitalWrite(load,HIGH);
}