开心果 发表于 2013-10-10 08:40:12

8*8 RGB 74ls595 点阵

    在舍友提议下,做了个。8*8RGB点阵。功能有单色、彩色、各种图形显示,循环显示数字0至9、左右移动;整体刷屏。目前屏大小只有8*8,还不支持显示汉字,不过驱动板留出了级联接口,慢慢完善。

参考:http://blog.spitzenpfeil.org/wordpress/wp-content/uploads/2008/10/matrix_code.pde

附上原理图:

附上代码:
只需要连接三根线,74595的SCK、RCK、SER(需要级联,前一个595的QH连接到下一个的SER)

#define __spi_clock 13   // SCK
#define __spi_latch 10   //RCK
#define __spi_data 11    //SER+

#define __display_enable 9
#define __rows 8
#define __max_row __rows-1
#define __leds_per_row 8
#define __max_led __leds_per_row-1
#define __brightness_levels 32 // 0...15 above 28 is bad for ISR ( move to timer1, lower irq freq ! )
#define __max_brightness __brightness_levels-1
#define __fade_delay 4

#define __TIMER1_MAX 0xFFFF // 16 bit CTR
#define __TIMER1_CNT 0x0130 // 32 levels --> 0x0130; 38 --> 0x0157 (flicker)
#include <avr/interrupt.h>   
#include <avr/io.h>
#include <stdint.h>

byte brightness_red;
byte brightness_green;
byte brightness_blue;

ISR(TIMER1_OVF_vect) {
//TCNT2 = __TIMER2_MAX - __TIMER2_CNT; // precharge TIMER2 to maximize ISR time --> max led brightness
TCNT1 = __TIMER1_MAX - __TIMER1_CNT;
byte cycle;

digitalWrite(__display_enable,LOW); // enable display inside ISR

for(cycle = 0; cycle < __max_brightness; cycle++) {
    byte led;
    byte row = B00000000;    // row: current source. on when (1)
    byte red;    // current sinker when on (0)
    byte green;// current sinker when on (0)
    byte blue;   // current sinker when on (0)

    for(row = 0; row <= __max_row; row++) {
      
      red = B11111111;    // off
      green = B11111111;// off
      blue = B11111111;   // off
      
   for(led = 0; led <= __max_led; led++) {
      if(cycle < brightness_red) {
          red &= ~(1<<led);
      }
      if(cycle < brightness_green) {
          green &= ~(1<<led);
      }
      if(cycle < brightness_blue) {
          blue &= ~(1<<led);
      }
      }
      digitalWrite(__spi_latch,LOW);
      spi_transfer(blue);
      spi_transfer(green);
      spi_transfer(red);
      spi_transfer(B00000001<<row);
      digitalWrite(__spi_latch,HIGH);
      digitalWrite(__spi_latch,LOW);
    }
}

digitalWrite(__display_enable,HIGH);    // disable display outside ISR
}

int data[]={0x00,0x36,0x7f,0x7f,0x3e,0x1c,0x08,0x00,//xin
         0x00,0x06,0x69,0x90,0x00,0x42,0x24,0x18,/*"xiaonian",0*/
0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x38,/*"1",0*/
0x00,0x18,0x24,0x04,0x08,0x10,0x20,0x3C,/*"2",1*/
0x00,0x18,0x24,0x04,0x18,0x04,0x24,0x18,/*"3",2*/
0x00,0x08,0x18,0x18,0x28,0x28,0x3C,0x08,/*"4",3*/
0x00,0x3C,0x20,0x20,0x38,0x04,0x04,0x38,/*"5",4*/
0x00,0x18,0x24,0x20,0x38,0x24,0x24,0x18,/*"6",5*/
0x00,0x3C,0x24,0x04,0x08,0x10,0x10,0x10,/*"7",6*/
0x00,0x18,0x24,0x24,0x18,0x24,0x24,0x18,/*"8",7*/
0x00,0x18,0x24,0x24,0x1C,0x04,0x24,0x18,/*"9",8*/
0x00,0x18,0x24,0x24,0x24,0x24,0x24,0x18,/*"0",9*/
         };
void setup(void) {
//Serial.begin(9600);
randomSeed(555);
byte ctr1;
byte ctr2;

pinMode(__spi_clock,OUTPUT);
pinMode(__spi_latch,OUTPUT);
pinMode(__spi_data,OUTPUT);
pinMode(__display_enable,OUTPUT);
digitalWrite(__spi_latch,LOW);
digitalWrite(__spi_data,LOW);
digitalWrite(__spi_clock,LOW);
   
setup_hardware_spi();
delay(10);
set_matrix_rgb(0,0,0);
setup_timer1_ovf();
}

void loop(void) {
   int ctr;

for(ctr=0; ctr < 2; ctr++) {
    fader_hue();//整体刷屏,颜色随设定值改变
}
for(ctr=0; ctr < 1; ctr++) {
    matrix_test();//从上往下刷屏,颜色随设定值改变
}

for(ctr=0; ctr < 4; ctr++) {
    matrix_heart_2();    //彩色
   // matrix_heart(100); //单色
}
}

byte spi_transfer(byte data)
{
SPDR = data;                  // Start the transmission
while (!(SPSR & (1<<SPIF)))   // Wait the end of the transmission
{
};
return SPDR;                  // return the received byte, we don't need that
}


void set_led_red(byte row, byte led, byte red) {
brightness_red = red;
}

void set_led_green(byte row, byte led, byte green) {
brightness_green = green;
}

void set_led_blue(byte row, byte led, byte blue) {
brightness_blue = blue;
}

void set_led_rgb(byte row, byte led, byte red, byte green, byte blue) {
set_led_red(row,led,red);
set_led_green(row,led,green);
set_led_blue(row,led,blue);
}


void set_matrix_rgb(byte red, byte green, byte blue) {
byte ctr1;
byte ctr2;
for(ctr2 = 0; ctr2 <= __max_row; ctr2++) {
    for(ctr1 = 0; ctr1 <= __max_led; ctr1++) {
      set_led_rgb(ctr2,ctr1,red,green,blue);
    }
}
}


void set_led_hue(byte row, byte led, int hue) {

// see wikipeda: HSV
float S=100.0,V=100.0,s=S/100.0,v=V/100.0,h_i,f,p,q,t,R,G,B;
   
    hue = hue%360;
    h_i = hue/60;            
    f = (float)(hue)/60.0 - h_i;
    p = v*(1-s);
    q = v*(1-s*f);
    t = v*(1-s*(1-f));
   
    if      ( h_i == 0 ) {
      R = v;
      G = t;
      B = p;
    }
    else if ( h_i == 1 ) {
      R = q;
      G = v;
      B = p;
    }
    else if ( h_i == 2 ) {
      R = p;
      G = v;
      B = t;
    }
    else if ( h_i == 3 ) {
      R = p;
      G = q;
      B = v;
    }
    else if ( h_i == 4 ) {
      R = t;
      G = p;
      B = v;
    }
    else                   {
      R = v;
      G = p;
      B = q;
    }

    set_led_rgb(row,led,byte(R*(float)(__max_brightness)),byte(G*(float)(__max_brightness)),byte(B*(float)(__max_brightness)));
   
    /*
    Serial.println(byte(R*(float)(__max_brightness)),DEC);
    Serial.println(byte(G*(float)(__max_brightness)),DEC);
    Serial.println(byte(B*(float)(__max_brightness)),DEC);
    Serial.println("---");
    */   
}

void set_row_byte_hue(byte row, byte data_byte, int hue) {
byte led;
for(led = 0; led <= __max_led; led++) {
    if( (data_byte>>led)&(B00000001) ) {
      set_led_hue(row,led,hue);
    }
    else {
      set_led_rgb(row,led,0,0,0);
    }
}
}

void set_matrix_hue(int hue) {
byte ctr1;
byte ctr2;
for(ctr2 = 0; ctr2 <= __max_row; ctr2++) {
    for(ctr1 = 0; ctr1 <= __max_led; ctr1++) {
      set_led_hue(ctr2,ctr1,hue);
    }
}
}

void set_column_hue(byte column, int hue) {
byte ctr1;
for(ctr1 = 0; ctr1 <= __max_row; ctr1++) {
      set_led_hue(ctr1,column,hue);
}
}


void setup_hardware_spi(void) {
byte clr;

SPCR |= ( (1<<SPE) | (1<<MSTR) ); // enable SPI as master
//SPCR |= ( (1<<SPR1) ); // 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
}


void setup_timer1_ovf(void) {

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;
// enable all interrupts
sei();
}
/*---------------------------单色图形--------------------------------------------*/
//通过改变 hue的值,来改变颜色
void matrix_heart(int hue) {
int k,i;
for(k = 0; k < 600; k=k+48) {
for(int j=0;j<8;j++)
      {
      set_row_byte_hue(j,data,hue);
      delay(20*__fade_delay);
      if(j>=7)
      i+=8;
      else if(i>=96)
      i=0;
      }
}
}
/*---------------------------彩色图形--------------------------------------------*/
//通过改变 hue=hue++*里面*的值,来改变颜色变换速率
void matrix_heart_2(void) {
int hue,i=0;
for(hue = 0; hue < 600; hue=hue+48) {
      for(int j=0;j<8;j++)
      {
      set_row_byte_hue(j,data,hue);
      delay(20*__fade_delay);
      if(j>=7)
      i+=8;
      else if(i>=96)
      i=0;
      }
}
}

/*---------------------------满屏切换不同颜色--------------------------------------------*/
//通过改变 ctr1=ctr1+*里面*的值,来改变颜色变换速率
void fader_hue(void) {
int ctr1;
byte row;
byte led;

for(ctr1 = 0; ctr1 < 360; ctr1=ctr1+3) {
    set_matrix_hue((float)(ctr1));
    delay(__fade_delay);
}
}
/*---------------------------从上往下单行切换不同颜色--------------------------------------------*/
//通过改变 hue=hue++*里面*的值,来改变颜色变换速率
void matrix_test(void) {
byte ctr1;
byte ctr2;
int hue;

for(hue = 0; hue < 360; hue=hue+32) {
    for(ctr2 = 0; ctr2 <= __max_row; ctr2++) {
      for(ctr1 = 0; ctr1 <= __max_led; ctr1++) {
      set_led_hue(ctr2,ctr1,hue);
      delay(5);
      }
    }
}
}

视频:http://v.youku.com/v_show/id_XNjE1NDU0OTgw.html

heiketiguo 发表于 2013-10-10 11:42:58

不错不错!我也正在做这个!不过,我是照抄老外的

爱因你而生 发表于 2013-10-10 20:51:50

我的是淘宝现成的 55全彩的模块

开心果 发表于 2013-10-11 20:10:56

heiketiguo 发表于 2013-10-10 11:42 static/image/common/back.gif
不错不错!我也正在做这个!不过,我是照抄老外的

老外这个给力,我也在改进中。。。

亦已即 发表于 2015-10-29 13:23:35

#define __display_enable 9这个脚连到哪里?
页: [1]
查看完整版本: 8*8 RGB 74ls595 点阵