LedControl and MAX7219

Hi all,

I tried to put together a 3 digit 7 segment display using the LedControl library and a MAX7219 driver for a GPS speedo project but it doesn't work and I don't know why.

I followed all the directions on the 7219 wiring schematic and have used all the default pins on the Arduino Dumilanove. I have triple checked the wiring. I am using Dig0 to 2.

Just for testing the display I ran the code example from the library. All the segments of all 3 digits blink in a pattern but none of the actual characters are displayed.

I have 5v on the 7219 Vcc and am powering the Arduino from a 6v supply.

I am using these common cathode leds http://au.element14.com/avago-technologies/hdsp-c1a3/led-display-25-4mm-deep-red-cc/dp/1830037?Ntt=hdsp+c1a3

If I power the leds individually they work fine with the positive of the supply on the segment and the common to ground.

I measured the output pins from the 7219 relative to ground and there is 5v on all the digit pins and the segment pins are grounded.

This seems back to front to me as the current needs to source from the segment pins of the 7219 through the leds and sink back to the digit pins to make the leds light.

Should I have bought common anode 7 segment displays?

Please help,
Matt.

This is the code;

//We always have to include the library
#include "LedControl.h"

/*
 Now we need a LedControl to work with.
 ***** These pin numbers will probably not work with your hardware *****
 pin 12 is connected to the DataIn 
 pin 11 is connected to the CLK 
 pin 10 is connected to LOAD 
 We have only a single MAX72XX.
 */
LedControl lc=LedControl(12,11,10,1);

/* we always wait a bit between updates of the display */
unsigned long delaytime=250;

void setup() {
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);
}


/*
 This method will display the characters for the
 word "Arduino" one after the other on digit 0. 
 */
void writeArduinoOn7Segment() {     
  lc.setChar(0,0,'a',false);
  delay(delaytime);
  lc.setRow(0,0,0x05);
  delay(delaytime);
  lc.setChar(0,0,'d',false);
  delay(delaytime);
  lc.setRow(0,0,0x1c);
  delay(delaytime);
  lc.setRow(0,0,B00010000);
  delay(delaytime);
  lc.setRow(0,0,0x15);
  delay(delaytime);
  lc.setRow(0,0,0x1D);
  delay(delaytime);
  lc.clearDisplay(0);
  delay(delaytime);
} 

/*
  This method will scroll all the hexa-decimal
 numbers and letters on the display. You will need at least
 four 7-Segment digits. otherwise it won't really look that good.
 */
void scrollDigits() {
  for(int i=0;i<13;i++) {
    lc.setDigit(0,3,i,false);
    lc.setDigit(0,2,i+1,false);
    lc.setDigit(0,1,i+2,false);
    lc.setDigit(0,0,i+3,false);
    delay(delaytime);
  }
  lc.clearDisplay(0);
  delay(delaytime);
}

void loop() { 
  writeArduinoOn7Segment();
  scrollDigits();
}
void setup() {
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);
}

I see no pinModes for data clock and load?

According to the directions,

You don't have to initialize the pins as outputs or set them to a certain state, the library will do that for you.

I noticed on someone elses project they were using the Arduino 5v to drive their display whereas I have used a separate regulator with a common ground. I might try changing that next.

The MAX7219 is set up to be driven from the SPI 'port'. Does that library use SPI?
If so, how do you have the SPI pins wired up?

13 is the arduino clock output
12 is the arduino data in line; not used here, the mAX7219 does output anything
11 is the arduino data out line
10 is the arduino SS/CS line to the MAX7219

If SPI port is being used, these pins are incorrect for a standard arduino:
LedControl lc=LedControl(12,11,10,1);

I use a MAX7221 in my application, and instead of a library I just wrote my own code:

#include <SPI.h>

int SS = 10;  // need for SPI
// the digits the MAX7221 writes out
int minutes_tens=0;  // decimalpoint = colon
int minutes_ones=0;  // decimalpoint = left_priority
int seconds_tens=0;  // decimalpoint = right_priority
int seconds_ones=0;  // decimal point = swap
int leftscore_tens=0;  // decimalpoint = left_yellow
int leftscore_ones=0; // decimalpoint = left_red
int rightscore_tens=0;  // decimalpoint = right_red
int rightscore_ones=0;  // decimalpoint = right_yellow

// addresses for the MAX7221, and the values/ranges to write in

#define DECODE_MODE 0x09 // write data 0xFF, Code B Decode for all digits
#define INTENSITY_ADDRESS 0x0A // 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)
#define SCANLIMIT_ADDRESS 0x0B // 0xFF, all 8 digits on
#define SHUTDOWN_ADDRESS 0x0C  // 0x01, normal operation (0x01 = shutdown) - powers up in shutdown mode

#define DISPLAYTEST_ADDRESS 0x0F // 0x01 = all lights on full, 0x00 = normal ops
#define leftscore_tens_address 0x01 // digit 0, leftscore_tens+left_yellow, fill right hand byte with data to display
// data = 0-9, A='-', B='E', C='H', D='L', E='P', F=blank
#define leftscore_ones_address 0x02 // digit 1, leftscore_ones+right_yellow
#define rightscore_tens_address 0x03 // digit 2, rightscore_tens+right_red
#define rightscore_ones_address 0x04 // digit 3, rightscore_ones+right_yellow
#define minutes_tens_address 0x05 // digit 4, minutes_tens+colon
#define minutes_ones_address 0x06 // digit 5, minutes_ones+left_priority
#define seconds_tens_address 0x07 // digit 6, seconds_tens+right_priority
#define seconds_ones_address 0x08 // digit 7, seconds_ones+swap
void setup() // stuff that runs once before looping forever
{
  // start up SPI to talk to the MAX7221
  SPI.begin(); // nothing in () because we are the master
  pinMode(SS, OUTPUT);  // Slave Select for SPI

  //  MAX7221: write shutdown register  
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SHUTDOWN_ADDRESS);  // select the Address,
  SPI.transfer(0x00);      // select the data, 0x00 = Outputs turned off
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  // Serial.println("shutdown register, dislays off");

  // put known values into MAX7221 so doesn't have weird display when actually turned on
  // 0x0F = blank digit
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(leftscore_tens_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(leftscore_ones_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(rightscore_tens_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip  

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(rightscore_ones_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(minutes_tens_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(minutes_ones_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data 
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(seconds_tens_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip  

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(seconds_ones_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data 
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

  //  MAX7221: 
  //  write intensity register
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(INTENSITY_ADDRESS);  // select the Address,
  SPI.transfer(intensity);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("intensity register ");

  // write scanlimit register
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SCANLIMIT_ADDRESS);  // select the Address,
  SPI.transfer(0xFF);      // select the data - FF = all 8 digits                       <<< change this if you only use 3 digits
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("scanlimit register ");

  // write decode register
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(DECODE_MODE);  // select the Address,
  SPI.transfer(0xFF);      // select the data - FF = all 8 digits               <<< change this if you only use 3 digits
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("decode register ");

  //display test
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(DISPLAYTEST_ADDRESS);  // select the Address,
  SPI.transfer(0x01);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("digit display test on ");
  delay (100);

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(DISPLAYTEST_ADDRESS);  // select the Address,
  SPI.transfer(0x00);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("digit display test off ");
  delay (100);

  // write shutdown register for normal display operations
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SHUTDOWN_ADDRESS);  // select the Address,
  SPI.transfer(0x01);      // select the data, 0x01 = Normal Ops
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("shutdown register, displays on ");

My void loop() does a bunch of things - reads buttons, checks for serial messages, and updates the display.
When I make a change to a digit based on button presses or a serial message, I set a flag. The update display code checks that flag and sends an SPI message like this to update the registers.
You can do the same for each individual register, or just update all 3 if any one changes.

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(seconds_ones_address);  // select the Address,
  SPI.transfer(0x0F);      // select the data 
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

CrossRoads:
The MAX7219 is set up to be driven from the SPI 'port'. Does that library use SPI?
If so, how do you have the SPI pins wired up?

I'm guessing this: http://arduino.cc/playground/Main/MAX72XXHardware

Interested, because I'm going to be going down the same road, but maybe use the AS1107 instead.

" The three signal lines (DIn,CLK,Load(/CS)) have to be connected to three digital outputs on the Arduino board. It depends on the software which Arduino pins have to be used. For the exact pin-numbers you have to refer to the documentation of the library or the example code on which you build your project. With most of the libraries for the MAX72XX you are free to choose any pins you like. "

Why, why, why? The part is set up to accept a fast hardware-hardware interface, why not use it?

Where are you getting them? I worked thru their cart for a price for 1:

Subtotal

$ 6.81

Shipping Fee

$ 29.90 <<<<<<<<<<<<< whooooooaaaa, not working for me!

Order total

$ 36.71

@ justjed. Yep that's the one. It should just work.

@CrossRoads. Sorry most of your reply was lost on me, I have very little programming experience. Thanks though, I will read through it to see if it can help me. Also, I have wired to pins 12,11 and 10 for DIn,CLK and Load. I believe I am free to choose any pins for these but they advise not to use 1, 2 or 13. All the examples use 12,11,10.

I modified the supplies so the driver and leds are powered by the arduino 5v but it didn't help.
Intrestingly I got a different display if I powered the arduino by the 6v socket or via USB.

CrossRoads:
Why, why, why? The part is set up to accept a fast hardware-hardware interface, why not use it?

Sorry, not following you there. The LED Control library implements SPI, AFAICT. (No, I don't see it including SPI.h, but I see lots of lines doing 'spi' stuff, and

/*

  • Now we create a new LedControl.
  • We use pins 12,11 and 10 on the Arduino for the SPI interface

ETA: If you were questioning using the 1107, I would include a couple in my next order of multiple items, from Digikey. Though they stock only the SOIC package, and I'd rather get DIP, so maybe I'd get the 7221 anyway. But at half the price, it's tempting. Particularly if I order 3 -- I have a couple places to use a 4-digit, 7-segment display, and I figure I should plan on burning one, so ordering 3 of each, along with misc. other stuff. No, I'm not planning on paying $20+ shipping for 1 IC. :slight_smile:

narcas:
Intrestingly I got a different display if I powered the arduino by the 6v socket or via USB.

You mean the barrel jack?

http://arduino.cc/en/Main/ArduinoBoardDuemilanove:
The board can operate on an external supply of 6 to 20 volts. If supplied with less than 7V, however, the 5V pin may supply less than five volts and the board may be unstable. If using more than 12V, the voltage regulator may overheat and damage the board. The recommended range is 7 to 12 volts.

The LED Control library implements SPI, AFAICT. (No, I don't see it including SPI.h, but I see lots of lines doing 'spi' stuff, and

Okay, since the library allows the user to select the pins used

    /* Data is shifted out of this pin*/
    int SPI_MOSI;
    /* The clock is signaled on this pin */
    int SPI_CLK;
    /* This one is driven LOW for chip selectzion */
    int SPI_CS;

    /* 
     * Create a new controler 
     * Params :
     * dataPin		pin on the Arduino where data gets shifted out
     * clockPin		pin for the clock
     * csPin		pin for selecting the device 
     * numDevices	maximum number of devices that can be controled
     */
    LedControl(int dataPin, int clkPin, int csPin, int numDevices=1);

and there is NO mention of setting the SPI register, or the data rate it will use, that says to me this library is only doing software bit-banging for the SPI function and not taking advantage of the much faster hardware SPI built into the ATMega.

CrossRoads:
... not taking advantage of the much faster hardware SPI built into the ATMega.

Gotcha. I'll make sure I keep that in mind, since I'll be using it quite a bit.

justjed:
You mean the barrel jack?

http://arduino.cc/en/Main/ArduinoBoardDuemilanove:
The board can operate on an external supply of 6 to 20 volts. If supplied with less than 7V, however, the 5V pin may supply less than five volts and the board may be unstable. If using more than 12V, the voltage regulator may overheat and damage the board. The recommended range is 7 to 12 volts.

Thanks for this. I'll check it out.

Success! 8)

Thanks so much CrossRoads. I copied in your code and modified it to suit my 3 digit display and it worked.
I wrote some basic loop code so it counts from 1 to 9 across the 3 digits to test and I'm a happy camper.

I'm still buggered if I know why the library wouldn't work but that doesn't matter now.

Cheers,
Matt

#include <SPI.h>

int SS = 10;  // need for SPI
// the digits the MAX7221 writes out
int tenths=0;  
int ones=0;  
int tens=0;  

// addresses for the MAX7221, and the values/ranges to write in

#define DECODE_MODE 0x09 // write data 0xFF, Code B Decode for all digits
#define INTENSITY_ADDRESS 0x0A // 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)
#define SCANLIMIT_ADDRESS 0x0B // 0xFF, all 8 digits on
#define SHUTDOWN_ADDRESS 0x0C  // 0x01, normal operation (0x01 = shutdown) - powers up in shutdown mode

#define DISPLAYTEST_ADDRESS 0x0F // 0x01 = all lights on full, 0x00 = normal ops
#define tenths 0x01 // digit 0, fill right hand byte with data to display
// data = 0-9, A='-', B='E', C='H', D='L', E='P', F=blank
#define ones 0x02 // digit 1
#define tens 0x03 // digit 2




void setup() // stuff that runs once before looping forever
{
  // start up SPI to talk to the MAX7221
  SPI.begin(); // nothing in () because we are the master
  pinMode(SS, OUTPUT);  // Slave Select for SPI

  //  MAX7221: write shutdown register  
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SHUTDOWN_ADDRESS);  // select the Address,
  SPI.transfer(0x00);      // select the data, 0x00 = Outputs turned off
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  // Serial.println("shutdown register, dislays off");

  // put known values into MAX7221 so doesn't have weird display when actually turned on
  // 0x0F = blank digit
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(tenths);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);  // take the SS pin high to de-select the chip



  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(ones);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip



  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(tens);  // select the Address,
  SPI.transfer(0x0F);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip  




  //  MAX7221: 
  //  write intensity register
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(INTENSITY_ADDRESS);  // select the Address,
  SPI.transfer(0x09);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("intensity register ");

  // write scanlimit register
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SCANLIMIT_ADDRESS);  // select the Address,
  SPI.transfer(0x02);      // select the data - FF = all 8 digits, 02 only 3 digits
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("scanlimit register ");

  // write decode register
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(DECODE_MODE);  // select the Address,
  SPI.transfer(0xFF);      // select the data - FF = all 8 digits               <<< change this if you only use 3 digits
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("decode register ");

  //display test
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(DISPLAYTEST_ADDRESS);  // select the Address,
  SPI.transfer(0x01);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("digit display test on ");
  delay (100);

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(DISPLAYTEST_ADDRESS);  // select the Address,
  SPI.transfer(0x00);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("digit display test off ");
  delay (100);

  // write shutdown register for normal display operations
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(SHUTDOWN_ADDRESS);  // select the Address,
  SPI.transfer(0x01);      // select the data, 0x01 = Normal Ops
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip:
  //Serial.println("shutdown register, displays on ");

}


void loop ()

{




  // 0x0F = blank digit
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(tenths);  // select the Address,
  SPI.transfer(1);      // select the data
  digitalWrite(SS,HIGH);  // take the SS pin high to de-select the chip
  delay(250);


  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(ones);  // select the Address,
  SPI.transfer(2);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip
  delay(250);


  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(tens);  // select the Address,
  SPI.transfer(3);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip  
  delay(250);

  // 0x0F = blank digit
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(tenths);  // select the Address,
  SPI.transfer(4);      // select the data
  digitalWrite(SS,HIGH);  // take the SS pin high to de-select the chip
  delay(250);


  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(ones);  // select the Address,
  SPI.transfer(5);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip
  delay(250);


  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(tens);  // select the Address,
  SPI.transfer(6);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip  
  delay(250);

  // 0x0F = blank digit
  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(tenths);  // select the Address,
  SPI.transfer(7);      // select the data
  digitalWrite(SS,HIGH);  // take the SS pin high to de-select the chip
  delay(250);


  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(ones);  // select the Address,
  SPI.transfer(8);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip
  delay(250);


  digitalWrite(SS,LOW);  // take the SS pin low to select the chip:
  SPI.transfer(tens);  // select the Address,
  SPI.transfer(9);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip  
  delay(1000);




}

Cool. Glad to see you have it working.

I think max7219 is not SPI.
7221 is.

db2db:
I think max7219 is not SPI.
7221 is.

Why do you think that?

Look at the data sheet:
"The MAX7219/MAX7221 are compact, serial input/out-put common-cathode display drivers that interface
microprocessors (µPs) to 7-segment numeric LED dis-plays of up to 8 digits, bar-graph displays, or 64 indi-vidual LEDs. Included on-chip are a BCD code-B decoder, multiplex scan circuitry, segment and digit drivers, and an 8x8 static RAM that stores each digit.Only one external resistor is required to set the seg-ment current for all LEDs.

The MAX7221 is compatible with SPI™, QSPI™, and MICROWIRE™, and has slew-rate-limited segment drivers to reduce EMI."

"MAX7219/MAX7221 Differences: The MAX7219 and MAX7221 are identical except for two parameters: the MAX7221 segment drivers are
slew-rate limited to reduce electromagnetic interference (EMI), and its serial interface is fully SPI compatible."

I read that as close to SPI, but not exactly.

Must be close enough, as OP narcas was able to use some simple SPI commands I wrote to set up and control a '7221 to do the same for his '7219:

"Success!

Thanks so much CrossRoads. I copied in your code and modified it to suit my 3 digit display and it worked."

Reading the datasheet some more, there is just subtle variation on the Load pin and the Clock pin work. Taking the Load pin low before clocking data out and then back high again after clocking is done works for either chip;

7219: Load-Data Input. The last 16 bits of serial data are latched on LOAD’s rising edge.
7221: Chip-Select Input. Serial data is loaded into the shift register while CS is low. The last 16 bits of
serial data are latched on CS’s rising edge.

Serial-Clock Input. 10MHz maximum rate. On CLK’s rising edge, data is shifted into the internal
shift register. On CLK’s falling edge, data is clocked out of DOUT.
On the MAX7221, the CLK input is active only while CS is low. >>> On the 7219, this becomes a don't care as the Load-Data pin is used to clock data into the output register only when commnanded.