Three Max7219 connected in daisy-chain to output ADC data

Is this Project an exercise or of real use?

Note: Do you think daisy-chain and cascade are synonymes? If not, please edit your Title of the thread.

#include <avr/io.h>
#include <util/delay.h>

// SPI initialization
void SPI_Init() {
    // Set MOSI (PB5) and SCK (PB7) as output
    DDRB |= (1<<PB5) | (1<<PB7);
    // Set SS (PB4) as output
    DDRB |= (1<<PB4);
    // Enable SPI, Master mode, set clock rate fck/16
    SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR0);
}

// Send a byte via SPI
void SPI_SendByte(uint8_t data) {
    SPDR = data;
    while (!(SPSR & (1<<SPIF)));  // Wait for transmission complete
}

// Send a command to all MAX7219s
void MAX7219_Send(uint8_t address, uint8_t data1, uint8_t data2, uint8_t data3) {
    PORTB &= ~(1<<PB4);  // SS low

    // Send data for the third display
    SPI_SendByte(address);
    SPI_SendByte(data3);

    // Send data for the second display
    SPI_SendByte(address);
    SPI_SendByte(data2);

    // Send data for the first display
    SPI_SendByte(address);
    SPI_SendByte(data1);

    PORTB |= (1<<PB4);   // SS high
}

// Initialize MAX7219
void MAX7219_Init() {
    // Initialization commands for all three MAX7219s
    MAX7219_Send(0x09, 0xFF, 0xFF, 0xFF);  // Decode mode: BCD decode for all digits
    MAX7219_Send(0x0B, 0x02, 0x02, 0x02);  // Scan limit: Display digits 0-2 (3 digits)
    MAX7219_Send(0x0C, 0x01, 0x01, 0x01);  // Shutdown: Normal operation
    MAX7219_Send(0x0F, 0x00, 0x00, 0x00);  // Display test: Off
}

// Read ADC value from a specific channel
uint16_t ADC_Read(uint8_t channel) {
    ADMUX = (1<<REFS0) | (channel & 0x07);  // AVcc as reference, select channel
    ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);  // Enable ADC, start conversion, prescaler 128
    while (ADCSRA & (1<<ADSC));  // Wait for conversion to complete
    return ADC;
}

// Display a 3-digit number on a specific display
void Display_Number(uint16_t number, uint8_t* digits) {
    digits[0] = (number / 100) % 10;
    digits[1] = (number / 10) % 10;
    digits[2] = number % 10;
}

// Display ADC values on the 3 displays
void Display_ADC_Values() {
    // Read ADC values
    uint16_t adc0 = ADC_Read(1);
    uint16_t adc1 = ADC_Read(2);
    uint16_t adc2 = ADC_Read(0);

    uint8_t digits1[3], digits2[3], digits3[3];

    // Convert ADC values to digits
    Display_Number(adc0, digits1);
    Display_Number(adc1, digits2);
    Display_Number(adc2, digits3);

    // Send each digit to the corresponding MAX7219
    for (uint8_t i = 1; i <= 3; i++) {
        MAX7219_Send(i, digits1[i-1], digits2[i-1], digits3[i-1]);
    }
}

int main() {
    SPI_Init();              // Initialize SPI
    MAX7219_Init();          // Initialize all MAX7219s

    while (1) {
        Display_ADC_Values(); // Display ADC readings on the 3 displays
        _delay_ms(500);       // Shorter delay to ensure the display updates frequently
    }
}

cool