本次的主角就是 8x8 矩陣顯示器:
不過如果只有 8x8 矩陣顯示器 是很難單獨運作的,必須要靠 MAX7219 這塊 IC 來處理字元的輸入與顯示。
組合在一起於是有了模組。
接線方式如下圖:
顯示結果如下影片:
參考網頁:
https://docs.labs.mediatek.com/resource/linkit7697-arduino/zh_tw/tutorial/driving-8x8-dot-matrices-with-max7219
https://forum.arduino.cc/t/max7219-led-matrix-rotate-text-8x8/438719
https://lastminuteengineers.com/max7219-dot-matrix-arduino-tutorial/
https://code.google.com/archive/p/arudino-maxmatrix-library/wikis/Example_Display_Characters.wiki
https://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf
程式如下:
//
// Use one MAX7219 to control a 8x8 dot matrix
// http://www.icshop.com.tw/product_info.php/products_id/13181
//
// MAX7219 datasheet: https://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf
//
// the MAX7219 address map (datasheet table 2)
#define MAX7219_DECODE_REG (0x09)
#define MAX7219_INTENSITY_REG (0x0A)
#define MAX7219_SCANLIMIT_REG (0x0B)
#define MAX7219_SHUTDOWN_REG (0X0C)
#define MAX7219_DISPLAYTEST_REG (0x0F)
#define MAX7219_DIGIT_REG(pos) ((pos) + 1)
#define MAX7219_COLUMN_REG(pos) MAX7219_DIGIT_REG(pos)
// shutdown mode (datasheet table 3)
#define MAX7219_OFF (0x0)
#define MAX7219_ON (0x1)
// pin 13 of MAX7219 (CLK)
const int clock_pin = 8;
// pin 12 of MAX7219 (LOAD)
const int data_latch_pin = 9;
// pin 1 of MAX7219 (DIN)
const int data_input_pin = 10;
// number of columns of the display matrx
#define NUM_OF_COLUMNS (8)
// for each character bitmap, it consumes 4 bytes
#define BYTE_PER_MAP (5)
// matrix pattern for "Samba"
const byte char_pattern[] =
{
B1000110, B1001001, B1001001, B0110010, B0000000, // S
B0100000, B1010100, B1010100, B1111000, B0000000, // a
B1111100, B0000100, B1111100, B0000100, B1111000, // m
B1111111, B1000100, B1000100, B0111000, B0000000, // b
B0100000, B1010100, B1010100, B1111000, B0000000, // a
B0000000, B0000000, B0000000, B0000000, B0000000, // space
};
#define DISPLAY_STR_LENGTH (sizeof(char_pattern) / BYTE_PER_MAP)
// update the register value of MAX7219
void set_register(byte address, byte value)
{
digitalWrite(data_latch_pin, LOW);
shiftOut(data_input_pin, clock_pin, MSBFIRST, address);
shiftOut(data_input_pin, clock_pin, MSBFIRST, value);
digitalWrite(data_latch_pin, HIGH);
}
void clear_matrix()
{
// clear the dot matrix
for (int i = 0; i < NUM_OF_COLUMNS; i++)
{
set_register(MAX7219_COLUMN_REG(i), B00000000);
}
}
void init_max7219()
{
// disable test mode. datasheet table 10
set_register(MAX7219_DISPLAYTEST_REG, MAX7219_OFF);
// set medium intensity. datasheet table 7
set_register(MAX7219_INTENSITY_REG, 0xf);
// turn off display. datasheet table 3
set_register(MAX7219_SHUTDOWN_REG, MAX7219_OFF);
// drive 8 digits. datasheet table 8
set_register(MAX7219_SCANLIMIT_REG, 7);
// no decode mode for all positions. datasheet table 4
set_register(MAX7219_DECODE_REG, B00000000);
// clear matrix display
clear_matrix();
}
void setup()
{
// init pin states
pinMode(clock_pin, OUTPUT);
pinMode(data_latch_pin, OUTPUT);
pinMode(data_input_pin, OUTPUT);
// init MAX2719 states
init_max7219();
}
unsigned int char_index = 0;
void loop()
{
int i;
// turn off display first
set_register(MAX7219_SHUTDOWN_REG, MAX7219_OFF);
// display one bitmap
for (i = 0; i < BYTE_PER_MAP; i++)
{
// starting from column 2
set_register(MAX7219_COLUMN_REG(2 + i), char_pattern[char_index * BYTE_PER_MAP + i]);
}
// turn on display
set_register(MAX7219_SHUTDOWN_REG, MAX7219_ON);
// step to the next character
char_index++;
// wrap around the character if needed
if (char_index >= DISPLAY_STR_LENGTH)
{
char_index = 0;
}
delay(666);
}