CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Max7221 and dot matrix displays
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
The Puma



Joined: 23 Apr 2004
Posts: 227
Location: The Netherlands

View user's profile Send private message

Max7221 and dot matrix displays
PostPosted: Mon May 28, 2007 7:55 am     Reply with quote

Hallo,

I have post already several times about this problem
Have 10 5x7 dotmatrix displays connected to ten cascaded MAX7221's

This is my code so far
It displays "TEST" on the rightmost matrix displays

Code:

#include <18F4620.h>
#include <stdlib.h>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOBROWNOUT,NOPUT,NOLVP,DEBUG,NOSTVREN,NOPROTECT

#include <max7221_5x7_dot_matrix.h>

void main() {
   char input_buffer[11];
   
   max7221_init();
   max7221_blank_dot_matrix();
   
   while(TRUE) {
      strcpy(input_buffer,"TEXT 1");
      max7221_fill_buffer(input_buffer);
      max7221_display_message();
      delay_ms(1000);
      strcpy(input_buffer,"TEXT 2");
      max7221_fill_buffer(input_buffer);
      max7221_display_message();
      delay_ms(1000);
   }
}

Code:

#ifndef MAX7221_CS

#define MAX7221_CS    PIN_C0
#define MAX7221_CLK   PIN_C3
#define MAX7221_DOUT  PIN_C4
#define MAX7221_DIN   PIN_C5

#endif

// Register address map
#define NO_OP                       0x00  // Used when cascading max7221s
#define DIGIT_0                     0x01  // Digit 0 register
#define DIGIT_1                     0x02  // Digit 1 register
#define DIGIT_2                     0x03  // Digit 2 register
#define DIGIT_3                     0x04  // Digit 3 register
#define DIGIT_4                     0x05  // Digit 4 register
#define DIGIT_5                     0x06  // Digit 5 register
#define DIGIT_6                     0x07  // Digit 6 register
#define DIGIT_7                     0x08  // Digit 7 register
#define DECODE_MODE                 0x09  // Decode mode register
#define INTENSITY                   0x0A  // Intensity register
#define SCAN_LIMIT                  0x0B  // Scan-limit register
#define SHUT_DOWN                   0x0C  // Shutdown register
#define DISPLAY_TEST                0x0F  // Display-test register

// Shutdown register
#define SHUTDOWN_MODE               0x00  // Shutdown mode
#define NORMAL_MODE                 0x01  // Normal mode

// Decode-mode register
#define NO_DECODE_DIGITS_7_0        0x00  // No decode for digits 7-0
#define CODE_B_DECODE_DIGIT_0       0x01  // Code B decode for digit 0
#define CODE_B_DECODE_DIGITS_3_0    0x0F  // Code B decode for digits 3-0
#define CODE_B_DECODE_DIGITS_7_0    0xFF  // Code B decode for digits 7-0

// Intensity register
#define DUTY_CYCLE_1                0x00  // Intensity min
#define DUTY_CYCLE_2                0x01
#define DUTY_CYCLE_3                0x02
#define DUTY_CYCLE_4                0x03
#define DUTY_CYCLE_5                0x04
#define DUTY_CYCLE_6                0x05
#define DUTY_CYCLE_7                0x06
#define DUTY_CYCLE_8                0x07
#define DUTY_CYCLE_9                0x08
#define DUTY_CYCLE_10               0x09
#define DUTY_CYCLE_11               0x0A
#define DUTY_CYCLE_12               0x0B
#define DUTY_CYCLE_13               0x0C
#define DUTY_CYCLE_14               0x0D
#define DUTY_CYCLE_15               0x0E
#define DUTY_CYCLE_16               0x0F  // Intensity full

// Scan-limit register
#define DISPLAY_DIGIT_0             0x00  // Display digit 0
#define DISPLAY_DIGITS_01           0x01  // Display digits 0 & 1
#define DISPLAY_DIGITS_012          0x02  // Display digits 0 1 2
#define DISPLAY_DIGITS_0123         0x03  // Display digits 0 1 2 3
#define DISPLAY_DIGITS_01234        0x04  // Display digits 0 1 2 3 4
#define DISPLAY_DIGITS_012345       0x05  // Display digits 0 1 2 3 4 5
#define DISPLAY_DIGITS_0123456      0x06  // Display digits 0 1 2 3 4 5 6
#define DISPLAY_DIGITS_01234567     0x07  // Display digits 0 1 2 3 4 5 6 7

// Display-test register
#define NORMAL_OPERATION            0x00  // Normal operation
#define DISPLAY_TEST_MODE           0x01  // Display-test mode, all leds on

// Number max. dot-matrix displays
#define MAX_DOT_MATRIX_USED         0x0A  // Max. dot matrix displays used

// Declare and Init the font array data
char const font5x7[96][5] = {
   0x00, 0x00, 0x00, 0x00, 0x00  // 0x20, Space
   0x00, 0x00, 0x5F, 0x00, 0x00  // 0x21, !
   0x00, 0x07, 0x00, 0x07, 0x00  // 0x22, "
   0x14, 0x7F, 0x14, 0x7F, 0x14  // 0x23, #
   0x12, 0x2A, 0x7F, 0x2A, 0x24  // 0x24, $
   0x62, 0x64, 0x08, 0x13, 0x23  // 0x25, %
   0x50, 0x22, 0x55, 0x49, 0x36  // 0x26, &
   0x00, 0x00, 0x03, 0x05, 0x00  // 0x27, '
   0x00, 0x41, 0x22, 0x1C, 0x00  // 0x28, (
   0x00, 0x1C, 0x22, 0x41, 0x00  // 0x29, )
   0x08, 0x2A, 0x1C, 0x2A, 0x08  // 0x2A, *
   0x08, 0x08, 0x3E, 0x08, 0x08  // 0x2B, +
   0x00, 0x00, 0x30, 0x50, 0x00  // 0x2C, ,
   0x08, 0x08, 0x08, 0x08, 0x08  // 0x2D, -
   0x00, 0x00, 0x60, 0x60, 0x00  // 0x2E, .
   0x02, 0x04, 0x08, 0x10, 0x20  // 0x2F, /
   0x3E, 0x45, 0x49, 0x51, 0x3E  // 0x30, 0
   0x00, 0x40, 0x7F, 0x42, 0x00  // 0x31, 1
   0x46, 0x49, 0x51, 0x61, 0x42  // 0x32, 2
   0x31, 0x4B, 0x45, 0x41, 0x21  // 0x33, 3
   0x10, 0x7F, 0x12, 0x14, 0x18  // 0x34, 4
   0x39, 0x45, 0x45, 0x45, 0x27  // 0x35, 5
   0x30, 0x49, 0x49, 0x4A, 0x3C  // 0x36, 6
   0x03, 0x05, 0x09, 0x71, 0x01  // 0x37, 7
   0x36, 0x49, 0x49, 0x49, 0x36  // 0x38, 8
   0x1E, 0x29, 0x49, 0x49, 0x06  // 0x39, 9
   0x00, 0x00, 0x36, 0x36, 0x00  // 0x3A, :
   0x00, 0x00, 0x36, 0x56, 0x00  // 0x3B, ;
   0x41, 0x22, 0x14, 0x08, 0x00  // 0x3C, <0x14>
   0x06, 0x09, 0x51, 0x01, 0x02  // 0x3F, ?
   0x3E, 0x41, 0x79, 0x49, 0x32  // 0x40, @
   0x7E, 0x11, 0x11, 0x11, 0x7E  // 0x41, A
   0x36, 0x49, 0x49, 0x49, 0x7F  // 0x42, B
   0x22, 0x41, 0x41, 0x41, 0x3E  // 0x43, C
   0x1C, 0x22, 0x41, 0x41, 0x7F  // 0x44, D
   0x41, 0x49, 0x49, 0x49, 0x7F  // 0x45, E
   0x01, 0x01, 0x09, 0x09, 0x7F  // 0x46, F
   0x32, 0x51, 0x41, 0x41, 0x3E  // 0x37, G
   0x7F, 0x08, 0x08, 0x08, 0x7F  // 0x48, H
   0x00, 0x41, 0x7F, 0x41, 0x00  // 0x49, I
   0x01, 0x3F, 0x41, 0x40, 0x20  // 0x4A, J
   0x41, 0x22, 0x14, 0x08, 0x7F  // 0x4B, K
   0x40, 0x40, 0x40, 0x40, 0x7F  // 0x4C, L
   0x7F, 0x02, 0x04, 0x02, 0x7F  // 0x4D, M
   0x7F, 0x10, 0x08, 0x04, 0x7F  // 0x4E, N
   0x3E, 0x41, 0x41, 0x41, 0x3E  // 0x4F, O
   0x06, 0x09, 0x09, 0x09, 0x7F  // 0x50, P
   0x5E, 0x21, 0x51, 0x41, 0x3E  // 0x51, Q
   0x46, 0x29, 0x19, 0x09, 0x7F  // 0x52, R
   0x31, 0x49, 0x49, 0x49, 0x46  // 0x53, S
   0x01, 0x01, 0x7F, 0x01, 0x01  // 0x54, T
   0x3F, 0x40, 0x40, 0x40, 0x3F  // 0x55, U
   0x1F, 0x20, 0x40, 0x20, 0x1F  // 0x56, V
   0x7F, 0x20, 0x18, 0x20, 0x7F  // 0x57, W
   0x63, 0x14, 0x08, 0x14, 0x63  // 0x58, X
   0x03, 0x04, 0x78, 0x04, 0x03  // 0x59, Y
   0x43, 0x45, 0x49, 0x51, 0x61  // 0x5A, Z
   0x41, 0x41, 0x7F, 0x00, 0x00  // 0x5B, [
   0x20, 0x10, 0x08, 0x04, 0x02  // 0x5C, \
   0x00, 0x00, 0x7F, 0x41, 0x41  // 0x5D, ]
   0x04, 0x02, 0x01, 0x02, 0x04  // 0x5E, ^
   0x40, 0x40, 0x40, 0x40, 0x40  // 0x5F, _
   0x00, 0x04, 0x02, 0x01, 0x00  // 0x60, `
   0x78, 0x54, 0x54, 0x54, 0x20  // 0x61, a
   0x38, 0x44, 0x44, 0x48, 0x7F  // 0x62, b
   0x20, 0x44, 0x44, 0x44, 0x38  // 0x63, c
   0x7F, 0x48, 0x44, 0x44, 0x38  // 0x64, d
   0x18, 0x54, 0x54, 0x54, 0x38  // 0x65, e
   0x02, 0x01, 0x09, 0x7E, 0x08  // 0x66, f
   0x3C, 0x54, 0x54, 0x14, 0x08  // 0x67, g
   0x78, 0x04, 0x04, 0x08, 0x7F  // 0x68, h
   0x00, 0x40, 0x7D, 0x44, 0x00  // 0x69, i
   0x00, 0x3D, 0x44, 0x40, 0x20  // 0x6A, j
   0x44, 0x28, 0x10, 0x7F, 0x00  // 0x6B, k
   0x00, 0x40, 0x7F, 0x41, 0x00  // 0x6C, l
   0x78, 0x04, 0x18, 0x04, 0x7C  // 0x6D, m
   0x78, 0x04, 0x04, 0x08, 0x7C  // 0x6E, n
   0x38, 0x44, 0x44, 0x44, 0x38  // 0x6F, o
   0x08, 0x14, 0x14, 0x14, 0x7C  // 0x70, p
   0x7C, 0x18, 0x14, 0x14, 0x08  // 0x71, q
   0x08, 0x04, 0x04, 0x08, 0x7C  // 0x72, r
   0x20, 0x54, 0x54, 0x54, 0x48  // 0x73, s
   0x20, 0x40, 0x44, 0x3F, 0x04  // 0x74, t
   0x7C, 0x20, 0x40, 0x40, 0x3C  // 0x75, u
   0x1C, 0x20, 0x40, 0x20, 0x1C  // 0x76, v
   0x3C, 0x40, 0x30, 0x40, 0x3C  // 0x77, w
   0x44, 0x28, 0x10, 0x28, 0x44  // 0x78, x
   0x3C, 0x50, 0x50, 0x50, 0x0C  // 0x79, y
   0x44, 0x4C, 0x54, 0x64, 0x44  // 0x7A, z
   0x00, 0x41, 0x36, 0x08, 0x00  // 0x7B, {
   0x00, 0x00, 0x7F, 0x00, 0x00  // 0x7C, |
   0x00, 0x08, 0x36, 0x41, 0x00  // 0x7D, }
   0x08, 0x1C, 0x2A, 0x08, 0x08  // 0x7E, ~
   0x08, 0x08, 0x2A, 0x1C, 0x08  // 0x7F, DEL
};

char led_buffer[50];

void max7221_fill_buffer(char *buffer) {
   int i,j;
   char *reverse_buffer,*led_buffer_ptr,currentchar;
   
   j=strlen(buffer);
   reverse_buffer[j--]=0;
   for(i=0;i<strlen(buffer);i++,j--)
      reverse_buffer[j]=buffer[i];
      
   memset(led_buffer,0x00,50);
   led_buffer_ptr=&led_buffer[0];
   currentchar=*reverse_buffer;
   while(currentchar) {
      memcpy(led_buffer_ptr,font5x7[currentchar-0x20],5);
      led_buffer_ptr+=5;
      currentchar=*(++reverse_buffer);
   }
}

void max7221_display_message() {
   int column,index,dot_matrix;
   
   for(column=DIGIT_0;column<=DIGIT_4;column++) {
      index=5-column;
      output_low(MAX7221_CS);
      for(dot_matrix=1;dot_matrix<=MAX_DOT_MATRIX_USED;dot_matrix++) {
         spi_write(column);
         spi_write(led_buffer[index]);
         index+=5;
      }
      output_high(MAX7221_CS);
   }
}

void max7221_put(int addr,data) {
   output_low(MAX7221_CS);
   spi_write(addr);
   spi_write(data);
   output_high(MAX7221_CS);
}

void max7221_put_all(int addr,data) {
   int dot_matrix;
   
   output_low(MAX7221_CS);
   for(dot_matrix=1;dot_matrix<=MAX_DOT_MATRIX_USED;dot_matrix++) {
      spi_write(addr);
      spi_write(data);
   }
   output_high(MAX7221_CS);
}

void max7221_blank_dot_matrix() {
   int column;
   
   for(column=DIGIT_0;column<=DIGIT_4;column++)
      max7221_put_all(column,0x00);
}

void max7221_init() {
   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_16);
   max7221_put_all(DECODE_MODE,NO_DECODE_DIGITS_7_0);
   max7221_put_all(SCAN_LIMIT,DISPLAY_DIGITS_01234);
   max7221_put_all(SHUT_DOWN,NORMAL_MODE);
   max7221_put_all(DISPLAY_TEST,NORMAL_OPERATION);
   max7221_put_all(INTENSITY,DUTY_CYCLE_1);
}


Last edited by The Puma on Thu Oct 11, 2007 11:44 am; edited 4 times in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon May 28, 2007 5:32 pm     Reply with quote

Quote:

This is my code so far.

void main() {
setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16);



Here are ckielstra's SPI mode definitions:
Code:

#define SPI_MODE_0_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_0_1  (SPI_L_TO_H)
#define SPI_MODE_1_0  (SPI_H_TO_L)
#define SPI_MODE_1_1  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

From his definitions, we can see that you are using SPI mode 2.
("1_0" in binary is "2" in decimal).

Download the MAX7221 data sheet:
http://datasheets.maxim-ic.com/en/ds/MAX7219-MAX7221.pdf
In Figure 1 (on page 6), there is a timing diagram that shows the
relationship of CLK to DIN. It shows that the rising edge of CLK
is used to sample the data. The timing diagram also shows that
the CLK signal idles in the low state when it's not active. Both of
these things are needed to determine the correct SPI mode.

Now look at this diagram on the TotalPhase website.
http://www.totalphase.com/support/articles/article03/#modes
It shows the edge of the clock and the idle state of the clock,
that are used in each of the four possible SPI modes.

So here is a question for you:
Based on the information I gave you above, which SPI mode should
you use to communicate between the PIC and the Max7221 ?

How would you re-write your setup_spi() statement to use the
correct SPI mode ?
The Puma



Joined: 23 Apr 2004
Posts: 227
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 4:32 am     Reply with quote

@PCM programmer

Which the setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16); the program works
with setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16) the output gives strange results.
Why??

I did't understand the above illustration you get.
Please can you give me the corrrect setup_spi command for the max7221
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 11:24 am     Reply with quote

Randomly trying different modes is not the way to solve the problem.

In the MAX7221 data sheet, they show the SPI timing in the diagram
with this title (on page 6):
Quote:
Figure 1. Timing Diagram

http://datasheets.maxim-ic.com/en/ds/MAX7219-MAX7221.pdf

It shows the idle state of CLK is a low level, and that the Din signal
is sampled on the rising edge of CLK. Look at the diagram on the
Total Phase website, and it shows the SPI mode is clearly Mode 0.
That means you use this constant in the setup_spi():
Code:
SPI_MODE_0_0 
The Puma



Joined: 23 Apr 2004
Posts: 227
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 11:38 am     Reply with quote

Strange if a use your setting than the display give strange output.
Why did it work any good with setup, and with the SPI_H_L it work good?
Can you explain this?


setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_16);
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 11:44 am     Reply with quote

What is the strange output ? Describe it.
The Puma



Joined: 23 Apr 2004
Posts: 227
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 11:48 am     Reply with quote

See updated code above

If give one good character and then strange chars

If i use this setup, all works
setup_spi(SPI_MASTER|SPI_H_TO_L|SPI_CLK_DIV_16);
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 12:08 pm     Reply with quote

Quote:
It gives one good character and then strange chars

This probably means that the data is being delayed too much as
you pass it to several different MAX7221 chips. It's being delayed
so much that you have to invert the clock to make it work.

I haven't studied how to connect the MAX7221 chips in cascade mode,
but I suspect that you are not doing it correctly.
The Puma



Joined: 23 Apr 2004
Posts: 227
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 12:14 pm     Reply with quote

Hardware:

The DOUT pin of the first chip is connected to the DIN pin ofr the second chip, and so on

All CLK and CS lines connected to all chips

Is the SPI_CLK_DIV_16 a good choice for this chip??
and must all chips get the initializing commands?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 12:18 pm     Reply with quote

It may be the CLK signal that's getting delayed too much. I'll have to
read the data sheet later. I don't have any more time right now.
The Puma



Joined: 23 Apr 2004
Posts: 227
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 2:05 pm     Reply with quote

I have a unit with one max7221 on it
The max7221 is connected to eight 7 seven displays

Then works the setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_16) without problems

Why is that possible?

Here is the code
Code:

#include <18F4620.h>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOBROWNOUT,NOPUT,NOLVP,DEBUG,NOSTVREN,NOPROTECT

#include <max7221_et_sdp8.h>

void main() {
   int32 j;
   
   max7221_init();
   max7221_blank_digits();
   
   for(j=0;j<10000000;j++) {
      max7221_write_num(j);
      delay_ms(20);
   }
}

Code:

#ifndef MAX7221_CS

#define MAX7221_CS    PIN_C0
#define MAX7221_CLK   PIN_C3
#define MAX7221_DOUT  PIN_C4
#define MAX7221_DIN   PIN_C5

#endif

// Register address map
#define NO_OP                     0x00  // Used when cascading max7221s
#define DIGIT_0                   0x01  // Digit 0 register
#define DIGIT_1                   0x02  // Digit 1 register
#define DIGIT_2                   0x03  // Digit 2 register
#define DIGIT_3                   0x04  // Digit 3 register
#define DIGIT_4                   0x05  // Digit 4 register
#define DIGIT_5                   0x06  // Digit 5 register
#define DIGIT_6                   0x07  // Digit 6 register
#define DIGIT_7                   0x08  // Digit 7 register
#define DECODE_MODE               0x09  // Decode mode register
#define INTENSITY                 0x0A  // Intensity register
#define SCAN_LIMIT                0x0B  // Scan-limit register
#define SHUT_DOWN                 0x0C  // Shutdown register
#define DISPLAY_TEST              0x0F  // Display-test register

// Shutdown register
#define SHUTDOWN_MODE             0x00  // Shutdown mode
#define NORMAL_MODE               0x01  // Normal mode

// Decode-mode register
#define NO_DECODE_DIGITS_7_0      0x00  // No decode for digits 7-0
#define CODE_B_DECODE_DIGIT_0     0x01  // Code B decode for digit 0
#define CODE_B_DECODE_DIGITS_3_0  0x0F  // Code B decode for digits 3-0
#define CODE_B_DECODE_DIGITS_7_0  0xFF  // Code B decode for digits 7-0

// Code B font
#define SEGMENT_CHAR_0            0x00  // 0
#define SEGMENT_CHAR_1            0x01  // 1
#define SEGMENT_CHAR_2            0x02  // 2
#define SEGMENT_CHAR_3            0x03  // 3
#define SEGMENT_CHAR_4            0x04  // 4
#define SEGMENT_CHAR_5            0x05  // 5
#define SEGMENT_CHAR_6            0x06  // 6
#define SEGMENT_CHAR_7            0x07  // 7
#define SEGMENT_CHAR_8            0x08  // 8
#define SEGMENT_CHAR_9            0x09  // 9
#define SEGMENT_CHAR_LINE         0x0A  // -
#define SEGMENT_CHAR_E            0x0B  // E
#define SEGMENT_CHAR_H            0x0C  // H
#define SEGMENT_CHAR_L            0x0D  // L
#define SEGMENT_CHAR_P            0x0E  // P
#define SEGMENT_CHAR_BLANK        0x0F  // BLANK
#define SEGMENT_CHAR_DP           0x80  // DP

// Intensity register
#define DUTY_CYCLE_1              0x00  // Intensity min
#define DUTY_CYCLE_2              0x01
#define DUTY_CYCLE_3              0x02
#define DUTY_CYCLE_4              0x03
#define DUTY_CYCLE_5              0x04
#define DUTY_CYCLE_6              0x05
#define DUTY_CYCLE_7              0x06
#define DUTY_CYCLE_8              0x07
#define DUTY_CYCLE_9              0x08
#define DUTY_CYCLE_10             0x09
#define DUTY_CYCLE_11             0x0A
#define DUTY_CYCLE_12             0x0B
#define DUTY_CYCLE_13             0x0C
#define DUTY_CYCLE_14             0x0D
#define DUTY_CYCLE_15             0x0E
#define DUTY_CYCLE_16             0x0F  // Intensity full

// Scan-limit register
#define DISPLAY_DIGIT_0           0x00  // Display digit 0
#define DISPLAY_DIGITS_01         0x01  // Display digits 0 & 1
#define DISPLAY_DIGITS_012        0x02  // Display digits 0 1 2
#define DISPLAY_DIGITS_0123       0x03  // Display digits 0 1 2 3
#define DISPLAY_DIGITS_01234      0x04  // Display digits 0 1 2 3 4
#define DISPLAY_DIGITS_012345     0x05  // Display digits 0 1 2 3 4 5
#define DISPLAY_DIGITS_0123456    0x06  // Display digits 0 1 2 3 4 5 6
#define DISPLAY_DIGITS_01234567   0x07  // Display digits 0 1 2 3 4 5 6 7

// Display-test register
#define NORMAL_OPERATION          0x00  // Normal operation
#define DISPLAY_TEST_MODE         0x01  // Display-test mode, all leds on

void max7221_put(int addr,data) {
   output_low(MAX7221_CS);
   spi_write(addr);
   spi_write(data);
   output_high(MAX7221_CS);
}

void max7221_write_num(int32 num) {
   int1 leading=true;
   int8 led_data[8];
   int8 j;
   int32 temp32;
   
   for(j=0;j<7;j++) {
      temp32=num/10;
      led_data[j]=num-(temp32*10);
      num=temp32;
   }
   led_data[7]=num;
   
   for(j=7;j>0;j--) {
      if(leading&&led_data[j]==0)
         led_data[j]=SEGMENT_CHAR_BLANK;
      else
         leading=false;
   }
   for(j=DIGIT_0;j<=DIGIT_7;j++)
      max7221_put(j,led_data[j-1]);
}

void max7221_blank_digits() {
   int j;
   
   for(j=DIGIT_0;j<=DIGIT_7;j++)
      max7221_put(j,SEGMENT_CHAR_BLANK);
}

void max7221_init() {
   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_16);
   max7221_put(DECODE_MODE,CODE_B_DECODE_DIGITS_7_0);
   max7221_put(SCAN_LIMIT,DISPLAY_DIGITS_01234567);
   max7221_put(SHUT_DOWN,NORMAL_MODE);
   max7221_put(INTENSITY,DUTY_CYCLE_4);
}
The Puma



Joined: 23 Apr 2004
Posts: 227
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Oct 11, 2007 3:44 pm     Reply with quote

I have tested futher and it is an no go with L_TO_H

This simple example lit on every column of the dot matrix from above to below an led

With H_TO_L it work OK, with L_TO_H it gives problems


Code:
void main() {
   int i,j;
   
   max7221_init();
   max7221_blank_dot_matrix();
   
   while(TRUE) {
      for(j=DiGIT_0;j<=DIGIT_4;j++) {
         
         output_low(MAX7221_CS);
         for(i=1;i<=10;i++) {
            spi_write(j);
            spi_write(1);
         }
         output_high(MAX7221_CS);
      
         delay_ms(100);
      
         output_low(MAX7221_CS);
         for(i=1;i<=10;i++) {
            spi_write(j);
            spi_write(2);
         }
         output_high(MAX7221_CS);
      
         delay_ms(100);
      
         output_low(MAX7221_CS);
         for(i=1;i<=10;i++) {
            spi_write(j);
            spi_write(4);
         }
         output_high(MAX7221_CS);
      
            delay_ms(100);
         
         output_low(MAX7221_CS);
         for(i=1;i<=10;i++) {
            spi_write(j);
            spi_write(8);
         }
         output_high(MAX7221_CS);
      
         delay_ms(100);
      
         output_low(MAX7221_CS);
         for(i=1;i<=10;i++) {
            spi_write(j);
            spi_write(16);
         }
         output_high(MAX7221_CS);
   
         delay_ms(100);
      
         output_low(MAX7221_CS);
         for(i=1;i<=10;i++) {
            spi_write(j);
            spi_write(32);
         }
         output_high(MAX7221_CS);
      
         delay_ms(100);
      
         output_low(MAX7221_CS);
      
         for(i=1;i<=10;i++) {
            spi_write(j);
            spi_write(64);
         }
         output_high(MAX7221_CS);
   
      delay_ms(100);
      
      max7221_blank_dot_matrix();
   
      }
   }
}
The Puma



Joined: 23 Apr 2004
Posts: 227
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Oct 14, 2007 4:51 pm     Reply with quote

I found this
http://www.maxim-ic.com/appnotes.cfm/an_pk/1879

And here is the spi mode
CPHA=1
CPOL=0

Then the spi_setup would be
Mode 1 0

Which is then the correct CCS-C setup???
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Oct 14, 2007 5:37 pm     Reply with quote

The MAX7221 data sheet shows that the SPI timing is setup for Mode 0,0.
The Puma



Joined: 23 Apr 2004
Posts: 227
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Oct 15, 2007 1:26 am     Reply with quote

strange, in the datasheet Using Maxim SPI-compatible Display Drivers with other SPI Peripherals shows that it must as follows
CPHA=1
CPOL=0

Please can you tell me what the Setup_Spi for that is?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group