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
不错不错!我也正在做这个!不过,我是照抄老外的 我的是淘宝现成的 55全彩的模块 heiketiguo 发表于 2013-10-10 11:42 static/image/common/back.gif
不错不错!我也正在做这个!不过,我是照抄老外的
老外这个给力,我也在改进中。。。 #define __display_enable 9这个脚连到哪里?
页:
[1]