// 動手做8-6: LED 矩陣逐字捲動效果程式之一
// 詳細的程式說明,請參閱第八章,8-32頁。
#include <SPI.h>
#include "fonts.h" // 引用外部的 LED 字元外觀定義檔
byte buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};
// 儲存要顯示的訊息
char msg[] = { 'A', 'r', 'd', 'u', 'i', 'n', 'o', ' ' };
int msgSize = sizeof(msg);
// 定義 MAX7219 暫存器值
const byte NOOP = 0x0; // 不運作
const byte DECODEMODE = 0x9; // 解碼模式
const byte INTENSITY = 0xA; // 顯示強度
const byte SCANLIMIT = 0xB; // 掃描限制
const byte SHUTDOWN = 0xC; // 停機
const byte DISPLAYTEST = 0xF; // 顯示器檢測
// 設定 MAX7219 暫存器資料的自訂函數
const byte CS = 5;
void max7219 (const byte reg, const byte data) {
digitalWrite (CS, LOW);
SPI.transfer (reg);
SPI.transfer (data);
digitalWrite (CS, HIGH);
}
// 捲動字元
void scroll(byte chr) {
for (byte j = 0; j<8; j++) {
for (byte i=0; i<7; i++) {
buffer[i] = buffer[i+1];
max7219 (i + 1, buffer[i]);
}
buffer[7] = fonts[chr][j];
max7219 (8, buffer[7]);
delay(100);
}
}
void setup () {
SPI.begin (); // 啟動 SPI 連線
pinMode(CS, OUTPUT);
max7219 (SCANLIMIT, 7); // 設定掃描 8 行
max7219 (DECODEMODE, 0); // 不使用 BCD 解碼
max7219 (INTENSITY, 8); // 設定成中等亮度
max7219 (DISPLAYTEST, 0); // 關閉顯示器測試
max7219 (SHUTDOWN, 1); // 關閉停機模式(亦即,「開機」)
// 清除顯示畫面(LED 矩陣中的八行都設定成 0)
for (byte i=0; i < 8; i++) {
max7219 (i + 1, 0);
}
}
void loop () {
byte chr;
// 從 msg 陣列的第 0 個字元開始,每次從中取出一個字...
for (int i = 0; i < msgSize; i++) {
chr = msg[i];
scroll(chr);
}
}
// ///////////////////////////////////////////////////////////////////////////////////////////
// //// SPI介面(序列周邊介面) 與 MAX7219
// //// 控制多個LED矩陣1個畫面
// // 引用arduino內建 SPI 程式庫
// #include<SPI.h>
// //// 接線
// // CS : GPIO5
// // CLK : GPIO18
// // DATA(MOSI) : GPIO23
// const byte CS = 5; // Chip Select晶片選擇線(SS周邊選擇線)
// const int deviceNnm = 4; //串連設備數
// //// 繪圖資料
// // 矩陣參數生成網站
// // https://www.riyas.org/2013/12/online-led-matrix-font-generator-with.html
// // 音符繪圖
// const byte symbol[8] = {0x18,0x1c,0x1e,0x13,0x70,0xf0,0xf0,0x60};
// //// bit reversal
// // 將資料位元翻轉成所需的順位(高位-低位? 低位- 高位?)
// byte reverse(byte b){
// b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
// b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
// b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
// return(b);
// };
// //// MAX7219暫存器位址(16進制)
// // 資料暫存器位址為 0x1~0x8
// const byte NOOP = 0x0; // 不運作
// const byte DECODEMODE = 0x9; // 解碼模式
// const byte INTENSITY = 0xA; // 顯示強度
// const byte SCANLIMIT = 0xB; // 掃描限制
// const byte SHUTDOWN = 0xC; // 停機
// const byte DISPLAYTEST = 0xF; // 顯示器檢測
// //// 設定 MAX7219 暫存器資料的自訂函數
// // MAX7219每次接收16位元的數據
// // reg 為暫存器的位址 ; data 為要傳送的資料
// void max7219(byte reg, byte data, int x = deviceNnm){
// digitalWrite(CS, LOW); // 傳送或接收資料前CS腳位需設為0
// for(int i = 1; i < x; i++){
// SPI.transfer(NOOP);
// SPI.transfer(0x00);
// }
// SPI.transfer(reg); // 傳送暫存器的位址
// SPI.transfer(reverse(data)); // 傳送資料
// // SPI.transfer(data); // 傳送資料
// for(int i = deviceNnm; i > x; i--){
// SPI.transfer(NOOP);
// SPI.transfer(0x00);
// }
// digitalWrite(CS, HIGH); // 傳送結束CS腳位需設為1
// }
// void setup() {
// pinMode(CS, OUTPUT); // 設定CS腳位為輸出模式
// digitalWrite(CS, HIGH); // CS腳位設為高電位表示尚不傳輸
// SPI.begin(); // 啟動SPI連線
// max7219(DECODEMODE, 0); // 解碼模式 // 設定為0表示不使用BCD解碼
// max7219(INTENSITY, 8); // 顯示強度 // 設定亮度0~15
// max7219(SCANLIMIT, 7); // 掃描限制 // 設定掃描顯示器的個數0~7,設定為7為顯示LED矩陣所有行數8行
// max7219(SHUTDOWN, 1); // 停機 // 關閉停機模式,亦即開機
// //max7219(DISPLAYTEST, 1); // 顯示器檢測 // 開啟顯示器檢測點亮所有LED
// //delay(1000);
// max7219(DISPLAYTEST, 0); // 顯示器檢測 // 關閉顯示器檢測
// // 清除顯示畫面(LED矩陣中的8行都設為0)
// for(byte i = 0; i < 8; i++){
// max7219(i + 1 , 0);
// }
// // 顯示自訂圖像
// for(byte i = 0; i < 8; i++){
// max7219(i + 1 , symbol[i], 2);
// }
// for(byte i = 0; i < 8; i++){
// max7219(i + 1 , symbol[i], 1);
// }
// }
// void loop() {
// }