Seven Segment Displays and Printout() Function

Discussion on projects that are created by users and posted on mikroElektronika website.
Post Reply
Author
Message
Bill Legge
Posts: 235
Joined: 28 Oct 2007 03:16
Location: West Australia

Seven Segment Displays and Printout() Function

#1 Post by Bill Legge » 15 Feb 2019 06:07

I know 7 segment displays are a bit old fashioned - but they are big, bright and I've got a few.
The following code uses a Futurlec 8X7 segment display (ET-SDP8) with a driver chip Max7219 that uses SPI to drive up to 8 displays.
Connected to an EasyPICv7 Connectivity board with a PIC18F46K22.
I've used the function Printout() to display the digits and it works with the flags %d, %u, %E, %e and width . precision.
The function that handles the SPI is SPI1_Putc1() and because this must deal with variable lengths of digits it looks for a terminating character '\r'
For example to display a float:

Code: Select all

float        fb = -0.000087654321;  // test number
Printout(SPI1_Putc1,"%.2e\r",fb);   // the \r tells the function SPI1_Putc1() that the stream is complete
I'd like to do away with this requirement but can't think of a better method - any ideas?
My working code follows:

Code: Select all

////////////////////////////////////////////////////////////////////////////////
// Project:         Futurlec_Displays                                         //
// File:            Futurlec_Displays.c                                       //
// Function:        Display on 8 Futurlec 7 segment displays                  //
//                  Display uses MAX7219 driver using SPI                     //
// MCU:             PIC1846K22                                                //
// Board:           EasyPICv7                                                 //
// Power:           5 Volts                                                   //
// Frequency:       32kHz                                                     //
// Compiler:        mikroC PRO for PIC version 7.2.0                          //
// Programmer:      ICD3 or on-board                                          //
// Author:          WVL                                                       //
// Date:            10 Feb 2019                                               //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Defines  for  MAX7219                                                      //
#define CS1    LATC0_bit    // data latched in on rising edge                 //
#define DECODE      0x09    // display digits data 00h to FFh to decode all   //
#define BRIGHTNESS  0x0A    // intensity      data 00h to 0Fh for maximum     //
#define SCANLIMIT   0x0B    // digits shown   data 00h to 07h for all         //
#define SHUTDOWN    0x0C    // on or off      data 00h or 01h for ON          //
#define ON          0x01                                                      //
#define OFF         0x00                                                      //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Set initial conditions on MAX7219 7 segment driver              //
void Max7219_Init(){                                                          //
    // Cycle load     // First byte           // Second byte                  //
    CS1 = 1; CS1 = 0; SPI1_Write(SHUTDOWN);   SPI1_Write(ON);   // on         //
    CS1 = 1; CS1 = 0; SPI1_Write(DECODE);     SPI1_Write(0xFF); // decode all //
    CS1 = 1; CS1 = 0; SPI1_Write(BRIGHTNESS); SPI1_Write(0x0F); // max        //
    CS1 = 1; CS1 = 0; SPI1_Write(SCANLIMIT);  SPI1_Write(0x07); // show all   //
    CS1 = 1;                                                                  //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Clear 7 segment display CS1 using display address 1-8           //
void Segment1_Clear(){                                                        //
    char x = 0;                                                               //
    for(x=1;x<=8;x++){                                                        //
        CS1 = 0;                                                              //
        SPI1_Write(x);                                                        //
        SPI1_Write(0xF);                                                      //
        CS1 = 1;                                                              //
    }                                                                         //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Show variables on 7 segment displays using SPI and CS=1         //
//            Normal Printout() descriptors %d %u %f with width and precision //
//            Decodes E,e,-,. as special cases. + signs not displayed         //
//            Requires all Printout() functions to be terminated with '\r'    //
void SPI1_Putc1(char ascii){                                                  //
    char     display = 0;               // set to display a character         //
    static char    x = 8;               // x is digit address, 8 is leftmost  //
    static  old_byte = 0;               // last byte already displayed        //
    char byte = ascii-48;               // convert ASCII to digit             //
        if(ascii=='+'){                 // test for '+' signs                 //
            display = 0;                // don't display                      //
        }                                                                     //
        if(ascii=='E'||ascii=='e'){     // test for 'e' or 'E'                //
            byte = 0x0B;                // E in MAX7219 decode                //
            display = 1;                // display 'E'                        //
        }                                                                     //
        if(ascii=='-'){                 // test for '-'                       //
            byte = 0x0A;                // - in MAX7219 decode                //
            display = 1;                // display '-'                        //
        }                                                                     //
        if(isdigit(ascii)){             // test for digits 0 to 9             //
            old_byte=byte;              // in case next character is '.'      //
            display = 1;                // display digits 0-9                 //
        }                                                                     //
        if(ascii=='.'){                 // test for a '.'                     //
            byte = old_byte|0x80;       // add decimal point 0x80 to old byte //
            x++;                        // move back 1 address to the left    //
            display = 1;                // display '.' with  previous digit   //
        }                                                                     //
        if(ascii=='\r'){                // test for termination '\r'          //
            x=8;                        // leftmost digit                     //
            old_byte=0;                                                       //
            display =0;                                                       //
        }                                                                     //
        // Write byte to address X if display has been set                    //
        if(display){                                                          //
            CS1 = 0;                    // active low                         //
            SPI1_Write(x);              // digit address 8=left, 1=right      //
            SPI1_Write(byte);           // byte to be displayed               //
            CS1 = 1;                    // deselect                           //
            x--;                        // move address to the right          //
            display = 0;                // clear the flag                     //
        }                                                                     //
    return;                                                                   //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

void main() {
    char          n = 0;
    unsigned int ui =  65500;           // test number
    signed int   si = -12001;           // test number
    signed int   sj = -1;               // test number
    float        fa = 1.2345678;        // test number
    float        fb = -0.000087654321;  // test number
    float        fc = 987.654;          // test number
    float        fd = 1234567.1;        // test number
    // Ports and pins
    ANSELA = 0b00000000;    // 1=analog 0=digital
    ANSELB = 0b00000000;    // 1=analog 0=digital
    ANSELC = 0b00000000;    // 1=analog 0=digital
    ANSELD = 0b00000000;    // 1=analog 0=digital
    ANSELE = 0b00000000;    // 1=analog 0=digital
    WPUB   = 0b00000000;    // pull up 1=enabled 0=disabled
    TRISA  = 0b00000000;    //
    TRISB  = 0b00000000;    //
    TRISC  = 0b00000000;    //
    TRISD  = 0b00000000;    //
    TRISE  = 0b00000000;    //
    LATA   = 0;
    LATB   = 0;
    LATC   = 0;
    LATD   = 0;
    LATE   = 0;
    // Peripherals
    UART1_Init(9600);       // use RC6/Tx1 RC7/Rx1 not RD6/Tx2 RD7/Rx2
    delay_ms(10);
    UART1_Write_Text("EasyPICv7_Futurlec_Displays running at 32MHz\r\n");
    SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
    Max7219_Init();
    // Flash LEDs
    for(n=0;n<10;n++){LATD = ~LATD;delay_ms(100);}
    
    while(1){
        // Display on the 7 segments using SPI1 and CS1
        Segment1_Clear();
        Printout(SPI1_Putc1,"%u\r",ui);     // 65500
        delay_ms(3000);
        Segment1_Clear();
        Printout(SPI1_Putc1,"%d\r",si);     // -12001
        delay_ms(3000);
        Segment1_Clear();
        Printout(SPI1_Putc1,"%d\r",sj);     // -1
        delay_ms(3000);
        Segment1_Clear();
        Printout(SPI1_Putc1,"%f\r",fa);     // 1.2345678
        delay_ms(3000);
        Segment1_Clear();
        Printout(SPI1_Putc1,"%.2e\r",fb);   // -0.000087654321
        delay_ms(3000);
        Segment1_Clear();
        Printout(SPI1_Putc1,"%7.3f\r",fc);  // 987.654
        delay_ms(3000);
        Segment1_Clear();
        Printout(SPI1_Putc1,"%.3e\r",fd);   // 1234567.1
        delay_ms(3000);
        Segment1_Clear();
        // Housekeeping
        delay_ms(1000);
        LATE0_bit = ~LATE0_bit;
    }
}
Regards Bill Legge in Australia
Attachments
Futurlec Display Circuit Diagram Small.pdf
(253.55 KiB) Downloaded 148 times
Last edited by Bill Legge on 17 Feb 2019 23:47, edited 1 time in total.

hexreader
Posts: 1786
Joined: 27 Jun 2010 12:07
Location: England

Re: Seven Segment Displays and Printout() Function

#2 Post by hexreader » 17 Feb 2019 19:56

Tried a few different options for solving the problem, but failed every time.

Seems to me that an answer is to set x back to 8 as part of the delay operation, or as part of the clear operation. Requires making x and a couple of other variables global.

Bit confused as to why there is an X (capital) declared in main and x (lower case) declared within functions. Probably harmless, as scope will be different, but still a cause of confusion to me.

Suspect there is a simple solution, but it evades my brain right now.

Maybe my ramblings will trigger you to spot some kind of fix.

.... or maybe the way you did it is actually a good way, since it avoids use of global declarations? ...
Start every day with a smile...... (get it over with) :)

Bill Legge
Posts: 235
Joined: 28 Oct 2007 03:16
Location: West Australia

Re: Seven Segment Displays and Printout() Function

#3 Post by Bill Legge » 17 Feb 2019 23:46

MCU and Displays.pdf
(168.67 KiB) Downloaded 127 times
Hexreader thanks for your thoughts.
1. The big X and small x. Nothing to do with each other, as you say the scope 'separates' them. I always make my code 'case insensitive' so my compiler does not pick up this sort of fault. Confusing, so I've amended the code.
2. Variable lengths and '\r' terminator. Can't think of a solution apart from making everything the same length! A bit difficult to do with the 'e' format?
3. Nearly finished my project - Aim is to make a general purpose display unit to display variables when developing code. I've used three displays driven by a Olimex PIC40 board - drawing attached. Will be driven by RS232 or SPI from the development board. I'ts looking good so far.

Regards Bill Legge in Australia

hexreader
Posts: 1786
Joined: 27 Jun 2010 12:07
Location: England

Re: Seven Segment Displays and Printout() Function

#4 Post by hexreader » 18 Feb 2019 02:23

Brain now functioning again. Here is my attempt with no "\r"

Code: Select all

////////////////////////////////////////////////////////////////////////////////
// Project:         Futurlec_Displays                                         //
// File:            Futurlec_Displays.c                                       //
// Function:        Display on 8 Futurlec 7 segment displays                  //
//                  Display uses MAX7219 driver using SPI                     //
// MCU:             PIC1846K22                                                //
// Board:           EasyPICv7                                                 //
// Power:           5 Volts                                                   //
// Frequency:       32kHz                                                     //
// Compiler:        mikroC PRO for PIC version 7.2.0                          //
// Programmer:      ICD3 or on-board                                          //
// Author:          WVL                                                       //
// Date:            10 Feb 2019                                               //
////////////////////////////////////////////////////////////////////////////////

// global variables
unsigned char new_disp = 1;                          // flag for new LED display

////////////////////////////////////////////////////////////////////////////////
// Defines  for  MAX7219                                                      //
#define CS1    LATC0_bit    // data latched in on rising edge                 //
#define DECODE      0x09    // display digits data 00h to FFh to decode all   //
#define BRIGHTNESS  0x0A    // intensity      data 00h to 0Fh for maximum     //
#define SCANLIMIT   0x0B    // digits shown   data 00h to 07h for all         //
#define SHUTDOWN    0x0C    // on or off      data 00h or 01h for ON          //
#define ON          0x01                                                      //
#define OFF         0x00                                                      //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Set initial conditions on MAX7219 7 segment driver              //
void Max7219_Init(){                                                          //
    // Cycle load     // First byte           // Second byte                  //
    CS1 = 1; CS1 = 0; SPI1_Write(SHUTDOWN);   SPI1_Write(ON);   // on         //
    CS1 = 1; CS1 = 0; SPI1_Write(DECODE);     SPI1_Write(0xFF); // decode all //
    CS1 = 1; CS1 = 0; SPI1_Write(BRIGHTNESS); SPI1_Write(0x0F); // max        //
    CS1 = 1; CS1 = 0; SPI1_Write(SCANLIMIT);  SPI1_Write(0x07); // show all   //
    CS1 = 1;                                                                  //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Clear 7 segment display CS1 using display address 1-8           //
void Segment1_Clear(){                                                        //
    char x = 0;                                                               //
    for(x=1;x<=8;x++){                                                        //
        CS1 = 0;                                                              //
        SPI1_Write(x);                                                        //
        SPI1_Write(0xF);                                                      //
        CS1 = 1;                                                              //
    }
    new_disp = 1;               // start a new LED display                     //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Show variables on 7 segment displays using SPI and CS=1         //
//            Normal Printout() descriptors %d %u %f with width and precision //
//            Decodes E,e,-,. as special cases. + signs not displayed         //
//            Requires all Printout() functions to be terminated with '\r'    //
void SPI1_Putc1(char ascii){                                                  //
    char     display = 0;               // set to display a character         //
    static char    x = 8;               // x is digit address, 8 is leftmost  //
    static  old_byte = 0;               // last byte already displayed        //
    char byte = ascii-48;               // convert ASCII to digit             //
        
        if(new_disp){                   // is a new display wanted
            new_disp = 0;               // reset flag
            x = 8;                      // cursor to left
            old_byte = 0;               // initialise
        }
        if(ascii=='+'){                 // test for '+' signs                 //
            display = 0;                // don't display                      //
        }                                                                     //
        if(ascii=='E'||ascii=='e'){     // test for 'e' or 'E'                //
            byte = 0x0B;                // E in MAX7219 decode                //
            display = 1;                // display 'E'                        //
        }                                                                     //
        if(ascii=='-'){                 // test for '-'                       //
            byte = 0x0A;                // - in MAX7219 decode                //
            display = 1;                // display '-'                        //
        }                                                                     //
        if(isdigit(ascii)){             // test for digits 0 to 9             //
            old_byte=byte;              // in case next character is '.'      //
            display = 1;                // display digits 0-9                 //
        }                                                                     //
        if(ascii=='.'){                 // test for a '.'                     //
            byte = old_byte|0x80;       // add decimal point 0x80 to old byte //
            x++;                        // move back 1 address to the left    //
            display = 1;                // display '.' with  previous digit   //
        }                                                                     //
        if(ascii=='\r'){                // test for termination '\r'          //
            x=8;                        // leftmost digit                     //
            old_byte=0;                                                       //
            display =0;                                                       //
        }                                                                     //
        // Write byte to address X if display has been set                    //
        if(display){                                                          //
            CS1 = 0;                    // active low                         //
            SPI1_Write(x);              // digit address 8=left, 1=right      //
            SPI1_Write(byte);           // byte to be displayed               //
            CS1 = 1;                    // deselect                           //
            x--;                        // move address to the right          //
            display = 0;                // clear the flag                     //
        }                                                                     //
    return;                                                                   //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

void main() {
    char          n = 0;
    unsigned int ui =  65500;           // test number
    signed int   si = -12001;           // test number
    signed int   sj = -1;               // test number
    float        fa = 1.2345678;        // test number
    float        fb = -0.000087654321;  // test number
    float        fc = 987.654;          // test number
    float        fd = 1234567.1;        // test number
    // Ports and pins
    ANSELA = 0b00000000;    // 1=analog 0=digital
    ANSELB = 0b00000000;    // 1=analog 0=digital
    ANSELC = 0b00000000;    // 1=analog 0=digital
    ANSELD = 0b00000000;    // 1=analog 0=digital
    ANSELE = 0b00000000;    // 1=analog 0=digital
    WPUB   = 0b00000000;    // pull up 1=enabled 0=disabled
    TRISA  = 0b00000000;    //
    TRISB  = 0b00000000;    //
    TRISC  = 0b00000000;    //
    TRISD  = 0b00000000;    //
    TRISE  = 0b00000000;    //
    LATA   = 0;
    LATB   = 0;
    LATC   = 0;
    LATD   = 0;
    LATE   = 0;
    // Peripherals
    UART1_Init(9600);       // use RC6/Tx1 RC7/Rx1 not RD6/Tx2 RD7/Rx2
    delay_ms(10);
    UART1_Write_Text("EasyPICv7_Futurlec_Displays running at 32MHz\r\n");
    SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
    Max7219_Init();
    // Flash LEDs
    for(n=0;n<10;n++){LATD = ~LATD;delay_ms(100);}

    while(1){
        // Display on the 7 segments using SPI1 and CS1
        Segment1_Clear();
        Printout(SPI1_Putc1,"%u",ui);     // 65500
        delay_ms(3000);
        Segment1_Clear();
        Printout(SPI1_Putc1,"%d",si);     // -12001
        delay_ms(3000);
        Segment1_Clear();
        Printout(SPI1_Putc1,"%d",sj);     // -1
        delay_ms(3000);
        Segment1_Clear();
        Printout(SPI1_Putc1,"%f",fa);     // 1.2345678
        delay_ms(3000);
        Segment1_Clear();
        Printout(SPI1_Putc1,"%.2e",fb);   // -0.000087654321
        delay_ms(3000);
        Segment1_Clear();
        Printout(SPI1_Putc1,"%7.3f",fc);  // 987.654
        delay_ms(3000);
        Segment1_Clear();
        Printout(SPI1_Putc1,"%.3e",fd);   // 1234567.1
        delay_ms(3000);
        Segment1_Clear();
        // Housekeeping
        delay_ms(1000);
        LATE0_bit = ~LATE0_bit;
    }
}
Start every day with a smile...... (get it over with) :)

Bill Legge
Posts: 235
Joined: 28 Oct 2007 03:16
Location: West Australia

Re: Seven Segment Displays and Printout() Function

#5 Post by Bill Legge » 19 Feb 2019 00:45

Hex reader,
Thanks for that - It looks like a good solution to avoid the need for a '\r'
I can't try it at the moment as by test rig is 'up the creek'
The displays work OK using the RS232 interrupt but I've been adding code to use SPI as an alternative.
Problem is the SPI slave on the PIC18F46K22:

Code: Select all

////////////////////////////////////////////////////////////////////////////////
// Defines                                                                    //
#define LED_OLIMEX  LATA0_bit                                                 //
#define LED_RED     LATA2_bit                                                 //
#define LED_GREEN   LATA3_bit                                                 //
#define LED_YELLOW  LATA4_bit                                                 //
#define LED_WHITE   LATA5_bit                                                 //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Globals                                                                    //
char instring[21] = "1234567890";   // loaded after header detected           //
bit  good_data;                     // set in RS232 interrupt, cleared in main//
char display_number = 0;            // 0 to 2, always instring[0]             //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// ISR for all HIGH priority interrupts to 0x0008. Low go to 0018h            //
void high_priority_int() iv 0x0008 ics ICS_AUTO {                             //
    // Test if SSP2 has received a character.                                 //
    // Look for header SHOW and record until '\r' is received, set good_data  //
    // Re-set all variables if >20 characters are received before '\r'        //
    if(SSP2IF_bit){                                                           //
        unsigned short            rxtemp=0;   // last character rx from base  //
        static unsigned short lock_state=0;   // inc after good ID character  //
        static unsigned short          x=0;   // array counter                //
        unsigned short           dummy = 0;
        static unsigned short     got_id=0;   // TRUE after all ID received   //
        // Receive a character                                                //
        rxtemp  = SPI2_Read(dummy);                                           //
        LED_RED = ~LED_RED;                                                   //
        // Header has been received so start filling array                    //
        if(got_id==1){                                                        //
            LED_RED   = 1;                                                    //
            LED_GREEN = 1;                                                    //
            instring[x] = rxtemp;                                             //
            x++;                                                              //
        }                                                                     //
        if(x>20){                                                             //
            LED_RED    = 0;                                                   //
            LED_GREEN  = 0;                                                   //
            LED_YELLOW = 0;                                                   //
            lock_state = 0;                                                   //
            got_id     = 0;                                                   //
            good_data  = 0;                                                   //
            x          = 0;                                                   //
        }                                                                     //
        // Test if '\r' has been received and terminate string with '\0'      //
        if(instring[x-1]=='\r'){                                              //
            instring[x]='\0';                                                 //
            got_id     = 0;                                                   //
            x          = 0;                                                   //
            LED_RED    = 0;                                                   //
            LED_GREEN  = 0;                                                   //
            LED_YELLOW = 1;                                                   //
            good_data  = 1;                                                   //
        }                                                                     //
        // Search for id = 'SHOW' and if found set got_id                     //
        if      (rxtemp== 'S' && lock_state == 0)lock_state++;                //
        else if (rxtemp== 'H' && lock_state == 1)lock_state++;                //
        else if (rxtemp== 'O' && lock_state == 2)lock_state++;                //
        else if (rxtemp== 'W' && lock_state == 3)got_id = 1;                  //
        else lock_state = 0;   // id wrong so reset combination               //
                                                                              //
        SSP2IF_bit = 0;         // clear interrupt flag                       //
    }                                                                         //                                                                                                                                                          //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

void main() {
    char x = 0;
    // Ports and pins
    ANSELA = 0b00000000;    // 1=analog 0=digital
    ANSELB = 0b00000000;    // 1=analog 0=digital
    ANSELC = 0b00000000;    // 1=analog 0=digital
    ANSELD = 0b00000000;    // 1=analog 0=digital
    ANSELE = 0b00000000;    // 1=analog 0=digital
    WPUB   = 0b00000000;    // pull up 1=enabled 0=disabled
    TRISA  = 0b00000000;    //
    TRISB  = 0b00000000;    //
    TRISC  = 0b00000000;    //
    // SPI2 uses PORTD so set the pins for ip or op
    TRISD0_bit = 1;         // ip for SCK2
    TRISD1_bit = 1;         // ip for SDI2
    TRISD3_bit = 1;         // ip for SS2
    TRISD4_bit = 0;         // 0p for SDO2
    TRISE  = 0b00000000;    //
    LATA   = 0;
    LATB   = 0;
    LATC   = 0;
    LATD   = 0;
    LATE   = 0;
    // Peripherals
    PMD1 = 0b00011111;      // all CCPs off
    PMD2 = 0xFF;            // all off but watch out for ADC?
    SPI2_Init_Advanced(_SPI_SLAVE_SS_DIS,_SPI_DATA_SAMPLE_MIDDLE,_SPI_CLK_IDLE_LOW,_SPI_HIGH_2_LOW);
    // Flash LEDs
    for(x=0;x<10;x++){LATA = ~LATA;delay_ms(100);}
    // Interruptst
    SSP2IP_bit = 1;         // SSP2 is high priority
    SSP2IF_bit = 0;         // CLEAR interrupt flag
    SSP2IE_bit = 1;         // ENABLE SSP2 interrupt
    IPEN_bit   = 1;         // ENABLE interrupt prioroty
    GIEH_bit   = 1;         // ENABLE all high priority ints
    GIEL_bit   = 1;         // ENABLE all low priority ints
    good_data  = 0;
    while(1){
        // If good_data, read instring
        if(good_data){
            // Read display number
            if(display_number=='0')LED_WHITE = ~LED_WHITE;
            if(display_number=='1')LED_WHITE = ~LED_WHITE;
            if(display_number=='2')LED_WHITE = ~LED_WHITE;
            good_data = 0;
            LED_YELLOW = 0;
        }
        // Housekeeping
        LED_OLIMEX = ~LED_OLIMEX;
    }
}  
My scope shows the problem - SDI2/RD1 should be an input but when I set the SPI_Init, it turns it into an output.
Any ideas?
Regards Bill Legge in Australia

hexreader
Posts: 1786
Joined: 27 Jun 2010 12:07
Location: England

Re: Seven Segment Displays and Printout() Function

#6 Post by hexreader » 19 Feb 2019 11:22

Not worked with SPI slave before, but I see this in the help text:
The mikroC PRO for PIC provides a library for comfortable with SPI work in Master mode. The PIC MCU can easily communicate with other devices via SPI: A/D converters, D/A converters, MAX7219, LTC1290, etc.
I take this to mean that library will not support slave operation, even though there is no explicit statement of that

I think that you will need to manipulate SPI registers in code, and avoid the SPI library

Code: Select all

      rxtemp  = SPI2_Read(dummy); 
Presumably your interrupt will be in response to receiving a byte of data, but this function fetches a second byte. I doubt that this is what you intended.

My SPI knowledge is sketchy, so I could be wrong

When I load your code to easyPIC7 board, RD1 appears to be happily operating as input. Don't see any obvious configuration bit that might affect it. Could it be that you have a hardware short or similar?

RD0 is output, but that is because library SPI init will have set your SPI module as master.
Start every day with a smile...... (get it over with) :)

hexreader
Posts: 1786
Joined: 27 Jun 2010 12:07
Location: England

Re: Seven Segment Displays and Printout() Function

#7 Post by hexreader » 19 Feb 2019 12:25

Looks like I am wrong about SPI slave and library, judging by the example on Libstock..

https://libstock.mikroe.com/projects/vi ... party-pack
Start every day with a smile...... (get it over with) :)

Bill Legge
Posts: 235
Joined: 28 Oct 2007 03:16
Location: West Australia

Re: Seven Segment Displays and Printout() Function

#8 Post by Bill Legge » 19 Feb 2019 12:45

After lots of help from people, I've got some working code:
1. Using a PIC18F46K22 on an Olimex 40 pin board with three Futurlec 7 segment displays.
2. The code uses interrupts to look for RS232 or SPI messages and displays the results on one of the 7 segment displays.
3. The driving message is either RS232 or SPI and uses the Printout function. Two examples:
Printout(UART1_Write,"SHOW0%.3e\r",fd); // SHOW 1234567.1 on display 0
Printout(SPI1_Write, "SHOW2%7.3f\r",fc); // SHOW 987.654 on display 2
Both RS232 and SPI messages must be terminated by a '\r' to let the interrupt know that the message has ended.
Files are attached:
.c and .h files for the displays.
.c file to drive/test the displays.
some drawing files of the wiring.
Things that you may find useful and want to copy from the code:
1. SPI_Init_Advanced() on the PIC18F46K22 is not straightforward and took some help from MikeoE Filip.
2. Interrupt code for SPI and RS232 messages.
3. Using code to find a header ('SHOW') and a terminator ('\r') in the message stream.
4. Driving the MAX7219 seven segment driver chip.
And - if you are an ace programmer and spot an easier to do this - please post your improvements here.
Code for display .h

Code: Select all

////////////////////////////////////////////////////////////////////////////////
// Project:         Futurlec_Displays                                         //
// File:            Futurlec_Displays.h                                       //
// Function:        Display on 4 Futurlec 7 segment dusplays                  //
//                  Display uses MAX7219 driver using SPI                     //
// MCU:             PIC1846K22                                                //
// Board:           EasyPICv7                                                 //
// Power:           5 Volts                                                   //
// Frequency:       32kHz                                                     //
// Compiler:        mikroC PRO for PIC version 7.2.0                          //
// Programmer:      ICD3 or on-board                                          //
// Author:          WVL                                                       //
// Date:            10 Feb 2019                                               //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Displays driven by MAX7219 seven segment driver                            //
// The digits are numbered 0 to 7 but have addresses 1 to 8                   //
// This code uses the address 1-8, not the digit number                       //
// Address 8 is the leftmost digit. Address 1 is the rightmost digit          //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// DECODE Register Address 0x09                                               //
// 1 in register does decode, 0 by-passes                                     //
// SCANLIMIT Register Address 0xB                                             //
// 1 in register displays digit, 0 gives no display of digit                  //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Pin allocation PIC18(L)F46K22 64k Flash, 32768 Instructions, 3896 Data     //
// Two SPI:                                                                   //
// SDO1    RC5          SDO2    RD4                                           //
// SDI1    RC4          SDI2    RD1                                           //
// SCK1    RC3          SCK2    RD0                                           //
// LOAD0   RB0          Bottom display active on rising edge                  //
// LOAD1   RB1          Middle display                                        //
// LOAD2   RB2          Top    display                                        //
// Maximum clock is 10MHz                                                     //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Defines                                                                    //
#define CS0    LATB0_bit    // bottom display                                 //
#define CS1    LATB1_bit    // data latched in on rising edge                 //
#define CS2    LATB2_bit    // top display                                    //
#define DECODE      0x09    // display digits data 00h to FFh to decode all   //
#define BRIGHTNESS  0x0A    // intensity      data 00h to 0Fh for maximum     //
#define SCANLIMIT   0x0B    // digits shown   data 00h to 07h for all         //
#define SHUTDOWN    0x0C    // on or off      data 00h or 01h for ON          //
#define ON          0x01                                                      //
#define OFF         0x00                                                      //
#define LED_OLIMEX  LATA0_bit                                                 //
#define LED_RED     LATA2_bit                                                 //
#define LED_GREEN   LATA3_bit                                                 //
#define LED_YELLOW  LATA4_bit                                                 //
#define LED_WHITE   LATA5_bit                                                 //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Globals                                                                    //
char instring[21] = "1234567890";   // loaded after header detected           //
bit  good_data;            // set in RS232 or SPI2 interrupt, cleared in main //
char display_number = 0;            // 0 to 2, always instring[0]             //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Set initial conditions on all MAX7219 7 segment drivers         //
void Max7219_InitAll();                                                       //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Clear one 7 segment display using display address 1-8           //
//            Bottom dusplay= 0. Middle = 1. Top = 2                          //
void Segment_Clear(char chip_select);                                         //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Clear all 7 segment display CS0-CS2 using display address 1-8   //
void Segment_ClearAll();                                                      //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Show variables on 7 segment displays using SPI1 and CS=0        //
//            Normal Printout() descriptors %d %u %f with width and precision //
//            Decodes E,e,-,. as special cases. + signs not displayed         //
//            Requires all Printout() functions to be terminated with '\r'    //
void SPI1_Putc0(char ascii);                                                  //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Show variables on 7 segment displays using SPI1 and CS=1        //
//            Normal Printout() descriptors %d %u %f with width and precision //
//            Decodes E,e,-,. as special cases. + signs not displayed         //
//            Requires all Printout() functions to be terminated with '\r'    //
void SPI1_Putc1(char ascii);                                                  //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Show variables on 7 segment displays using SPI1 and CS=2        //
//            Normal Printout() descriptors %d %u %f with width and precision //
//            Decodes E,e,-,. as special cases. + signs not displayed         //
//            Requires all Printout() functions to be terminated with '\r'    //
void SPI1_Putc2(char ascii);                                                  //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Show demo on all displays                                       //
void Demo_Display();                                                          //
////////////////////////////////////////////////////////////////////////////////
Code for displa .c

Code: Select all

////////////////////////////////////////////////////////////////////////////////
// Project:         Futurlec_Displays                                         //
// File:            Futurlec_Displays.c                                       //
// Function:        Display on 4 Futurlec 7 segment displays                  //
//                  Display uses MAX7219 driver using SPI                     //
// MCU:             PIC1846K22                                                //
// Board:           EasyPICv7                                                 //
// Power:           5 Volts                                                   //
// Frequency:       32kHz                                                     //
// Compiler:        mikroC PRO for PIC version 7.2.0                          //
// Programmer:      ICD3 or on-board                                          //
// Author:          WVL                                                       //
// Date:            10 Feb 2019                                               //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Last notes                                                                 //
// SPI now working - special file from forum downloaded to                    //
// C:\Users\Public\Documents\Mikroelektronika\mikroC PRO for PIC\Uses\P18     //
////////////////////////////////////////////////////////////////////////////////

#include "Futurlec_Displays.h" // prototypes, definintions, globals

////////////////////////////////////////////////////////////////////////////////
// ISR for all HIGH priority interrupts to 0x0008. Low go to 0018h            //
void high_priority_int() iv 0x0008 ics ICS_AUTO {                             //
    // Test if UART1 has received a character.                                //
    // Look for header SHOW and record until '\r' is received, set good_data  //
    // Re-set all variables if >20 characters are received before '\r'        //
    if(RC1IF_bit){                                                            //
        unsigned short            rxtemp=0;   // last character rx from base  //
        static unsigned short lock_state=0;   // inc after good ID character  //
        static unsigned short          x=0;   // array counter                //
        static unsigned short     got_id=0;   // TRUE after all ID received   //
        // Writing '0' clears errors                                          //
        RCSTA1.OERR= 0;                                                       //
        RCSTA1.FERR= 0;                                                       //
        // Receive a character                                                //
        rxtemp  = UART1_Read();                                               //
        LED_RED = ~LED_RED;                                                   //
        // Header has been received so start filling array                    //
        if(got_id==1){                                                        //
            LED_GREEN = 1;                                                    //
            instring[x] = rxtemp;                                             //
            x++;                                                              //
        }                                                                     //
        // instring is 20 bytes+'\0' test for overflow                        //
        if(x>20){                                                             //
            LED_RED    = 0;                                                   //
            LED_GREEN  = 0;                                                   //
            lock_state = 0;                                                   //
            got_id     = 0;                                                   //
            good_data  = 0;                                                   //
            x          = 0;                                                   //
        }                                                                     //
        // Test if '\r' AND got_id received and terminate string with '\0'    //
        // If so, set LED_WHITE and good_data                                 //
        if(instring[x-1]=='\r'  && got_id==1){                                //
            instring[x]='\0';                                                 //
            got_id     = 0;                                                   //
            x          = 0;                                                   //
            LED_RED    = 0;                                                   //
            LED_GREEN  = 0;                                                   //
            LED_WHITE  = 1;                                                   //
            good_data  = 1;                                                   //
        }                                                                     //
        // Search for id = 'SHOW' and if found set got_id                     //
        if      (rxtemp== 'S' && lock_state == 0)lock_state++;                //
        else if (rxtemp== 'H' && lock_state == 1)lock_state++;                //
        else if (rxtemp== 'O' && lock_state == 2)lock_state++;                //
        else if (rxtemp== 'W' && lock_state == 3)got_id = 1;                  //
        else lock_state = 0;   // id wrong so reset combination               //
                                                                              //
        RC1IF_bit = 0;         // clear interrupt flag                        //
    }                                                                         //
                                                                              //
    // Test if SSP2 has received a character.                                 //
    // Look for header SHOW and record until '\r' is received, set good_data  //
    // Re-set all variables if >20 characters are received before '\r'        //
    if(SSP2IF_bit){                                                           //
        char                      rxtemp=0;   // last character rx from base  //
        static unsigned short lock_state=0;   // inc after good ID character  //
        static unsigned short          x=0;   // array counter                //
        static unsigned short     got_id=0;   // TRUE after all ID received   //
        // Receive a character                                                //
        rxtemp  = SSP2BUF;                                                    //
        LED_RED = ~LED_RED;                                                   //
        // Header has been received so start filling array                    //
        if(got_id==1){                                                        //
            LED_GREEN = 1;                                                    //
            instring[x] = rxtemp;                                             //
            x++;                                                              //
        }                                                                     //
        // instring is 20 bytes+'\0' test for overflow                        //
        if(x>20){                                                             //
            LED_RED    = 0;                                                   //
            LED_GREEN  = 0;                                                   //
            lock_state = 0;                                                   //
            got_id     = 0;                                                   //
            good_data  = 0;                                                   //
            x          = 0;                                                   //
        }                                                                     //
        // Test if '\r' AND got_id received and terminate string with '\0'    //
        // If so, set LED_YELLOW and good_data                                //
        if(instring[x-1]=='\r' && got_id==1){                                 //
            instring[x]='\0';                                                 //
            got_id     = 0;                                                   //
            x          = 0;                                                   //
            LED_RED    = 0;                                                   //
            LED_GREEN  = 0;                                                   //
            LED_YELLOW = 1;                                                   //
            good_data  = 1;                                                   //
        }                                                                     //
        // Search for id = 'SHOW' and if found set got_id                     //
        if      (rxtemp== 'S' && lock_state == 0)lock_state++;                //
        else if (rxtemp== 'H' && lock_state == 1)lock_state++;                //
        else if (rxtemp== 'O' && lock_state == 2)lock_state++;                //
        else if (rxtemp== 'W' && lock_state == 3)got_id = 1;                  //
        else lock_state = 0;   // id wrong so reset combination               //
                                                                              //
        SSP2IF_bit = 0;         // clear interrupt flag                       //
    }                                                                         //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

void main() {
    char x = 0;
    // Ports and pins
    ANSELA = 0b00000000;    // 1=analog 0=digital
    ANSELB = 0b00000000;    // 1=analog 0=digital
    ANSELC = 0b00000000;    // 1=analog 0=digital
    ANSELD = 0b00000000;    // 1=analog 0=digital
    ANSELE = 0b00000000;    // 1=analog 0=digital
    WPUB   = 0b00000000;    // pull up 1=enabled 0=disabled
    TRISA  = 0b00000000;    // LEDs on RA0 and RA2 to RA5
    TRISB  = 0b00000000;    // chip selects on RB0 to RB2
    // SPI1 on PORTC is a MASTER
    TRISC3_bit = 0;         // op for SCK1  - used
    TRISC4_bit = 1;         // ip for SDI1  - unused
    TRISC5_bit = 0;         // op for SDO1  - used
    // SPI2 on PORD is s SLAVE
    TRISD0_bit = 1;         // ip for SCK2  - used
    TRISD1_bit = 1;         // ip for SDI2  - used
    TRISD3_bit = 1;         // ip for SS2   - unused
    TRISD4_bit = 0;         // op for SDO2  - unused
    // UART1 on PORTC
    TRISC6_bit = 0;         // op for UART1 - used
    TRISC7_bit = 1;         // ip for UART1 - used
    LATA   = 0;
    LATB   = 0;
    LATC   = 0;
    LATD   = 0;
    LATE   = 0;
    // Peripherals
    PMD1 = 0b00011111;      // CCP1MD to CCP5MD off
    UART1_Init(9600);       // use RC6/Tx1 RC7/Rx1 not RD6/Tx2 RD7/Rx2    _SPI_CLK_IDLE_LOW
    delay_ms(5);
    UART1_Write_Text("EasyPICv7_Futurlec_Displays running at 20MHz\r\n");
    SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4,_SPI_DATA_SAMPLE_MIDDLE,_SPI_CLK_IDLE_LOW,_SPI_LOW_2_HIGH);
    SPI2_Init_Advanced(_SPI_SLAVE_SS_DIS,_SPI_DATA_SAMPLE_MIDDLE,_SPI_CLK_IDLE_LOW,_SPI_LOW_2_HIGH);
    Max7219_InitAll();
    Segment_ClearAll();
    // Flash LEDs
    for(x=0;x<10;x++){LATA = ~LATA;delay_ms(50);}
    // Run demo
    Demo_Display();
    // Interrupts
    RC1IP_bit  = 1;         // UART1 Rx is high priority
    RC1IF_bit  = 0;         // CLEAR interrupt flag
    RC1IE_bit  = 1;         // ENABLE U1Rx interrupt
    SSP2IP_bit = 1;         // SSP2 is high priority
    SSP2IF_bit = 0;         // CLEAR interrupt flag
    SSP2IE_bit = 1;         // ENABLE SSP2 interrupt
    IPEN_bit   = 1;         // ENABLE interrupt prioroty
    GIEH_bit   = 1;         // ENABLE all high priority ints
    GIEL_bit   = 1;         // ENABLE all low priority ints
    good_data  = 0;         // clear flag
    
    while(1){
        // If good_data, read instring
        if(good_data){
            // Read display number
            display_number = instring[0];
            x = 1;
            if(display_number=='0'){
                Segment_Clear(0);
                while(instring[x] !='\0'){
                    SPI1_Putc0(instring[x]);
                    x++;
                    if(x>20)break;
                }
            }
            if(display_number=='1'){
                Segment_Clear(1);
                while(instring[x] !='\0'){
                    SPI1_Putc1(instring[x]);
                    x++;
                    if(x>20)break;
                }
            }
            if(display_number=='2'){
                Segment_Clear(2);
                while(instring[x] !='\0'){
                    SPI1_Putc2(instring[x]);
                    x++;
                    if(x>20)break;
                }
            }
            good_data = 0;
            LED_YELLOW = 0;
            LED_WHITE  = 0;
        }
        // Housekeeping
        LED_OLIMEX = ~LED_OLIMEX;
        Delay_ms(1);
    }
}
////////////////////////////////////////////////////////////////////////////////
// Function - Set initial conditions on all MAX7219 7 segment drivers         //
void Max7219_InitAll(){                                                       //
    LATB = 0b00000000;                                                        //
    SPI1_Write(SHUTDOWN);   SPI1_Write(ON);     // on                         //
    LATB = 0b00000111;                                                        //
    LATB = 0b00000000;                                                        //
    SPI1_Write(DECODE);     SPI1_Write(0xFF);   // decode all                 //
    LATB = 0b00000111;                                                        //
    LATB = 0b00000000;                                                        //
    SPI1_Write(BRIGHTNESS); SPI1_Write(0x0F);   // max                        //
    LATB = 0b00000111;                                                        //
    LATB = 0b00000000;                                                        //
    SPI1_Write(SCANLIMIT);  SPI1_Write(0x07);   // show all                   //
    LATB = 0b00000111;                                                        //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Clear one 7 segment display using display address 1-8           //
//            Bottom dusplay= 0. Middle = 1. Top = 2                          //
void Segment_Clear(char chip_select){                                         //
    char x = 0;                                                               //
    for(x=1;x<=8;x++){                                                        //
        LATB = ~(1<<chip_select);   // selected pin low, rest high            //
        SPI1_Write(x);                                                        //
        SPI1_Write(0xF);                                                      //
        LATB = 0b00000111;          // all chip selects high                  //
    }                                                                         //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Clear all 7 segment display CS0-CS2 using display address 1-8   //
void Segment_ClearAll(){                                                      //
    char x = 0;                                                               //
    for(x=1;x<=8;x++){                                                        //
        LATB = 0b00000000;          // selected pin low, rest high            //
        SPI1_Write(x);                                                        //
        SPI1_Write(0xF);                                                      //
        LATB = 0b00000111;          // all chip selects high                  //
    }                                                                         //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Show variables on 7 segment displays using SPI1 and CS=0        //
//            Normal Printout() descriptors %d %u %f with width and precision //
//            Decodes E,e,-,. as special cases. + signs not displayed         //
//            Requires all Printout() functions to be terminated with '\r'    //
void SPI1_Putc0(char ascii){                                                  //
    char     display = 0;               // set to display a character         //
    static char    x = 8;               // x is digit address, 8 is leftmost  //
    static  old_byte = 0;               // last byte already displayed        //
    char byte = ascii-48;               // convert ASCII to digit             //
        if(ascii=='+'){                 // test for '+' signs                 //
            display = 0;                // don't display                      //
        }                                                                     //
        if(ascii=='E'||ascii=='e'){     // test for 'e' or 'E'                //
            byte = 0x0B;                // E in MAX7219 decode                //
            display = 1;                // display 'E'                        //
        }                                                                     //
        if(ascii=='-'){                 // test for '-'                       //
            byte = 0x0A;                // - in MAX7219 decode                //
            display = 1;                // display '-'                        //
        }                                                                     //
        if(isdigit(ascii)){             // test for digits 0 to 9             //
            old_byte=byte;              // in case next character is '.'      //
            display = 1;                // display digits 0-9                 //
        }                                                                     //
        if(ascii=='.'){                 // test for a '.'                     //
            byte = old_byte|0x80;       // add decimal point 0x80 to old byte //
            x++;                        // move back 1 address to the left    //
            display = 1;                // display '.' with  previous digit   //
        }                                                                     //
        if(ascii=='\r'){                // test for termination '\r'          //
            x=8;                        // leftmost digit                     //
            old_byte=0;                                                       //
            display =0;                                                       //
        }                                                                     //
        // Write byte to address X if display has been set                    //
        if(display){                                                          //
            CS0 = 0;                    // active low                         //
            SPI1_Write(x);              // digit address 8=left, 1=right      //
            SPI1_Write(byte);           // byte to be displayed               //
            CS0 = 1;                    // deselect                           //
            x--;                        // move address to the right          //
            display = 0;                // clear the flag                     //
        }                                                                     //
    return;                                                                   //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Show variables on 7 segment displays using SPI1 and CS=1        //
//            Normal Printout() descriptors %d %u %f with width and precision //
//            Decodes E,e,-,. as special cases. + signs not displayed         //
//            Requires all Printout() functions to be terminated with '\r'    //
void SPI1_Putc1(char ascii){                                                  //
    char     display = 0;               // set to display a character         //
    static char    x = 8;               // x is digit address, 8 is leftmost  //
    static  old_byte = 0;               // last byte already displayed        //
    char byte = ascii-48;               // convert ASCII to digit             //
        if(ascii=='+'){                 // test for '+' signs                 //
            display = 0;                // don't display                      //
        }                                                                     //
        if(ascii=='E'||ascii=='e'){     // test for 'e' or 'E'                //
            byte = 0x0B;                // E in MAX7219 decode                //
            display = 1;                // display 'E'                        //
        }                                                                     //
        if(ascii=='-'){                 // test for '-'                       //
            byte = 0x0A;                // - in MAX7219 decode                //
            display = 1;                // display '-'                        //
        }                                                                     //
        if(isdigit(ascii)){             // test for digits 0 to 9             //
            old_byte=byte;              // in case next character is '.'      //
            display = 1;                // display digits 0-9                 //
        }                                                                     //
        if(ascii=='.'){                 // test for a '.'                     //
            byte = old_byte|0x80;       // add decimal point 0x80 to old byte //
            x++;                        // move back 1 address to the left    //
            display = 1;                // display '.' with  previous digit   //
        }                                                                     //
        if(ascii=='\r'){                // test for termination '\r'          //
            x=8;                        // leftmost digit                     //
            old_byte=0;                                                       //
            display =0;                                                       //
        }                                                                     //
        // Write byte to address X if display has been set                    //
        if(display){                                                          //
            CS1 = 0;                    // active low                         //
            SPI1_Write(x);              // digit address 8=left, 1=right      //
            SPI1_Write(byte);           // byte to be displayed               //
            CS1 = 1;                    // deselect                           //
            x--;                        // move address to the right          //
            display = 0;                // clear the flag                     //
        }                                                                     //
    return;                                                                   //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Show variables on 7 segment displays using SPI1 and CS=2        //
//            Normal Printout() descriptors %d %u %f with width and precision //
//            Decodes E,e,-,. as special cases. + signs not displayed         //
//            Requires all Printout() functions to be terminated with '\r'    //
void SPI1_Putc2(char ascii){                                                  //
    char     display = 0;               // set to display a character         //
    static char    x = 8;               // x is digit address, 8 is leftmost  //
    static  old_byte = 0;               // last byte already displayed        //
    char byte = ascii-48;               // convert ASCII to digit             //
        if(ascii=='+'){                 // test for '+' signs                 //
            display = 0;                // don't display                      //
        }                                                                     //
        if(ascii=='E'||ascii=='e'){     // test for 'e' or 'E'                //
            byte = 0x0B;                // E in MAX7219 decode                //
            display = 1;                // display 'E'                        //
        }                                                                     //
        if(ascii=='-'){                 // test for '-'                       //
            byte = 0x0A;                // - in MAX7219 decode                //
            display = 1;                // display '-'                        //
        }                                                                     //
        if(isdigit(ascii)){             // test for digits 0 to 9             //
            old_byte=byte;              // in case next character is '.'      //
            display = 1;                // display digits 0-9                 //
        }                                                                     //
        if(ascii=='.'){                 // test for a '.'                     //
            byte = old_byte|0x80;       // add decimal point 0x80 to old byte //
            x++;                        // move back 1 address to the left    //
            display = 1;                // display '.' with  previous digit   //
        }                                                                     //
        if(ascii=='\r'){                // test for termination '\r'          //
            x=8;                        // leftmost digit                     //
            old_byte=0;                                                       //
            display =0;                                                       //
        }                                                                     //
        // Write byte to address X if display has been set                    //
        if(display){                                                          //
            CS2 = 0;                    // active low                         //
            SPI1_Write(x);              // digit address 8=left, 1=right      //
            SPI1_Write(byte);           // byte to be displayed               //
            CS2 = 1;                    // deselect                           //
            x--;                        // move address to the right          //
            display = 0;                // clear the flag                     //
        }                                                                     //
    return;                                                                   //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function - Show demo on all displays                                       //
void Demo_Display(){                                                          //
    char x = 0;                                                               //
    // Write BILL LEGGE                                                       //
    CS2 = 0;SPI1_Write(8);SPI1_Write(8); CS2 = 1;   // B                      //
    CS2 = 0;SPI1_Write(7);SPI1_Write(1); CS2 = 1;   // I                      //
    CS2 = 0;SPI1_Write(6);SPI1_Write(13);CS2 = 1;   // L                      //
    CS2 = 0;SPI1_Write(5);SPI1_Write(13);CS2 = 1;   // L                      //
    CS1 = 0;SPI1_Write(8);SPI1_Write(13);CS1 = 1;   // L                      //
    CS1 = 0;SPI1_Write(7);SPI1_Write(11);CS1 = 1;   // E                      //
    CS1 = 0;SPI1_Write(6);SPI1_Write(6); CS1 = 1;   // 6                      //
    CS1 = 0;SPI1_Write(5);SPI1_Write(6); CS1 = 1;   // 6                      //
    CS1 = 0;SPI1_Write(4);SPI1_Write(11);CS1 = 1;   // E                      //
    delay_ms(1000);                                                           //
    Segment_ClearAll();                                                       //
    // Ripple segment displays, x must be <=8                                 //
    for(x=1;x<=8;x++){                                                        //
        CS0 = 0;SPI1_Write(x);SPI1_Write(x);CS0 = 1;    // position,character //
        CS1 = 0;SPI1_Write(x);SPI1_Write(x);CS1 = 1;    // position,character //
        CS2 = 0;SPI1_Write(x);SPI1_Write(x);CS2 = 1;    // position,character //
        delay_ms(50);                                                         //
    }                                                                         //
    delay_ms(500);                                                            //
    Segment_ClearAll();                                                       //
    for(x=8;x>=1;x--){                                                        //
        CS0 = 0;SPI1_Write(x);SPI1_Write(x);CS0 = 1;   // position,character  //
        CS1 = 0;SPI1_Write(x);SPI1_Write(x);CS1 = 1;   // position,character  //
        CS2 = 0;SPI1_Write(x);SPI1_Write(x);CS2 = 1;   // position,character  //
        delay_ms(50);                                                         //
    }                                                                         //
    delay_ms(5);                                                              //
    Segment_ClearAll();                                                       //
}                                                                             //
////////////////////////////////////////////////////////////////////////////////
And a test file .c

Code: Select all

////////////////////////////////////////////////////////////////////////////////
// Project:         Futurlec_Displays_Test                                    //
// File:            Futurlec_Displays_Test.c                                  //
// Function:        Display on 4 Futurlec 7 segment dusplays                  //
//                  Send test data to the Futurlec displays by RS232          //
//                  ... and SPI                                               //
// MCU:             PIC1846K22                                                //
// Board:           EasyPICv7                                                 //
// Power:           5 Volts                                                   //
// Frequency:       32kHz                                                     //
// Compiler:        mikroC PRO for PIC version 7.2.0                          //
// Programmer:      ICD3 or on-board                                          //
// Author:          WVL                                                       //
// Date:            10 Feb 2019                                               //
////////////////////////////////////////////////////////////////////////////////

void main() {
    char   my_string[] = "%u\r";
    char          x = 0;
    char          c = 48;               // ascii '0' test number
    unsigned int ui =  1;               // test number
    signed int   si = -12001;           // test number
    signed int   sj = -1;               // test number
    float        fa = 1.2345678;        // test number
    float        fb = -0.000087654321;  // test number
    float        fc = 987.654;          // test number
    float        fd = 12345678.0;       // test number
    // Ports and pins
    ANSELA = 0b00000000;    // 1=analog 0=digital
    ANSELB = 0b00000000;    // 1=analog 0=digital
    ANSELC = 0b00000000;    // 1=analog 0=digital
    ANSELD = 0b00000000;    // 1=analog 0=digital
    ANSELE = 0b00000000;    // 1=analog 0=digital
    WPUB   = 0b00000000;    // pull up 1=enabled 0=disabled
    TRISA  = 0b00000000;    // RA0 is looping LED, RA5 is CS
    TRISB  = 0b00000000;    //
    TRISC3_bit = 0;         // op for SCK1
    TRISC4_bit = 1;         // ip for SDI1
    TRISC5_bit = 0;         // op for SDO1
    LATA = 0;
    // Peripherals
    PMD1 = 0b00011111;        // disable all comparators
    // Use RC6/Tx1 RC7/Rx1 not RD6/Tx2 RD7/Rx2
    UART1_Init(9600);
    // Use RC3/SCK1 RC4/SDI1 RC5/SDO1
    SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64,_SPI_DATA_SAMPLE_MIDDLE,_SPI_CLK_IDLE_LOW,_SPI_LOW_2_HIGH);
    delay_ms(5);
    UART1_Write_Text("EasyPICv7_Futurlec_Displays_Test running at 8MHz\r\n");
    
    while(1){
        // By RS232 on UART1 RC6 and RC7
        Printout(UART1_Write,"SHOW0%u\r",ui);     // 1++
        delay_ms(1000);
        Printout(UART1_Write,"SHOW1%d\r",si);     // -12001
        delay_ms(1000);
        Printout(UART1_Write,"SHOW2%d\r",sj);     // -1
        delay_ms(1000);
        Printout(UART1_Write,"SHOW0%f\r",fa);     // 1.2345678
        delay_ms(1000);
        Printout(UART1_Write,"SHOW1%.2e\r",fb);   // -0.000087654321
        delay_ms(1000);
        Printout(UART1_Write,"SHOW2%7.3f\r",fc);  // 987.654
        delay_ms(1000);
        Printout(UART1_Write,"SHOW0%.3e\r",fd);   // 1234567.1
        delay_ms(1000);
        // By SPI1 on RC3 and RC4
        Printout(SPI1_Write,"SHOW0%u\r",ui);     // 1++
        delay_ms(1000);
        Printout(SPI1_Write,"SHOW1%d\r",si);     // -12001
        delay_ms(1000);
        Printout(SPI1_Write,"SHOW2%d\r",sj);     // -1
        delay_ms(1000);
        Printout(SPI1_Write,"SHOW0%f\r",fa);     // 1.2345678
        delay_ms(1000);
        Printout(SPI1_Write,"SHOW1%.2e\r",fb);   // -0.000087654321
        delay_ms(1000);
        Printout(SPI1_Write,"SHOW2%7.3f\r",fc);  // 987.654
        delay_ms(1000);
        Printout(SPI1_Write,"SHOW0%.3e\r",fd);   // 1234567.1
        delay_ms(1000);
        // Housekeeping
        delay_ms(50);
        LATA0_bit = ~LATA0_bit;
    }
}
Good luck from Bill Legge in Australia
Attachments
Futurlec Display MCU Only.pdf
(138.69 KiB) Downloaded 139 times
MCU and Displays.pdf
(174.24 KiB) Downloaded 147 times

Post Reply

Return to “User Projects”