I am attempting to drive a 4 digit, common cathode LED display with a MAX7219CNG display driver and a PIC16F690 MCU for SPI communication.
The LED display does not light up and appears to not be driven by the MAX7219.
I tested the LED display functionality by itself and it works and is in fact common cathode.
The PIC16F690 SPI pins CLK, SDO, and CS appear to be working properly as the signals are correct on the oscilloscope and on the correct pins.
When powered, pin voltages on the MAX7219 are: all digits high at 5V, all segments low at 0V, Dout (pin24) does mirror the Din (pin1) data. With all digits pins high and all segment pins low, this is very similar to the shutdown mode which it enters when initially powered up.
One thing is that when I initialize the MAX7219, I put it into test mode for 1 second, which is supposed to light up all digits and segments but this does NOT happen.
So I am not sure but it is almost like there is no communication between the PIC16F690 and the MAX7219, but again, the SPI on the PIC16F690 does appear to be working. I can see the bytes being sent correctly (MSB first, 2 bytes per instruction set).
So I have no idea why this is not working and would really appreciate if someone would look things over and help me understand what the problem is.
I have included the schematic, the code, and the relevant datasheets. I am using MPLAB X IDE with XC8 compiler and coding in embedded C.
PIC16F690 datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/41262A.pdf
MAX7219 datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX7219-MAX7221.pdf
5641AH datasheet: http://www.xlitx.com/datasheet/5641AH.pdf
Thanks.
Schematic: Please note, the U13 identifier is wrong. It is a 5641AH LED display.
Code:
//NOT working. LED display does not light up.
//PIC16F690 CLK, SDO, and CS appear to be working properly as the signal are correct on the oscilloscope and on the correct pins.
//The pin voltages on the MAX7219 are: all digit pins high at 5V, all segment pins low at 0V, Dout (pin24) does have the Din (pin1) correct signal.
// PIC16F690 Configuration Bit Settings
//#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config FOSC = INTRCCLK // Oscillator Selection bits (INTOSC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // MCLR Pin Function Select bit (MCLR pin function is MCLR)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Selection bits (BOR enabled)
#pragma config IESO = ON // Internal External Switchover bit (Internal External Switchover mode is enabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#include <xc.h>
#define _XTAL_FREQ 8000000
//#define _XTAL_FREQ 1000000
//MAX7219 control registers
#define DECODE_REG 0x09
#define INTENSITY_REG 0x0A
#define SCANLIMIT_REG 0x0B
#define SHUTDOWN_REG 0x0C
#define TEST_REG 0x0F
//MAX7219 register program values
#define DECODE_ALL 0xFF //All digits decoded
#define INTENSITY_LEVEL_8 0x08 //Intensity 17/32nds of Max Value
#define SCANLIMIT_4 0x03 //Digits 0-3 (4 digits)
#define SHUTDOWN_MODE_ON 0x00 //Shutdown mode ON
#define SHUTDOWN_MODE_OFF 0x01 //Shutdown mode OFF
#define TEST_MODE_ON 0x01 //Test ON
#define TEST_MODE_OFF 0x00 //Test OFF
//MAX7219 digit addresses
#define DIGIT1 0x01
#define DIGIT2 0x02
#define DIGIT3 0x03
#define DIGIT4 0x04
//MAX7219 character addresses
#define CHAR0 0x00
#define CHAR1 0x01
#define CHAR2 0x02
#define CHAR3 0x03
#define CHAR4 0x04
#define CHAR5 0x05
#define CHAR6 0x06
#define CHAR7 0x07
//General use
char dummy;
int loop = 0;
void SPI_Write(char reg, char data)
{
PORTCbits.RC6 = 0; //Set CS line low to transmit
SSPBUF = reg; //Register address
while (SSPSTATbits.BF == 0){};
dummy = SSPBUF;
SSPBUF = data; //Value to send to register
while (SSPSTATbits.BF == 0){};
dummy = SSPBUF;
PORTCbits.RC6 = 1; //Set CS line high to latch sent data
}
void main()
{
//Ports
//All ports set to digital low
PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
//All analog ports disabled
ANSEL = 0x00;
ANSELH = 0x00;
//All ports set to output
TRISA = 0x00;
TRISB = 0x00;
TRISC = 0x00;
//Clock setup - clock set to 8MHz = 111
OSCCONbits.IRCF0 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF2 = 1;
//SPI port setup
//CLK - RB6
TRISBbits.TRISB6 = 0;
//SS - RC6
TRISCbits.TRISC6 = 0;
//SDO - RC7
TRISCbits.TRISC7 = 0;
//SDI - RB4
//TRISBbits.TRISB4 = 1;
//SPI module setup
SSPSTATbits.CKE = 0; //transmit on rising edge
SSPSTATbits.BF = 0; //buffer clear
SSPCONbits.CKP = 0; //clock polarity - idle low
SSPCONbits.SSPM0 = 0; //SPI Master mode, clock = FOSC/4
SSPCONbits.SSPM0 = 0;
SSPCONbits.SSPM0 = 0;
SSPCONbits.SSPM0 = 0;
SSPCONbits.SSPEN = 1; //enable SPI
__delay_ms(10); //allow to settle
while(1)
{
//Initialize MAX7219CNG
SPI_Write(DECODE_REG, DECODE_ALL);
SPI_Write(INTENSITY_REG, INTENSITY_LEVEL_8);
SPI_Write(SCANLIMIT_REG, SCANLIMIT_4);
SPI_Write(TEST_REG, TEST_MODE_ON);
__delay_ms(1000);
SPI_Write(TEST_REG, TEST_MODE_OFF);
SPI_Write(SHUTDOWN_REG, SHUTDOWN_MODE_OFF);
__delay_ms(1);
while (1)
{
//Write the number 2 to digit 2
SPI_Write(DIGIT2, CHAR2);
__delay_us(10);
}
}
}