Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Interfacing MAX7219 to PIC 16F877

Status
Not open for further replies.

mdf

New Member
Hello There,

I have been trying to interface MAX7219 to PIC 16F877 using the code below. It doesn't work. Please help to identify the issues and correct it.
C:
// CONFIG
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config CP = OFF         // FLASH Program Memory Code Protection bits (Code protection off)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low Voltage In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection (Code Protection off)
#pragma config WRT = ON         // FLASH Program Memory Write Enable (Unprotected program memory may be written to by EECON control)

#define _XTAL_FREQ 4000000


#define SPI_CS PORTBbits.RB1

unsigned char i;

void spi_setup(void)
{
    TRISC=0b00010000 ; // PORTC ping direction
    TRISB=0b00000000 ; // PORTB ping direction
 
    PIR1bits.SSPIF = 0; // Clear interrupt flag
    PIE1bits.SSPIE = 0; // Disable MSSP interrupt
    //INTCONbits.PEIE = 0; // Disable perriferal interrupts
 
    INTCON = 0x0;
 
    SSPSTATbits.SMP = 0; //input samled at middle of interval
    SSPSTATbits.CKE = 0; //Data transmitted from low to high clock
 
     
    SSPCON = 0b00000000;  // Enable SSP, Master mode, clock Fosc/4
    SSPCONbits.CKP = 0;
    SSPCONbits.SSPEN = 1; // Enable
    SSPCONbits.SSPOV = 0; // Overflow disable
       
 
}

unsigned char spi_transfer(unsigned char data)
{
 
    SSPBUF = data;
    while( !SSPSTATbits.BF );
    SSPSTATbits.BF = 0;
    return SSPBUF;
}


void max7219_init()
{

  SPI_CS = 0;                         //ON MAX
  spi_transfer(0x09);              //BCD mode
  spi_transfer(0xFF);      
  SPI_CS = 1;                         //OFF MAX

  SPI_CS = 0;                        //ON MAX
  spi_transfer(0x0A);            //Intensity
  spi_transfer(0x0F);
  SPI_CS = 1;                        //OFF MAX

  SPI_CS = 0;                       //ON MAX
  spi_transfer(0x0B);           //Display refresh
  spi_transfer(0x07);
  SPI_CS = 1;                       //OFF MAX

  SPI_CS = 0;                       //ON MAX
  spi_transfer(0x0C);           //Turn on the display
  spi_transfer(0x01);
  PORTBbits.RB1 = 1;          // OFF MAX

  SPI_CS = 0;                       //ON MAX
  spi_transfer(0x00);            //NO Test
  spi_transfer(0xFF);
  SPI_CS = 1;                        //OFF MAX

}




void main(void) {
 
  __delay_ms(100);
  spi_setup();          
  __delay_ms(100);
                     
  SPI_CS = 1;
  __delay_ms(100);
  max7219_init();      

  for (i = 1; i<=8; i++)
   {
       SPI_CS = 0;      
       spi_transfer(i);
       spi_transfer(8-i);      
       SPI_CS = 1;
     
      __delay_ms(500);

    } //  <------ MISSING!!!
    return;
}
 
Last edited by a moderator:
Hi, Thanks for the reply. It seems there was a copy paste error. Even after adding while (1) {} to stop resetting the program. It still doesn't work. Help!
 
Hi,

I changed the initialization code as below. Bet still no luck.

void max7219_init()
{
SPI_CS = 1;
__delay_ms(100);
SPI_CS = 0; //ON MAX
spi_transfer(0x09); //BCD mode
spi_transfer(0xFF);
SPI_CS = 1; //OFF MAX

SPI_CS = 0; //ON MAX
spi_transfer(0x0A); //Intensity
spi_transfer(0x0F);
SPI_CS = 1; //OFF MAX

SPI_CS = 0; //ON MAX
spi_transfer(0x0B); //Display refresh
spi_transfer(0x07);
SPI_CS = 1; //OFF MAX

SPI_CS = 0; //ON MAX
spi_transfer(0x0C); //Turn on the display
spi_transfer(0x01);
PORTBbits.RB1 = 1; // OFF MAX

SPI_CS = 0; //ON MAX
spi_transfer(0x0F); //NO Test
spi_transfer(0x00);
SPI_CS = 1; //OFF MAX

}
 
Does for me..... I simulated it in ISIS... Turn you scan rate down to 3 and!!!

Change your code to this..
C:
  while(1)
   {   
       for (i = 1; i<=8; i++)
       {
       SPI_CS = 0;   
       spi_transfer(i);
       spi_transfer(8-i);   
       SPI_CS = 1;
     }   
     __delay_ms(500);
     
   }
Or you won't see your numbers....
 
Hi Ian, Could you please share your Proteous project file and the complete code. Appreciate your help. Cheers!
 
Same as yours...

If you are using Proteus, then you will experience HUGE flicker.. This is due the the simulation being extremely slow... It runs about 10 time slower than real time

C:
#include<xc.h>

#pragma config FOSC = XT  // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF  // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF  // Power-up Timer Enable bit (PWRT disabled)
#pragma config CP = OFF  // FLASH Program Memory Code Protection bits (Code protection off)
#pragma config BOREN = ON  // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF  // Low Voltage In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF  // Data EE Memory Code Protection (Code Protection off)
#pragma config WRT = ON  // FLASH Program Memory Write Enable (Unprotected program memory may be written to by EECON control)

#define _XTAL_FREQ 4000000


#define SPI_CS PORTBbits.RB1

unsigned char i;

void spi_setup(void)
{
  TRISC=0b00010000 ; // PORTC ping direction
  TRISB=0b00000000 ; // PORTB ping direction
  PIR1bits.SSPIF = 0; // Clear interrupt flag
  PIE1bits.SSPIE = 0; // Disable MSSP interrupt
  //INTCONbits.PEIE = 0; // Disable perriferal interrupts
  INTCON = 0x0;
  SSPSTATbits.SMP = 0; //input samled at middle of interval
  SSPSTATbits.CKE = 0; //Data transmitted from low to high clock
   
  SSPCON = 0b00000000;  // Enable SSP, Master mode, clock Fosc/4
  SSPCONbits.CKP = 0;
  SSPCONbits.SSPEN = 1; // Enable
  SSPCONbits.SSPOV = 0; // Overflow disable
   
}

unsigned char spi_transfer(unsigned char data)
{
  SSPBUF = data;
  while( !SSPSTATbits.BF );
  SSPSTATbits.BF = 0;
  return SSPBUF;
}


void max7219_init()
{

  SPI_CS = 0;  //ON MAX
  spi_transfer(0x09);  //BCD mode
  spi_transfer(0xFF);   
  SPI_CS = 1;  //OFF MAX

  SPI_CS = 0;  //ON MAX
  spi_transfer(0x0A);  //Intensity
  spi_transfer(0x0F);
  SPI_CS = 1;  //OFF MAX

  SPI_CS = 0;  //ON MAX
  spi_transfer(0x0B);  //Display refresh
  spi_transfer(0x03);
  SPI_CS = 1;  //OFF MAX

  SPI_CS = 0;  //ON MAX
  spi_transfer(0x0C);  //Turn on the display
  spi_transfer(0x01);
  PORTBbits.RB1 = 1;  // OFF MAX

  SPI_CS = 0;  //ON MAX
  spi_transfer(0xF);  //NO Test
  spi_transfer(0x0);
  SPI_CS = 1;  //OFF MAX

}

void main(void) {
  __delay_ms(100);
  spi_setup();   
  __delay_ms(100);
   
  SPI_CS = 1;
  __delay_ms(100);
  max7219_init();   
   while(1)
   {   
       for (i = 1; i<=8; i++)
       {
       SPI_CS = 0;   
       spi_transfer(i);
       spi_transfer(8-i);   
       SPI_CS = 1;
     }   
     __delay_ms(500);
     
   }
   
}
 
#pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config CP = OFF // FLASH Program Memory Code Protection bits (Code protection off)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low Voltage In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EE Memory Code Protection (Code Protection off)
#pragma config WRT = ON // FLASH Program Memory Write Enable (Unprotected program memory may be written

Hi,
many of bis setting are off??
 
Guys,

I am using 4MHz Chrystal oscillator. I tested a simple code to to bilk a LED using the same hardware and settings. It worked. Do you still think it is an oscillator settings problem?

Do I need to connect any pull-up or down resistors to SDI, SDO, Clock and chip select pins?
 
Have you a logic analyser?? Or at least a storage scope to see if the max is getting the right signalling??

I don't have the max7219 I only have a couple of the old ICM7218's But the interface is entirely different!!
 
Ian > I don't have logic analyse. Let me try to find a way to verify proper single reception at MAX7219. Anyway thanks a lot for your support.
koolguy > This is the current limiter resistor
grandad > What is the meaning of "bit bang MAX7219"
 
mdf bit-bang ...Not a phrase i like really, it usually refers to simulation of a serial interface , where by the signals are controlled by a routine, rather than a peripheral, this is my PIC24FV16KM202 to MAX7219 , needs work to define the pins, ( I usually do this after a good testing ) example LATBbits14 could be defined MAXload , the last Nop() probably not needed , was there for a 140Mhz pic24 .
Code:
void setMAX()
{
                          // DECODE-INTEN- SCAN - SUTD- TEST
    unsigned int MAX_init[] = {0x09FF,0xA02,0x0B05,0x0C01,0x0F00} ;
     int x;
   for ( x = 0; x < 5 ; x++)
   {
   MAX_ss_bb( MAX_init[x] );
   }
}


void MAX_ss_bb(unsigned int test)  //  MAX seven Segment bit bang
{
  unsigned int x ;
  LATBbits.LATB14 = 0;       // Load MAX7219 = low
  for ( x = 0; x < 16 ; x++)      // 16 bits to send
  {
  if (test & 0x8000) {      // set/clear data pin
    LATBbits.LATB15 = 1;    // Data = 1
  }else{
    LATBbits.LATB15 = 0;    // Data = 0
  }
  LATBbits.LATB13 = 1;       // Clock high
  LATBbits.LATB13 = 0;       // Clock low
  test = test << 1;
  }
LATBbits.LATB14 = 1;  // Load pin  High
Nop();
LATBbits.LATB15 = 0;  // drop Data line

}
note... make Load pin High in IO setup
With apology to any real programmers ... I was just a service engineer in the 1970's :)
 
Last edited:
Status
Not open for further replies.

Latest threads

Back
Top