🤖
LinkIt 7697 BlocklyDuino 使用指南
  • LinkIt 7697 BlocklyDuino 使用指南
    • 認識 LinkIt 7697
    • 認識 BlocklyDuino
    • BlocklyDuino v2 & v3 比較
    • 安裝開發環境 (v2)
      • 安裝 Arduino 編輯器
      • 安裝驅動並連接開發板
      • 安裝 BlocklyDuino 編輯器
      • 連結兩個編輯器並上傳程式
    • 安裝開發環境 (v3)
    • BlocklyDuino 基礎操作
    • 實作範例教學
      • A01. 內建 LED 閃爍
      • A02. 外接 LED 閃爍
      • A03. 外接 LED 呼吸燈
      • A04. RGB LED 顏色變化
      • A05. 外部按鈕控制開關
      • A06. 蜂鳴器播放聲音
      • A07 .可變電阻控制電壓輸出
      • A08. 伺服馬達控制
      • A21. DHT: 溫濕度感應器
      • A22. HTU21D: 溫溼度感應器
      • A23. PMSX003: PM2.5 感測器
      • A24. HC-SR04P: 超音波測距
      • A25. ADXL345: 加速規(動態)
      • A26. ADXL345: 加速規(手勢)
      • A27. 1602/2004: 液晶顯示模組
      • A28. WS2812: RGB 彩色燈條
      • A29. MFRC522: RFID
      • B00. Grove 相關基礎知識
      • B01. Grove 光感應器
      • B02. Grove 超音波測距感應器
      • B03. Grove 溫溼度感應器
      • B04. Grove 繼電器
      • B05. Grove LED 燈條
      • B06. Grove OLED 顯示器
      • C01. 雲端控制 LED 開關
      • C02. 上傳溫溼度到雲端
      • D01. 手機透過 BLE 讀寫裝置資料
      • E01. 遙控器: 按鈕控制 LED
    • 資源鏈結
  • LinkIt 7697 - Arduino IDE 開發指南
    • 環境設定
      • 設定 Arduino IDE
      • 將 LinkIt 7697 連接到電腦
        • 在 Windows 上安裝 CP2102N 驅動程式
        • 在 macOS 上安裝 CP2102N 驅動程式
      • 執行第一個程式
    • 開發指南
      • GPIO
      • UART
      • ADC
      • EINT (外部中斷 / External Interrupt)
      • I2C
      • SPI
      • EEPROM
      • Timer
      • Flash (索引式儲存空間)
      • RTC (Real-Time Clock)
      • Software Serial
      • 使用 Wi-Fi 函式庫
      • 使用 MCS 函式庫
        • 連接到 MCS
        • 連接到 MCSLite
          • 建立可透過 MCS Lite 控制的 Beacon
        • MCS 函式庫 API 使用手冊
          • MCSDevice
          • MCSLiteDeviceMCSLiteDevice
          • MCSDataChannel 相關類別
      • 使用 BLE 低功耗藍牙
        • 藍牙信標
        • 主控裝置
        • 周邊裝置
        • 已知限制
        • LBLE API 指南
          • LBLE
          • LBLECentral
          • LBLEPeripheral
          • LBLEAdvertisementData
          • LBLEService
          • LBLECharacteristic
          • LBLEAddress
          • LBLEUuid
          • LBLEClient
      • 使用 LinkIt Remote
        • LRemote API
        • LRemote 控制元件 API
      • LinkIt 7697 腳位的初始狀態
      • LinkIt 7697 供電說明
      • 更新 Bootloader 與韌體
      • Flash 燒錄工具
      • FOTA 更新
      • LinkIt 7697 的功能限制
      • 自行編譯 Arduino Package
      • 回報問題
    • 週邊元件連接教學
      • SMD 按鈕
      • RGB 三色 LED
      • 可變電阻
      • 九軸感應器 (MPU-9250)
      • 溫度與濕度感應器 (AM2302)
      • 超音波距離感應器
      • 光感應器 (LM358)
      • 0.96 吋 OLED 顯示模組 (SSD1308Z)
      • 長條型 LED 顯示模組 (MY9221)
      • 繼電器
      • 伺服馬達 (EMAX 9g ES08A Servo)
      • 使用 74HC595 驅動七段顯示器
      • 使用 MAX7219 驅動七段顯示器
      • 使用 MAX7219 驅動 8x8 矩陣式顯示器
      • 使用 OLED 模組 (如 SH1106 / SSD1306... 等模組)
      • 使用 PCF8574 / PCF8574A 驅動 1602 LCD
    • 開發套件與擴充板
      • Grove Starter Kit
      • Robot Shield
        • OTTO97
    • 下載
    • 資源連結
    • BSP 版本更新資訊
  • LinkIt 7697 - Development Guide for Arduino IDE
    • Environment Setup
      • Setup Arduino IDE
      • Connecting LinkIt 7697 to Computer
        • Install CP2102N Driver on Windows
        • Install CP2102N Driver on macOS
      • Run Your First Sketch
    • Developer Guide
      • GPIO
      • UART
      • ADC
      • External Interrupt
      • I2C
      • SPI
      • EEPROM
      • Timer
      • Flash (Key-Pair Storage)
      • RTC (Real-Time Clock)
      • Software Serial
      • Using the Wi-Fi Library
      • Using MCS Library
        • Connecting to MCS
        • Connecting to MCSLite
          • Build a Beacon controlled by MCS Lite
        • MCS Library API Reference
          • MCSDevice
          • MCSLiteDevice
          • MCSDataChannel Classes
      • Using Bluetooth
        • Beacons
        • Central Devices
        • Peripheral Devices
        • Limitations of LBLE library
        • LBLE Library API Guide
          • LBLE
          • LBLECentral
          • LBLEPeripheral
          • LBLEAdvertisementData
          • LBLEService
          • LBLECharacteristic
          • LBLEAddress
          • LBLEUuid
          • LBLEClient
      • Using LinkIt Remote
        • LRemote
        • LRemote Control Classes
      • Initial Pin State of LinkIt 7697
      • Powering the LinkIt 7697
      • Update Bootloader and Firmware
      • Flash Uploading Tool
      • FOTA Update
      • Limitations of LinkIt 7697
      • Source Code of Arduino Package
      • Issue Report
    • Tutorial
      • SMD Buttons
      • RGB LED
      • Potentiometer
      • IMU 9DOF v2.0 (MPU-9250)
      • Temperature and Humidity Sensor Pro (AM2302)
      • Grove Ultrasonic Ranger
      • Light Sensor (LM358)
      • Grove OLED Display 0.96" (SSD1308Z)
      • LED Bar v2.0 (MY9221)
      • Relay
      • Mini Servo (EMAX 9g ES08A Servo)
      • Driving 7-segment Displays with 74HC595
      • Driving 7-segment Displays with MAX7219
      • Driving 8x8 Dot Matrices with MAX7219
      • Using OLED module (SH1106 / SSD1306... etc.)
      • Driving 1602 LCD with PCF8574 / PCF8574A
    • Kits and Shields
      • Grove Starter Kit
      • Robot Shield
        • OTTO97
    • Download
    • Resources
    • BSP Release Notes
Powered by GitBook
On this page
  • Table of Contents
  • Command Format
  • Hardware Setup
  • Register Map
  • The Counting Example
  • Summary
  1. LinkIt 7697 - Development Guide for Arduino IDE
  2. Tutorial

Driving 7-segment Displays with MAX7219

PreviousDriving 7-segment Displays with 74HC595NextDriving 8x8 Dot Matrices with MAX7219

Last updated 3 years ago

In , we introduced the basic ideas about a seven-segment display and how to drive it with a 74HC595 shift register. In this tutorial, we'll show another LED driving IC: , which is designed to drive 7-segment displays (up to 8 digits are supported), or 64 LEDs equivalently. By modifying the example used in the 74HC595 tutorial, we will go through major functionalities of MAX7219 by using LinkIt 7697 with a (with MAX7219 built in).

Table of Contents

Command Format

Before going into details of MAX7219, let's first look at how to communicate with it. All operations on MAX7219 are triggered by commands to update the values of its registers. And all commands share a unified format: a 16-bit "register address / data value" pair format (X stands for "don't care"):

By latching the LOAD pin and sending a 16-bit command with DIN pin in 16 clocks on CLK pin, a command is thus sent into the MAX7219. The timing diagram of a command sequence is:

// define pins used on LinkIt 7697
// pin 13 of MAX7219 (CLK)
const int clock_pin = 15;
// pin 12 of MAX7219 (LOAD)
const int data_latch_pin = 16;
// pin 1 of MAX7219 (DIN)
const int data_input_pin = 17;
 
// 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);
}

Hardware Setup

5 pins are needed from LinkIt 7697 to communicate with the 8-digit display module:

  • 5V

  • GND

  • P15

  • P16

  • P17

And they are connected to:

  • VCC

  • GND

  • CLK

  • CS (i.e. LOAD pin of MAX7219)

  • DIN

pins of the display module, respectively:

5V power is needed for the display module. If 3.3V is supplied, there would be a decrease in the display brightness of the module.

Register Map

For controlling the display, several registers of MAX7219 need to be set correctly. In the example of this tutorial, six types of registers will be accessed:

Name / Functionality
Address
Description

Decode Mode

0x09

Turn on / off the decode mode

Intensity

0x0A

Adjust the brightness of the display

Scan Limit

0x0B

Determine how many digits are enabled

Shutdown

0x0C

Turn on / off the display module

Display Test

0x0F

Enter the test mode (all LED segments light on) or not

Digit 0 ~ Digit 7 data

0x01 ~ 0x08

The address to control digit 0 ~ digit 7

And they are defined in the Arduino code as:

// the MAX7219 address map (datasheet table 2)
#define MAX7219_DECODE_REG      (0x09)
#define MAX7219_DIGIT_REG(pos)  ((pos) + 1)
#define MAX7219_INTENSITY_REG   (0x0A)
#define MAX7219_SCANLIMIT_REG   (0x0B)
#define MAX7219_SHUTDOWN_REG    (0X0C)
#define MAX7219_DISPLAYTEST_REG (0x0F)

For each of those registers, here we show some examples of applications:

Decode Mode (0x09)

MAX7219 supports two types of input data for each digit: 1) raw data or 2) BCD Code B. And each digit can run in different modes. For example:

set_register(MAX7219_DECODE_REG, B00011010);

Because only bit 1, 3 and 4 are set to 1, this command sets Digit 1 / 3 / 4 to BCD Code B decode mode and leaves Digit 0 / 2 / 5 / 6 / 7 to non-decode (raw data) mode.

Digit 0 ~ Digit 7 data (0x01 ~ 0x08)

In the raw data mode, users control all segments of a 7-segment display by themselves as what they did with 74HC595:

For instance, if a character "7" is going to be displayed on Digit 3, the segements "A", "B" and "C" (refer to the figure above) needs to be turned on, which means bit 6, bit 5 and bit 4 for the data byte of Digit 3 register need to be 1:

set_register(MAX7219_DIGIT_REG(3), B01110000);

Although the raw mode adds complexities to describe the display data, it provides the flexibility for users to define all display patterns they need as below:

On the other hand, for the decode mode, characters defined in the BCD Code B set (see the table below) can be recognized by MAX7219 and indexed by a single value directly:

*For displaying the decimal point, set the bit 7 (D7) to 1 no matter in decode mode or in raw data mode.

That is, you can ask MAX7219 to drive the display to show 16 different characters: "0" to "9", "-", "E", "H", "L", "P" and " " (blank) directly without specifying segment data by yourself. For example to show a character "E", first configure Digit 5 to decode mode and set value 11 (B1011, see the table above) to the data byte of Digit 5, this makes it display the "E" character:

// Make Digit 5 is under BCD Code B decode mode
set_register(MAX7219_DECODE_REG, B00100000);
// Make it display character "E"
set_register(MAX7219_DIGIT_REG(5), 11);

Intensity (0x0A)

Define the LED brightness of the display. The valid range is between 0x0 ~ 0xF.

// Dimmest
set_register(MAX7219_INTENSITY_REG, 0x0);
// Brightest
set_register(MAX7219_INTENSITY_REG, 0xF);

Scan Limit (0x0B)

Use this value to decide how many digits are turned on for display. Here are some examples:

// Only Digit 0 are turned on
set_register(MAX7219_SCANLIMIT_REG, 0);
// Only Digit 0 ~ Digit 4 are turned on
set_register(MAX7219_SCANLIMIT_REG, 4);
// All digits (Digit 0 ~ Digit 7) are turned on
set_register(MAX7219_SCANLIMIT_REG, 7);

Shutdown (0x0C)

Turn on / off the display:

#define MAX7219_OFF (0x0)
#define MAX7219_ON  (0x1)

// Turn off the display
set_register(MAX7219_SHUTDOWN_REG, MAX7219_OFF);
// Turn on the display
set_register(MAX7219_SHUTDOWN_REG, MAX7219_ON);

Display Test (0x0F)

Turn on the test mode makes all segments of the display light on.

// Enter test mode. No matter what data bytes of each digit register are, all display segments are on
set_register(MAX7219_DISPLAYTEST_REG, MAX7219_ON);
// Non-test mode. Display segments according to the data byte and decode mode for each digit
set_register(MAX7219_DISPLAYTEST_REG, MAX7219_OFF);

The Counting Example

Let's put everything mentioned above together and modify the example used in the 74HC595 tutorial. A hexadecimal counting example with floating decimal point is shown in the following video and with the accompanying Arduino sketch code.

//
// Use one MAX7219 to control 8-digit seven-segment display
// the display module: http://www.icshop.com.tw/product_info.php/products_id/20686
//
// 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)

// shutdown mode (datasheet table 3)
#define MAX7219_OFF             (0x0)
#define MAX7219_ON              (0x1)

// pin 13 of MAX7219 (CLK)
const int clock_pin = 15;
// pin 12 of MAX7219 (LOAD)
const int data_latch_pin = 16;
// pin 1 of MAX7219 (DIN)
const int data_input_pin = 17;

// digit pattern for a 7-segment display. datasheet table 5
const byte digit_pattern[16] =
{
  B01111110,  // 0
  B00110000,  // 1
  B01101101,  // 2
  B01111001,  // 3
  B00110011,  // 4
  B01011011,  // 5
  B01011111,  // 6
  B01110000,  // 7
  B01111111,  // 8
  B01111011,  // 9
  B01110111,  // A
  B00011111,  // b
  B01001110,  // C
  B00111101,  // d
  B01001111,  // E
  B01000111   // F
};

#define DP_FLAG       (B10000000)
#define NUM_OF_DIGITS (8)

unsigned int counter = 0;
unsigned int digit_base = 16;

// 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 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, 0x8);
  // 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);
}

void setup()  
{
  // init pin states
  pinMode(clock_pin, OUTPUT);
  pinMode(data_latch_pin, OUTPUT);    
  pinMode(data_input_pin, OUTPUT);

  // init MAX2719 states
  init_max7219();
}

void loop()  
{
  int i;
  unsigned int number;
  unsigned int digit_value;
  byte byte_data;
  
  number = counter++;
  
  // turn off display first
  set_register(MAX7219_SHUTDOWN_REG, MAX7219_OFF);

  // get every values in each position of those 8 digits based on "digit_base"
  //
  // digit_base should be <= 16
  //
  // for example, if digit_base := 2, binary values will be shown. If digit_base := 16, hexidecimal values will be shown
  //
  for (i = 0; i < NUM_OF_DIGITS; i++)
  {
    digit_value = number % digit_base;
    number /= digit_base;

    byte_data = digit_pattern[digit_value];

    if (counter % NUM_OF_DIGITS == i)
    {
      byte_data |= DP_FLAG;
    }

    set_register(MAX7219_DIGIT_REG(i), byte_data);
  }

  // turn on display
  set_register(MAX7219_SHUTDOWN_REG, MAX7219_ON);
  
  delay(50);
}

The default parameters of the setup are:

  • Count in hexadecimal mode

  • Use the raw data (non-decode) mode

  • Set to medium brightness

To change the hexadecimal mode to decimal / octal / binary counting mode, you can modify Line 52 to 10, 8 or 2. Below codes change the counting mode from hexadecimal to the decimal mode:

// change the counting mode to decimal mode
unsigned int digit_base = 10;

To enable the BCD Code B decode mode, you need to modify Line 74 and Line 111 as below:

// enable decode mode for all positions. datasheet table 4
set_register(MAX7219_DECODE_REG, B11111111);

and

digit_value = number % digit_base;
number /= digit_base;
// no need to get the raw segment patterns. use the value directly to index the BCD code
byte_data = digit_value; // byte_data = digit_pattern[digit_value];

Summary

This operation can be coded as below in Arduino. The API is used to send bits with clock pulses:

By going through this tutorial, major functionalities of MAX7219 are introduced. Although it's designed to drive 7-segment displays, it can also be used to drive LEDs in a more general scenario. For example, a is another popular application which uses MAX7219 as the driving IC. This gives a good demonstration about how to use the raw data mode on driving such matrix displays. And we will take a closer look at it with another tutorial.

a previous tutorial
MAX7219
8-digit 7-segment display module
Command Format
Hardware Setup
Register Map
Decode Mode (0x09)
Digit 0 ~ Digit 7 data (0x01 ~ 0x08)
Intensity (0x0A)
Scan Limit (0x0B)
Shutdown (0x0C)
Display Test (0x0F)
The Counting Example
Summary
shiftOut()
8x8 dot-matrix display