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

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

CCS does not monitor this forum on a regular basis.

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

4x5 LED Matrix with 8bit shift registers PCH/PIC18F26K22

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
zzeroo



Joined: 17 Jun 2013
Posts: 18

View user's profile Send private message

4x5 LED Matrix with 8bit shift registers PCH/PIC18F26K22
PostPosted: Tue Jun 24, 2014 3:57 am     Reply with quote

Hello,

I'm looking for ideas for a fitting data model for the following problem.

I have a 4 colum, 5 row led matrix. They are connected via three 8bit 74HCT594 shift registers. The last 4 ports of the last shift register are not connected.
The first 5 bit are the first row of my LED matrix, the next 5bit are the next row and so on.

A additional problem comes at that. The hardware design does not allow me to clear the memory of the shift and the storage register.
The required pins are not connected to the MCU.

This means that to keep track of the current LED status I have to use a 24bit buffer in memory. And on each update I must shift in the whole 24bit (20 for each LED one + 4 bit not used) and latch them out.

What type of data structure should I use. My first experiment with a struct like the following results in an
Quote:
Error#35 Number of bits is out of range


Code:

struct LEDMap {
    unsigned char row1 :5;
    unsigned char row2 :5;
    unsigned char row3 :5;
    unsigned char row4 :5;
    unsigned char notUsed :4;
};


I want later to set some LED with a function like
Code:
void LED(int row, int column, char color);


Update:
the target MCU is a PIC18F26K22 and my
CCS Version=5.010
Compiler=PCH


Last edited by zzeroo on Tue Jun 24, 2014 5:14 am; edited 2 times in total
zzeroo



Joined: 17 Jun 2013
Posts: 18

View user's profile Send private message

Re: 4x5 LED Matrix with 8bit shift registers
PostPosted: Tue Jun 24, 2014 4:55 am     Reply with quote

Here is a gcc version how I think it could work. But the 24 bit datatype doesn't fit in my PCH

Code:
#include <stdio.h>

struct LEDBuffer {
  int bits :24;
};

void LED(int row, int column, struct LEDBuffer *buffer) {
  int num = ( ( row-1 ) * 5 ) + (column-1);

  buffer->bits |= 1 << num;
}

// Here the shift_register is feeded but for demonstration I print it out
void send_buffer(struct LEDBuffer *buffer) {
  int i;
  int data = buffer->bits;

  for(i=0; i<24; i++) {
    if(data & 0x01)
      printf("%d", 1);
    else
      printf("%d", 0);

    data >>= 1;
  }
  puts("");
}

int main(void) {
  struct LEDBuffer buffer = {0};

  send_buffer(&buffer);

  LED(1,1,&buffer);
  LED(1,2,&buffer);
  LED(1,3,&buffer);
  LED(1,4,&buffer);
  LED(1,5,&buffer);

  LED(4,1,&buffer);
  LED(4,2,&buffer);
  LED(4,3,&buffer);
  LED(4,4,&buffer);
  LED(4,5,&buffer);

  send_buffer(&buffer);

  return 0;
}
temtronic



Joined: 01 Jul 2010
Posts: 9219
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jun 24, 2014 5:07 am     Reply with quote

Can you please supply a good link to the datasheet for the 74954 shift registers you're using? Google didn't find anything !

tks
jay
zzeroo



Joined: 17 Jun 2013
Posts: 18

View user's profile Send private message

PostPosted: Tue Jun 24, 2014 5:14 am     Reply with quote

temtronic wrote:
Can you please supply a good link to the datasheet for the 74954 shift registers you're using? Google didn't find anything !

tks
jay


http://www.nxp.com/documents/data_sheet/74HC_HCT594.pdf

Sorry it a 74HCT594. But the shift register is not the problem Smile
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Tue Jun 24, 2014 5:38 am     Reply with quote

I assume you have a typo, please confirm your shift register is a 74594.
I am confused by you calling your display a 4*5 matrix.
It seems your LEDs are wired as a 20*1 linear network.

Using the CCS supplied driver you simply store a copy of your LED status in a 3 byte array.

Mike
zzeroo



Joined: 17 Jun 2013
Posts: 18

View user's profile Send private message

PostPosted: Tue Jun 24, 2014 6:01 am     Reply with quote

Mike Walne wrote:
I assume you have a typo, please confirm your shift register is a 74594.
I am confused by you calling your display a 4*5 matrix.
It seems your LEDs are wired as a 20*1 linear network.

Using the CCS supplied driver you simply store a copy of your LED status in a 3 byte array.

Mike


Yes all true. And as you can see from my questions, I am not a professional embedded C programmer.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

Re: 4x5 LED Matrix with 8bit shift registers
PostPosted: Tue Jun 24, 2014 6:45 am     Reply with quote

zzeroo wrote:
But the 24 bit datatype doesn't fit in my PCH

Code:

struct LEDBuffer {
  int bits :24;
};



No, it won't. Ints are eight bit by default (16 bits with PCD). This code is probably assuming an int is 32, e.g. a PC or an ARM. In any case CCS C doesn't like bit fields that cross byte boundaries. So even if you declared it as an int32 it wouldn't work.

A better way to do this would be to forget the bit field and treat it as a simple 32 bit integer, and use bit_set(), bit_clear() and bit_test() which are much more efficient, i.e. faster, than the bit shifts in the original code.
zzeroo



Joined: 17 Jun 2013
Posts: 18

View user's profile Send private message

PostPosted: Tue Jun 24, 2014 7:27 am     Reply with quote

Thank you all. This is my first solution. What do you think about?

Code:
// Device header
#include <18F26K22.h>

#FUSES NOWDT                    //No Watch Dog Timer
#use delay(clock=11052000,crystal=11052000)

#define DATA_IN PIN_A5
#define CLOCK PIN_A4
#define LATCH PIN_A3


// This memory portion stores the state of each LED
struct LEDBuffer {
    unsigned long long bits;
};


// Set all needed PIN's low. For a clean start.
void init_shift_registers() {
    output_low(DATA_IN);
    output_low(CLOCK);
    output_low(LATCH);
}

// This function latch out the shift register
void latch_out(){
    output_high(LATCH);
    output_low(LATCH);
}

// "Enable" one LED in buffer memory
void LED(int row, int column, struct LEDBuffer *buffer) {
    long long num = ( ( row-1 ) * 5 ) + ( column-1 );

    bit_set(buffer->bits, num);
}

// Clock in the buffer memory bit for bit. And transfer shift register data to
// storage register and enable the outputs, (latch out).
void send_buffer(struct LEDBuffer *buffer) {
    int i;
    long long data = buffer->bits << 4; // This four bit shift is needed because
                                        // the first 4 bits are not connected on my hardware

    for(i=0; i<24; i++) {
        if( data & 0x01) {
            output_high(DATA_IN);
        } else {
            output_low(DATA_IN);
        }

        output_high(CLOCK);     // Positive clock pulse
        output_low(CLOCK);

        data >>= 1;             // Get next bit in MSB position
    }

    latch_out();
}

void main(void) {
    init_shift_registers();

    // Initialize the LEDBuffer and set all bits to zero
    // This structure represents all shift registers memory
    struct LEDBuffer buffer = {0};

    LED(1,4,&buffer);
    LED(2,3,&buffer);
    LED(3,2,&buffer);
    LED(4,2,&buffer);

    send_buffer(&buffer);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19484

View user's profile Send private message

PostPosted: Tue Jun 24, 2014 9:05 am     Reply with quote

I think you are trying to make things more complex than they need to be.
You are 'hooked' on making the data structure in the PIC have some resemblance to the matrix, when it doesn't need/want to have this.
All that matters is that your 'clock out' function sends the right bits.

So simply have an array of four bytes.
Have the low five bits of each one represent one line of the LED.

Then have your send function, simply loop through the five low bits of each of these in turn, sending these, then send the four dummy bits, by just issuing clocks.

You don't need to ever store the extra dummy bits, or worry that the blocks of bits in the PIC have gaps between them.

So something like (totally theoretical)....:
Code:

char lines[4];
#define PULSE_CLOCK output_high(CLOCK);delay_cycles(1);output_low(CLOCK)

void send_lines()
{
    int8 line_no;
    int8 mask;
    int8 ctr;
    for (line_no=0;line_no<4;line_no++);
    {
         mask=1;
         for (ctr=0;ctr<5;ctr++)
         {
             if ((mask & lines[line_no]!=0)
                 output_high(DATA_BIT);
             else
                 output_low(DATA_BIT);
             PULSE_CLOCK;
             mask*=2;
         }
    }
    for (ctr=0;ctr<4;ctr++)
    {  //output four extra dummy bits
         PULSE_CLOCK;
    }
}


Then if you put 1 into each of the four 'lines', the first LED gets lit in each line, 2, the next one etc..

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

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


Powered by phpBB © 2001, 2005 phpBB Group