// 定義控制腳位
int DIN_pin = 2;
int LOAD_pin = 6;
int CLOCK_pin = 7;
 
// MAX7219 暫存器位址
byte max7219_REG_noop = 0x00;
byte max7219_REG_digit0 = 0x01;
byte max7219_REG_digit1 = 0x02;
byte max7219_REG_digit2 = 0x03;
byte max7219_REG_digit3 = 0x04;
byte max7219_REG_digit4 = 0x05;
byte max7219_REG_digit5 = 0x06;
byte max7219_REG_digit6 = 0x07;
byte max7219_REG_digit7 = 0x08;
byte max7219_REG_decodeMode = 0x09;
byte max7219_REG_intensity = 0x0a;
byte max7219_REG_scanLimit = 0x0b;
byte max7219_REG_shutdown = 0x0c;
byte max7219_REG_displayTest = 0x0f;
 
// 模擬SPI介面依序送出byte資料
void SPI_SendByte(byte data)                 
{             
 byte i = 8;
 byte mask;
 while(i > 0) {
 mask = 0x01 << (i - 1);                     // 製造位元遮罩,從最左邊位元開始
 digitalWrite( CLOCK_pin, LOW);              // 時脈同步線 = LOW
 if (data & mask){                           // 判斷位元遮罩對應的位元是 0 或 1
 digitalWrite(DIN_pin, HIGH);                // 如果對應位元為 1,DIN 送出 HIGH
 }
 else{
 digitalWrite(DIN_pin, LOW);                 // 如果對應位元為 1,DIN 送出 LOW
 }
 digitalWrite(CLOCK_pin, HIGH);              // 時脈同步線 = HIGH
 --i;                                        // 移到下一個位元
 }
}
 
// 控制單一個 MAX7219 模組
void MAX7219_1Unit(byte reg_addr, byte reg_data)    
{
 digitalWrite(LOAD_pin, LOW);                       // 傳送前 LOAD 腳要先變成LOW
 SPI_SendByte(reg_addr);                            // 先送出要設定的暫存器位址
 SPI_SendByte(reg_data);                            // 接著送出資料
 digitalWrite(LOAD_pin,HIGH);                       // 傳送完 LOAD 腳要變成 HIGH
}
 
// 圖樣資料矩陣-OK
byte matrixData_correct[8] = {
B00111100,
B01000010,
B00111100,
B00000000,
B01111110,
B00011000,
B00100100,
B01000010};
 
// 圖樣資料矩陣-X
byte matrixData_error[8] = {
B00000000,
B01000010,
B00100100,
B00011000,
B00011000,
B00100100,
B01000010,
B00000000};
 
// 靜態繪製整個畫面
void Draw (byte *LED_matrix)
{
 MAX7219_1Unit(1, LED_matrix[0]);
 MAX7219_1Unit(2, LED_matrix[1]);
 MAX7219_1Unit(3, LED_matrix[2]);
 MAX7219_1Unit(4, LED_matrix[3]);
 MAX7219_1Unit(5, LED_matrix[4]);
 MAX7219_1Unit(6, LED_matrix[5]);
 MAX7219_1Unit(7, LED_matrix[6]);
 MAX7219_1Unit(8, LED_matrix[7]);
}
 
void setup ( ) {
 pinMode(DIN_pin, OUTPUT);
 pinMode(CLOCK_pin, OUTPUT);
 pinMode(LOAD_pin, OUTPUT);
 digitalWrite(CLOCK_pin, HIGH);
 
// 初始化 MAX7219 的暫存器
MAX7219_1Unit(max7219_REG_scanLimit, 0x07);    // 設定為掃描所有行
MAX7219_1Unit(max7219_REG_decodeMode, 0x00);   // 不使用解碼模式
MAX7219_1Unit(max7219_REG_shutdown, 0x01);     // 設定為不是在關閉模式
MAX7219_1Unit(max7219_REG_displayTest, 0x00);  // 設定為不是在測試模式
 
// 先把所有 LED 矩陣變暗
 for(int i=1; i<=8; i++) {                      
 MAX7219_1Unit(i,0); }
// 設定亮度範圍,0x00 ~ 0x0f
 MAX7219_1Unit(max7219_REG_intensity, 0x0f);    
 delay(500);
}
 
void loop ( ) {
 Draw(matrixData_error);    // 或者選 matrixData_correct
 delay(1500);
 MAX7219_1Unit(max7219_REG_shutdown, 0x00);     // 設定LED為關閉模式
}