MAX7219 led matrix

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hi, i have a problem with text scrolling on max7219. It scroll text vertically but i want to scroll from right to left. 

 

this is main.c

#include "includes.h"

#define NUM_DEVICES     8	 // Number of cascaded max7219's
#define DEL 		20000    // Delay for scrolling speed in microseconds

// Buffer array of bytes to store current display data for each column in each cascaded device
uint8_t buffer [NUM_DEVICES*8];

// Initializes SPI
void initSPI(void)
{
	DDRB |= (1 << PORTB2);	    // Set SS output
	PORTB |= (1 << PORTB2);      // Begin high (unselected)

	DDRB |= (1 << PORTB3);       // Output on MOSI
	DDRB |= (1 << PORTB5);       // Output on SCK

	SPCR |= (1 << MSTR);      // Clockmaster
	SPCR |= (1 << SPE);       // Enable SPI
	SPCR |= (1 << SPR0);      //Set clock rate fck/16
}

// Send byte through SPI
void writeByte(uint8_t byte)
{
	SPDR = byte;                      // SPI starts sending immediately
	while(!(SPSR & (1 << SPIF)));     // Loop until complete bit set
}

// Sends word through SPI
void writeWord(uint8_t address, uint8_t data)
{
	writeByte(address);	// Write first byte
	writeByte(data);      // Write Second byte
}

// Initializes all cascaded devices
void initMatrix()
{
	uint8_t i;	// Var used in for loops

	// Set display brighness
	SLAVE_SELECT;
	for(i = 0; i < NUM_DEVICES; i++)   // Loop through number of cascaded devices
	{
		writeByte(0x0A); // Select Intensity register
		writeByte(0x07); // Set brightness
	}
	SLAVE_DESELECT;

	// Set display refresh
	SLAVE_SELECT;
	for(i = 0; i < NUM_DEVICES; i++)
	{
		writeByte(0x0B); // Select Scan-Limit register
		writeByte(0x07); // Select columns 0-7
	}
	SLAVE_DESELECT;

	// Turn on the display
	SLAVE_SELECT;
	for(i = 0; i < NUM_DEVICES; i++)
	{
		writeByte(0x0C); // Select Shutdown register
		writeByte(0x01); // Select Normal Operation mode
	}
	SLAVE_DESELECT;

	// Disable Display-Test
	SLAVE_SELECT;
	for(i = 0; i < NUM_DEVICES; i++)
	{
		writeByte(0x0F); // Select Display-Test register
		writeByte(0x00); // Disable Display-Test
	}
	SLAVE_DESELECT;
}

// Clears all columns on all devices
void clearMatrix(void)
{
	for(uint8_t x = 1; x < 9; x++) // for all columns
	{
		SLAVE_SELECT;
		for(uint8_t i = 0; i < NUM_DEVICES; i++)
		{
			writeByte(x);    // Select column x
			writeByte(0x00); // Set column to 0
		}
		SLAVE_DESELECT;
	}
}

// Initializes buffer empty
void initBuffer(void)
{
	for(uint8_t i = 0; i < NUM_DEVICES*8; i++)
	buffer[i] = 0x00;
}

// Moves each byte forward in the buffer and adds next byte in at the end
void pushBuffer(uint8_t x)
{
	for(uint8_t i = 0; i < NUM_DEVICES*8 - 1; i++)
		buffer[i] = buffer[i+1];

	buffer[NUM_DEVICES*8 - 1] = x;
}

// Pushes in 5 characters columns into the buffer.
void pushCharacter(uint8_t c)
{
	for(uint8_t i = 0; i < 5; i++)				// For 5 bytes representing each character
	{
		pushBuffer(pgm_read_byte(&characters[c][i]));   // Push the byte from the characters array to the display buffer
		displayBuffer();				// Display the current buffer on the devices
		_delay_us(DEL);					// and delay
	}
}

// Takes a pointer to the beginning of a char array holding message, and array size, scrolls message.
void displayMessage(const char *arrayPointer, uint16_t arraySize)
{
	for(uint16_t i = 0; i < arraySize; i++)
	{
		pushCharacter(pgm_read_byte_near(arrayPointer + i) - 32);	// Send converted ASCII value of character in message to index in characters array (-32 sends corrent index to characters array)
		pushBuffer(0x00);						// Add empty column after character for letter spacing
		displayBuffer();						// Display &
		_delay_us(DEL); 						// Delay
	}

}

// Displays current buffer on the cascaded devices
void displayBuffer()
{
	for(uint8_t i = 0; i < NUM_DEVICES; i++) // For each cascaded device
	{
		for(uint8_t j = 1; j < 9; j++) // For each column
		{
				SLAVE_SELECT;

				for(uint8_t k = 0; k < i; k++) // Write Pre No-Op code
				writeWord(0x00, 0x00);

				writeWord(j, buffer[j + i*8 - 1]); // Write column data from buffer

				for(uint8_t k = NUM_DEVICES-1; k > i; k--) // Write Post No-Op code
				writeWord(0x00, 0x00);

				SLAVE_DESELECT;
		}
	}
}

// Main Loop
int main(void)
{
	// Inits
	initSPI();
	initMatrix();
	clearMatrix();
	initBuffer();

	// Pointer to beginning of message
	const char *messagePointer = &message[0];

	// Size of message matrix
	uint16_t messageSize = sizeof(message);

	// Event loop
	while (1)
	{

		displayMessage(messagePointer, messageSize);	// Display the message

	}
	return (0);
}

here i have characters bits

#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>

// Macros to set SS line LOW (selected) or HIGH (deselected)
#define SLAVE_SELECT    PORTB &= ~(1 << PORTB2)
#define SLAVE_DESELECT  PORTB |= (1 << PORTB2)

// Array holding arrays of 5 Bytes for each representation of an ASCII character, stored in flash
const char characters[96][5] PROGMEM = {
	{0b00000000,0b00000000,0b00000000,0b00000000,0b00000000}, // space
	{0b00000000,0b00000000,0b01001111,0b00000000,0b00000000}, // !
	{0b00000000,0b00000111,0b00000000,0b00000111,0b00000000}, // "
	{0b00010100,0b01111111,0b00010100,0b01111111,0b00010100}, // #
	{0b00100100,0b00101010,0b01111111,0b00101010,0b00010010}, // $
	{0b00100011,0b00010011,0b00001000,0b01100100,0b01100010}, // %
	{0b00110110,0b01001001,0b01010101,0b00100010,0b01010000}, // &
	{0b00000000,0b00000101,0b00000011,0b00000000,0b00000000}, // '
	{0b00000000,0b00011100,0b00100010,0b01000001,0b00000000}, // (
	{0b00000000,0b01000001,0b00100010,0b00011100,0b00000000}, // )
	{0b00010100,0b00001000,0b00111110,0b00001000,0b00010100}, // *
	{0b00001000,0b00001000,0b00111110,0b00001000,0b00001000}, // +
	{0b00000000,0b01010000,0b00110000,0b00000000,0b00000000}, // ,
	{0b00001000,0b00001000,0b00001000,0b00001000,0b00001000}, // -
	{0b00000000,0b01100000,0b01100000,0b00000000,0b00000000}, // .
	{0b00100000,0b00010000,0b00001000,0b00000100,0b00000010}, // /
	{0b00111110,0b01010001,0b01001001,0b01000101,0b00111110}, // 0
	{0b00000000,0b01000010,0b01111111,0b01000000,0b00000000}, // 1
	{0b01000010,0b01100001,0b01010001,0b01001001,0b01000110}, // 2
	{0b00100001,0b01000001,0b01000101,0b01001011,0b00110001}, // 3
	{0b00011000,0b00010100,0b00010010,0b01111111,0b00010000}, // 4
	{0b00100111,0b01000101,0b01000101,0b01000101,0b00111001}, // 5
	{0b00111100,0b01001010,0b01001001,0b01001001,0b00110000}, // 6
	{0b00000011,0b01110001,0b00001001,0b00000101,0b00000011}, // 7
	{0b00110110,0b01001001,0b01001001,0b01001001,0b00110110}, // 8
	{0b00000110,0b01001001,0b01001001,0b00101001,0b00011110}, // 9
	{0b00000000,0b01101100,0b01101100,0b00000000,0b00000000}, // :
	{0b00000000,0b01010110,0b00110110,0b00000000,0b00000000}, // ;
	{0b00001000,0b00010100,0b00100010,0b01000001,0b00000000}, // <
	{0b00010100,0b00010100,0b00010100,0b00010100,0b00010100}, // =
	{0b00000000,0b01000001,0b00100010,0b00010100,0b00001000}, // >
	{0b00000010,0b00000001,0b01010001,0b00001001,0b00000110}, // ?
	{0b00110010,0b01001001,0b01111001,0b01000001,0b00111110}, // @
	{0b01111110,0b00010001,0b00010001,0b00010001,0b01111110}, // A
	{0b01111111,0b01001001,0b01001001,0b01001001,0b00111110}, // B
	{0b00111110,0b01000001,0b01000001,0b01000001,0b00100010}, // C
	{0b01111111,0b01000001,0b01000001,0b01000001,0b00111110}, // D
	{0b01111111,0b01001001,0b01001001,0b01001001,0b01001001}, // E
	{0b01111111,0b00001001,0b00001001,0b00001001,0b00000001}, // F
	{0b00111110,0b01000001,0b01001001,0b01001001,0b00111010}, // G
	{0b01111111,0b00001000,0b00001000,0b00001000,0b01111111}, // H
	{0b01000001,0b01000001,0b01111111,0b01000001,0b01000001}, // I
	{0b00110000,0b01000001,0b01000001,0b00111111,0b00000001}, // J
	{0b01111111,0b00001000,0b00010100,0b00100010,0b01000001}, // K
	{0b01111111,0b01000000,0b01000000,0b01000000,0b01000000}, // L
	{0b01111111,0b00000010,0b00001100,0b00000010,0b01111111}, // M
	{0b01111111,0b00000100,0b00001000,0b00010000,0b01111111}, // N
	{0b00111110,0b01000001,0b01000001,0b01000001,0b00111110}, // O
	{0b01111111,0b00001001,0b00001001,0b00001001,0b00000110}, // P
	{0b00111110,0b01000001,0b01010001,0b00100001,0b01011110}, // Q
	{0b01111111,0b00001001,0b00001001,0b00011001,0b01100110}, // R
	{0b01000110,0b01001001,0b01001001,0b01001001,0b00110001}, // S
	{0b00000001,0b00000001,0b01111111,0b00000001,0b00000001}, // T
	{0b00111111,0b01000000,0b01000000,0b01000000,0b00111111}, // U
	{0b00001111,0b00110000,0b01000000,0b00110000,0b00001111}, // V
	{0b00111111,0b01000000,0b00111000,0b01000000,0b00111111}, // W
	{0b01100011,0b00010100,0b00001000,0b00010100,0b01100011}, // X
	{0b00000011,0b00000100,0b01111000,0b00000100,0b00000011}, // Y
	{0b01100001,0b01010001,0b01001001,0b01000101,0b01000011}, // Z
	{0b01111111,0b01000001,0b01000001,0b00000000,0b00000000}, // [
	{0b00000010,0b00000100,0b00001000,0b00010000,0b00100000}, // '\'
	{0b00000000,0b00000000,0b01000001,0b01000001,0b01111111}, // ]
	{0b00000100,0b00000010,0b00000001,0b00000010,0b00000100}, // ^
	{0b01000000,0b01000000,0b01000000,0b01000000,0b01000000}, // _
	{0b00000000,0b00000001,0b00000010,0b00000100,0b00000000}, // `
	{0b00100000,0b01010100,0b01010100,0b01010100,0b01111000}, // a
	{0b01111111,0b01001000,0b01000100,0b01000100,0b00111000}, // 0b
	{0b00111000,0b01000100,0b01000100,0b01000100,0b00100000}, // c
	{0b00111000,0b01000100,0b01000100,0b01001000,0b01111111}, // d
	{0b00111000,0b01010100,0b01010100,0b01010100,0b00011000}, // e
	{0b00001000,0b01111110,0b00001001,0b00000001,0b00000010}, // f
	{0b00001100,0b01010010,0b01010010,0b01010010,0b00111110}, // g
	{0b01111111,0b00001000,0b00000100,0b00000100,0b01111000}, // h
	{0b00000000,0b01000100,0b01111101,0b01000000,0b00000000}, // i
	{0b00100000,0b01000000,0b01000100,0b00111101,0b00000000}, // j
	{0b01111111,0b00010000,0b00101000,0b01000100,0b00000000}, // k
	{0b00000000,0b01000001,0b01111111,0b01000000,0b00000000}, // l
	{0b01111000,0b00000100,0b00001000,0b00000100,0b01111000}, // m
	{0b01111100,0b00001000,0b00000100,0b00000100,0b01111000}, // n
	{0b00111000,0b01000100,0b01000100,0b01000100,0b00111000}, // o
	{0b01111100,0b00010100,0b00010100,0b00010100,0b00001000}, // p
	{0b00001000,0b00010100,0b00010100,0b01111100,0b00000000}, // q
	{0b01111100,0b00001000,0b00000100,0b00000100,0b00001000}, // r
	{0b01001000,0b01010100,0b01010100,0b01010100,0b00100000}, // s
	{0b00000100,0b00111111,0b01000100,0b01000000,0b00100000}, // t
	{0b00111100,0b01000000,0b01000000,0b00100000,0b01111100}, // u
	{0b00011100,0b00100000,0b01000000,0b00100000,0b00011100}, // v
	{0b00111100,0b01000000,0b00110000,0b01000000,0b00111100}, // w
	{0b01000100,0b00101000,0b00010000,0b00101000,0b01000100}, // x
	{0b00001100,0b01010000,0b01010000,0b01010000,0b00111100}, // y
	{0b01000100,0b01100100,0b01010100,0b01001100,0b01000100}, // z
	{0b00000000,0b00001000,0b00110110,0b01000001,0b00000000}, // {
	{0b00000000,0b00000000,0b01111111,0b00000000,0b00000000}, // |
	{0b00000000,0b01000001,0b00110110,0b00001000,0b00000000}, // }
	{0b00001000,0b00000100,0b00000100,0b00001000,0b00000100} // ~
}; // characters[95]

// Message to be displayed, stored in flash
const char message[] PROGMEM = "This is the message we want to scroll by.";

// Function Prototypes

void initSPI(void);

void writeByte(uint8_t byte);

void writeWord(uint8_t address, uint8_t data);

void initMatrix(void);

void clearMatrix(void);

void initBuffer(void);

void pushBuffer(uint8_t x);

void pushCharacter(uint8_t c);

void displayMessage(const char *arrayPointer, uint16_t arraySize);

void displayBuffer(void);

 

Last Edited: Sat. Jan 11, 2020 - 09:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you didn't write the code, where did it come from? 

 

This looks like homework - what have you done to solve the problem?

Last Edited: Sat. Jan 11, 2020 - 09:47 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's my laboratory for University. It's is one of the tasks that i cannot solve

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Where did the hardware design and code come from? This is a hint in itself - the answer might lead to the answer.

At university, you’re not majoring in a degree of CBF are you? Some schools have a double degree in NFI and CBF.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Then you really need to go to your Tutor / Supervisor / Lecturer for support !

 

 i cannot solve

So what have you tried to far ?

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1


Just a hint: you can use the "bus" button to bundle all those wires together.

 

 

See this tutorial, for example:

http://8051programming.blogspot....

 

Yeah, I know this doesn't solve your problem, but will reduce the mess.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You either have an alignment problem with the connection between the MAX72 and the 8x8 LED modules, or the alignment of the font table is 90 degrees off the font alignment of the 8x8 LED module.

 

The font table that you posted is derived from a Nokia 5110 graphics LED controller, which has vertical alignment of the char pixels.  Each character is 7 (vertical COLUMNs ) by 5 (horizontal  ROWs) pixels.  Counterintutively, each of the five bytes that define each of the 96 characters is a COLUMN.  Each byte has 7 pixels (0 =OFF, 1=ON) and one bit (bit 7 ) is always 0, which acts as a vertical spacer.

 

The columns start on the left side of the char, and the least significant bit of each byte is on the TOP of the character.  Look at the exclamation point char: the second one on the table.  The side columns are zeros and the middle column (byte 3 of 5) has a string of ON pixels in the lower bits (bits 4-0) while there is a single bit ON (logic 1) in the most-sigificant bits (0-2).  The string of five logic-1 pixels is the shaft of the exclamation char and the one logic-1 pixel in bit1 is the dot point underneath the shaft.

 

The MAX7217 is most-likely expecting the data to be in horizontal alignment.  This type of 7x5 font table will have 7 bytes per char and three bits in each byte will be spacers.  You need a routine that tilts each character 90 degrees when each char is being displayed.   Then this routine has to be added to the text scrolling routine.

 

Tell us more about how the chars are currently scrolling:

Last Edited: Sat. Jan 11, 2020 - 11:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The MAX7219 knows nothing about characters, matrices, rows, columns, etc. It's easiest to conceptualise it as controlling up to eight 7-seg+DP LED displays. It does this by having eight segment outputs and eight common cathode outputs. Depending on how the 8x8 LED matrices are wired up, you may be addressing rows or columns, i.e. is it eight columns of eight LEDs, or eight rows or eight LEDs ? This will determine how your char table should be structured.

 

It may be instructive to take a look at the source for the LedControl Arduino library for this IC: http://wayoda.github.io/LedControl/