Re: Multiplexing - how to speed up
- From: "Pubudu" <pubuducg@xxxxxxxxx>
- Date: 25 Jun 2006 17:12:24 -0700
roxlu wrote:
Don Lancaster wrote:
roxlu wrote:
Hi all,http://www.tinaja.com/glib/muse152.pdf
I'm working on a project where I need to multiplex a matrix of 512 LEDs
using a pic16f628.
Currently I'm testing with 5 cascaded shift registers (serial in,
parallel out). One shift register is used to control which LEDs must be
on, in the current column. The other 4 are used for the columns.
Here is a design of the circuit as example. I left out some parts, but
I hope you'll get an idea of the project:
http://imagebin.org/5459
After adding the 5th shift register the image started flickering. I've
talked to some people telling me its definitely possible to control at
least 40 columns. How can I achieve this? Are there any "tricks" to
speeds this up?
Here is my code for the pic16f628:
<code>
// Define the shift registers pins
#define SHIFT_DATA PORTA.F1
#define SHIFT_CLOCK PORTA.F0
#define SHIFT_OE PORTA.F2 // Output enable.
// The a_matrix holds the row values for the 8 columns
// in the 8x8 matrix. The keys of the matrix 0-7 are
// the columns, the corresponding values the row flags.
char a_matrix[8] = {
0b01010101
,0b01010101
,0b00100000
,0b00010000
,0b00001000
,0b00000100
,0b00000010
,0b00000001
};
char a_columns[32] = {
0b10000000
,0b01000000
,0b00100000
,0b00010000
,0b00001000
,0b00000100
,0b00000010
,0b00000001 // 8
,0b00000010
,0b00000100
,0b00001000
,0b00010000
,0b00100000
,0b01000000
,0b10000000
,0b00000001 // 16
,0b00000010
,0b00000100
,0b00001000
,0b00010000
,0b00100000
,0b01000000
,0b10000000
,0b00000001 // 24
,0b00000010
,0b00000100
,0b00001000
,0b00010000
,0b00100000
,0b01000000
,0b10000000
,0b00000001 // 32
};
char c_in = 0; // Used for serial input.
int f_state = 0; // Used to update the matrix. (update_matrix())
int c_col_in = 0; // update_matrix()
int c_row_in = 0; // update_matrix();
int c_called = 0; // update_matrix(), counting the number of times
method is called
int num_cols = 32;
int i = 0;
int j = 0;
int i_col = 0;
char c_column; // main()
// Shift one byte into the shift register.
void shift_byte(char pByte)
{
int i;
for (i = 0; i < 8; i++)
{
// Get bit (1 or 0) at position i of pByte.
SHIFT_DATA = (pByte >> i) & 1;
// Make clock pin high and low again, so data is shifted into the
registers.
SHIFT_CLOCK = 1;
SHIFT_CLOCK = 0;
}
}
void shift_bit(int fPin)
{
SHIFT_DATA = fPin; // 0 or 1
SHIFT_CLOCK = 1;
SHIFT_CLOCK = 0;
}
void put_col_on(int iCol)
{
// First we shift out several '0' to fill all the registers
j = 16 - iCol;
for (i_col = 0; i_col < j; i_col++)
{
shift_bit(0);
}
// The first bit is for the column which must be turned on.
shift_bit(1);
// All the other columns must be turned off.
for (i_col = 0; i_col < (iCol - 1); i_col++)
{
shift_bit(0);
}
}
// Make all the columns low.
void matrix_off()
{
SHIFT_OE = 0;
shift_byte(0x00);
shift_byte(0x00);
shift_byte(0x00);
shift_byte(0x00);
shift_byte(0x00);
SHIFT_OE = 1;
}
// This function checks if there is data available
// on the serial port. And if so, it will update the
// matrix table. The data which is received using rs-232
// is in the format (2 bytes):
// [column][row_flags]
void update_matrix()
{
// Read data.
if (usart_data_ready() == 1)
{
c_in = usart_read();
if (f_state == 0)
{
c_col_in = c_in;
f_state = 1;
}
else if (f_state == 1)
{
c_row_in = c_in; // not really needed, we can use c_in
f_state = 0;
if (c_col_in <= 7)
{
a_matrix[c_col_in] = c_row_in;
c_called = 0;
}
else
{
// usart_write('!');
}
}
}
// We didn't receive anything, reset counter and state.
if (c_called >= 255)
{
c_called = 0;
f_state = 0;
}
c_called++;
}
void main()
{
TRISA = 0x00; // All ports on PORTA are outputs.
PORTA = 0; // All outputs low
// Initialize USART (rs-232)
usart_init(57600);
// Main loop
while(1)
{
update_matrix();
for (i = 0; i < num_cols; i++)
{
matrix_off();
SHIFT_OE = 0;
put_col_on(i);
shift_byte(~a_columns[i]);
SHIFT_OE = 1;
}
}
}
</code>
--
Many thanks,
Don Lancaster voice phone: (928)428-4073
Synergetics 3860 West First Street Box 809 Thatcher, AZ 85552
rss: http://www.tinaja.com/whtnu.xml email: don@xxxxxxxxxx
Please visit my GURU's LAIR web site at http://www.tinaja.com
Thanx for the article! I think that the code for the uC will be a lot
more complicated which
will probably make the display even slower which causes flickering as
well. Though I'm not sure; have you tried this? And would this work
using shift reigsters?
Greetings
Hi,
Flickerig happens because your update rate is becoming slower. For a
naked eye it is required to have 25 frames ( as I remember ) or more
to keep smooth images on the screen. For me still I wonder how this
even works for 4 registers.
Is this for text display or graphics with animations ?.
First scanning (selecting columns) should not happen when row values
are written. those operations have to synchronised well. This is how
it should happen.
1. Load the row values to row register.
make sure register output is not enabled. i.e. value is written to the
internal buffer but not to the output pins of that register. This
should be a parallel buffer not a shift register. Shift registers also
will work but it need more time to load 8 bit values which might slower
the operation.
2. Now select the right column and enabled the row register at the
same time. (assume first column is selected)
Row values should be displayed now on the first column. This is the
tricky part. You should activate both functions at the same time. A
time difference will lead to flickering specially when there are more
columns.
4. Now Load the right row values for the second column. During this
operation output should be disabled. ( I mean the values are written to
the internal register but not to the output .Output should still
contain the previous values. There are buffers available for this.
5. Again select the output register and the second column at the
same time.
Now right row values should appear at the second column.
Repeat this procedure. You should not see any flickering unless the
scanning speed is not enough. I did this and worked very fine.
The most important thing is that the time taken for column selection
should kept at a constant rate. change in this time difference also
will lead to flickering. This is crutial when u try to load the row
register. Make should you scan the entire matrix atleast (beginning to
end) 25 times per second. Higher the better.
I think this might help you,
Pubudu.
.
- Follow-Ups:
- Re: Multiplexing - how to speed up
- From: roxlu
- Re: Multiplexing - how to speed up
- References:
- Multiplexing - how to speed up
- From: roxlu
- Re: Multiplexing - how to speed up
- From: Don Lancaster
- Re: Multiplexing - how to speed up
- From: roxlu
- Multiplexing - how to speed up
- Prev by Date: Re: Cascade two voltage regs
- Next by Date: Re: Can anyone help me?
- Previous by thread: Re: Multiplexing - how to speed up
- Next by thread: Re: Multiplexing - how to speed up
- Index(es):
Relevant Pages
|