hi there,
first post from me here, but I have visited the forum for some time now.
I try to drive a 3-color matrix from sparkfun with 4 shift register (74hc595) and already found much great code which helped a lot to get PWM running and to speed things up (special thanks goes to madworm and marklar
).
now I want to ask you if you could look through the code for any further (speed) improvement. maybe you find even an error although the code works for me.
//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 10;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 13;
////Pin connected to Data in (DS) of 74HC595
const int dataPin = 11;
#define LATCH_LOW PORTB &= ~(1 << PORTB2) // PB2 = Arduino Diecimila pin 10
#define LATCH_HIGH PORTB |= (1 << PORTB2) // PB2 = Arduino Diecimila pin 10
#define TIMER1_MAX 0xFFFF // 16 bit counter
#define TIMER1_CNT 0x0022 // 32 levels --> 0x0022
#define MAX_COLOR 32
byte r[8][8];
byte g[8][8];
byte b[8][8];
int row=0;
byte curRow=B11111110;
byte temp_red,temp_green,temp_blue;
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
digitalWrite(latchPin,LOW);
digitalWrite(dataPin,LOW);
digitalWrite(clockPin,LOW);
setupSPI();
setup_timer1_ovf();
for(int y=0;y<8;y++){
setPixel(0,y,y,0,0);
setPixel(1,y,0,y,0);
setPixel(2,y,0,0,y);
}
}
void loop() {
}
ISR(TIMER1_OVF_vect) {
TCNT1 = TIMER1_MAX - TIMER1_CNT;
for(int pwm=0;pwm<MAX_COLOR;pwm++){
temp_red= 0;
temp_green=0;
temp_blue= 0;
for(int y=0;y<8;y++){
if(r[row][y]>pwm){
temp_red |= (1<<y);
}
if(g[row][y]>pwm){
temp_green |= (1<<y);
}
if(b[row][y]>pwm){
temp_blue |= (1<<y);
}
}
LATCH_LOW;
spi_transfer(temp_red);
spi_transfer(temp_blue);
spi_transfer(temp_green);
spi_transfer(curRow);
LATCH_HIGH;
}
row++;
if(row>7) row=0;
curRow=(curRow << 1) | (curRow >> 7); //rotate curRow left by one: B11111110,B11111101,B11111011,...
}
void setPixel(int x,int y,int red,int green,int blue){
r[x][y]=red;
g[x][y]=green;
b[x][y]=blue;
}
//////////////////////////
void setupSPI(){
byte clr;
SPCR |= ( (1<<SPE) | (1<<MSTR) ); // enable SPI as master
//SPCR |= ( (1<<SPR1) | (1<<SPR0) ); // set prescaler bits
SPCR &= ~( (1<<SPR1) | (1<<SPR0) ); // clear prescaler bits
clr=SPSR; // clear SPI status reg
clr=SPDR; // clear SPI data reg
SPSR |= (1<<SPI2X); // set prescaler bits
//SPSR &= ~(1<<SPI2X); // clear prescaler bits
delay(10);
}
byte spi_transfer(byte data)
{
SPDR = data; // Start the transmission
loop_until_bit_is_set(SPSR, SPIF);
return SPDR; // return the received byte, we don't need that
}
void setup_timer1_ovf(void) {
// Arduino runs at 16 Mhz...
// Timer1 (16bit) Settings:
// prescaler (frequency divider) values: CS12 CS11 CS10
// 0 0 0 stopped
// 0 0 1 /1
// 0 1 0 /8
// 0 1 1 /64
// 1 0 0 /256
// 1 0 1 /1024
// 1 1 0 external clock on T1 pin, falling edge
// 1 1 1 external clock on T1 pin, rising edge
//
TCCR1B &= ~ ( (1<<CS11) );
TCCR1B |= ( (1<<CS12) | (1<<CS10) );
//normal mode
TCCR1B &= ~ ( (1<<WGM13) | (1<<WGM12) );
TCCR1A &= ~ ( (1<<WGM11) | (1<<WGM10) );
//Timer1 Overflow Interrupt Enable
TIMSK1 |= (1<<TOIE1);
TCNT1 = TIMER1_MAX - TIMER1_CNT;
}
thanks in advance, any comment is appreciated
Nicknack