一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
楼主: songta00728
收起左侧

<处女贴>初次玩LED点阵屏,32X160双基色3.7mm点阵屏

  [复制链接]
发表于 2012-4-4 01:20 | 显示全部楼层
希望多多分享一下
发表于 2012-4-4 11:02 | 显示全部楼层
啥时候公布下源码最好了
 楼主| 发表于 2012-4-5 10:58 | 显示全部楼层
话说我也有个双色的不找到怎么驱动
zhtj521 发表于 2012-4-2 14:18 https://www.yleee.com.cn/images/common/back.gif



    那你可以拍几张屏的图片上来,大家帮你看看怎么驱动嘛~
 楼主| 发表于 2012-4-5 11:01 | 显示全部楼层
啥时候公布下源码最好了
bqtx122 发表于 2012-4-4 11:02 https://www.yleee.com.cn/images/common/back.gif


我的单片机用的是AVR的ATMEGA644P型号,程序是用ICCAVR写的,现在还在改进中。。。。。稍后完成了一定会上传的~
 楼主| 发表于 2012-4-5 11:06 | 显示全部楼层
希望多多分享一下
tdwx 发表于 2012-4-4 01:20 https://www.yleee.com.cn/images/common/back.gif



    稍后会将这个屏的原理图整理贴出来,供大家参考学习吧,源代码也会贴出来~
 楼主| 发表于 2012-4-5 16:54 | 显示全部楼层
现在上传自已还原的这个屏的原理图,欢迎拍砖~

32X80.pdf (274.95 KB, 下载次数: 34, 售价: 1 人民币)

因为屏的上半部分和下半部分原理完全一样,所以仅仅画出了16X80的点阵屏的原理图,输入端口245处有两个类似排阻的元器件没有焊接,我在PDF中有圈住,因为不知道是什么元器件就用排阻代替了,但还是感觉不太对,还请了解的朋友指点一二。
发表于 2012-4-14 15:29 | 显示全部楼层
不错,把程序贴上来哟,对初学者也是一种帮助。
 楼主| 发表于 2012-4-17 09:33 | 显示全部楼层
本帖最后由 songta00728 于 2012-4-17 10:10 编辑

程序是采用状态机的思想编写的,这样12M晶振跑32X160的点阵就不会有闪烁感,理论上计算了一下,再增加一块32X80点阵屏也是没有问题的.这是随手编的程序,没来的急进行整理,只供参考吧,程序是可以运行的。开发环境ICCAVR.
#include<iom644v.h>

//Fuse Bit
//Low bit : DE; High bit: D9; Extended bit : FD
//外部晶振8-16M,掉电检测电压2.7V,不分频.

//typedef data model
typedef     signed char  i8;
typedef   unsigned char  u8;
typedef      signed int  i16;
typedef    unsigned int  u16;
typedef     signed long  i32;
typedef   unsigned long  u32;

// define use IO
#define A       (PD7)
#define B       (PD6)
#define C       (PD5)
#define D       (PD4)
#define RCK     (PD3)
#define SCK     (PD2)
#define OE      (PD1)

#define G1DATA   (PC6)
#define R1DATA   (PC5)
#define G2DATA  (PC0)
#define R2DATA  (PC1)

#define RCK_HIGH      PORTD |=  (1<<RCK)
#define RCK_LOW       PORTD &= ~(1<<RCK)
#define SCK_HIGH      PORTD |=  (1<<SCK)  
#define SCK_LOW       PORTD &= ~(1<<SCK)
#define OE_HIGH       PORTD |=  (1<<OE)
#define OE_LOW        PORTD &= ~(1<<OE)
//上半屏16X80数据
#define G1DATA_1       PORTC |=  (1<<G1DATA)
#define G1DATA_0       PORTC &= ~(1<<G1DATA)
#define R1DATA_1       PORTC |=  (1<<R1DATA)
#define R1DATA_0       PORTC &= ~(1<<R1DATA)
//下半屏16X80数据
#define G2DATA_1      PORTC |=  (1<<G2DATA)
#define G2DATA_0      PORTC &= ~(1<<G2DATA)
#define R2DATA_1      PORTC |=  (1<<R2DATA)
#define R2DATA_0      PORTC &= ~(1<<R2DATA)

#define RED      (0)
#define GREEN    (1)
#define YELLOW   (2)

#define NO_MOVE    (0)
#define LEFT_MOVE  (1)
#define RIGHT_MOVE (2)

#define BUFFER_SIZE    (12)          //半屏缓冲区汉字个数
#define DISPLAY_SIZE   (5)           //半屏显示最多显示汉字数16X16


const u8 dis16X16[BUFFER_SIZE*32*2] = {

//--  文字:  上  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFF,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0x07,0xFE,0xFF,
0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFB,0x80,0x01,0xFF,0xFF,

//--  文字:  海  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xDE,0xFF,0xEE,0xFF,0xEE,0x01,0xFD,0xFF,0x68,0x07,0xAD,0x77,0xAD,0xB7,0xED,0xF7,
0xD0,0x01,0xDD,0x77,0x1D,0xB7,0xDD,0xF7,0xDC,0x01,0xDF,0xF7,0xDF,0xD7,0xDF,0xEF,

//--  文字:  烽  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xEF,0xBF,0xEF,0x03,0xEF,0x77,0xEA,0xAF,0xA5,0xDF,0xAF,0x27,0xAC,0xD9,0xE2,0x03,
0xEF,0xDF,0xEE,0x03,0xD7,0xDF,0xD8,0x01,0xBF,0xDF,0xBF,0xDF,0x7F,0xDF,0xFF,0xDF,

//--  文字:  能  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xDF,0xBF,0xCF,0xBF,0xDB,0xB3,0xBD,0x8F,0x00,0xBB,0xBD,0xB9,0xFF,0x83,0x81,0xFF,
0xBD,0xBF,0x81,0xB3,0xBD,0x8F,0x81,0xBF,0xBD,0xBB,0xBD,0xB9,0xB5,0xC3,0xBB,0xFF,

//--  文字:  照  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFE,0x03,0xC3,0xBB,0xDB,0xBB,0xDB,0xBB,0xDB,0x6B,0xC2,0xF7,0xD9,0x03,0xDB,0x7B,
0xC3,0x7B,0xDB,0x03,0xFF,0x7B,0xD7,0x77,0xDB,0xBB,0x99,0x99,0x3D,0xDD,0xFF,0xFF,

//--  文字:  明  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFF,0x03,0x83,0x7B,0xBB,0x7B,0xBB,0x7B,0xBB,0x03,0x83,0x7B,0xBB,0x7B,0xBB,0x7B,
0xBB,0x03,0x83,0x7B,0xFF,0x7B,0xFE,0xFB,0xFE,0xFB,0xFD,0xFB,0xFB,0xEB,0xFF,0xF7,

//--  文字:  科  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xF9,0xF7,0x87,0x77,0xF7,0xB7,0xF7,0xB7,0x01,0xF7,0xE7,0x77,0xE3,0xB7,0xD5,0xB7,
0xD7,0xF1,0xB7,0x87,0x74,0x77,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,

//--  文字:  技  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xEF,0xDF,0xEF,0xDF,0xEF,0xDF,0x02,0x01,0xEF,0xDF,0xEB,0xDF,0xE6,0x03,0xCE,0xF7,
0x2F,0x77,0xEF,0x6F,0xEF,0x9F,0xEF,0x9F,0xEF,0x6F,0xEE,0xF1,0xA9,0xFB,0xDF,0xFF,

//--  文字:  有  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFE,0xFF,0xFE,0xFF,0x80,0x01,0xFD,0xFF,0xFB,0xFF,0xF0,0x0F,0xE7,0xEF,0xD7,0xEF,
0xB0,0x0F,0x77,0xEF,0xF7,0xEF,0xF0,0x0F,0xF7,0xEF,0xF7,0x6F,0xF7,0x8F,0xF7,0xDF,

//--  文字:  限  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFF,0xFF,0x04,0x07,0x6D,0xF7,0x6C,0x07,0x5D,0xF7,0x5D,0xF7,0x6C,0x07,0x75,0x7F,
0x75,0xB7,0x55,0xAF,0x6D,0xDF,0x7D,0xDF,0x7D,0xEF,0x7D,0x71,0x7C,0xFB,0x7D,0xFF,

//--  文字:  公  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFF,0xFF,0xFB,0xBF,0xF9,0xBF,0xFB,0xBF,0xF7,0xDF,0xF7,0xEF,0xEF,0xE7,0xDD,0xF1,
0xBC,0xFB,0xFD,0xFF,0xFB,0xDF,0xF7,0xEF,0xEE,0x07,0xC0,0xE7,0xEF,0xEF,0xFF,0xFF,

//--  文字:  司  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFF,0xFF,0xC0,0x03,0xFF,0xFB,0xFF,0xFB,0x80,0x1B,0xFF,0xFB,0xFF,0xFB,0xC0,0x3B,
0xDF,0xBB,0xDF,0xBB,0xC0,0x3B,0xDF,0xBB,0xDF,0xFB,0xFF,0xEB,0xFF,0xF7,0xFF,0xFF,


//--  文字:  上  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFF,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0x07,0xFE,0xFF,
0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFB,0x80,0x01,0xFF,0xFF,

//--  文字:  海  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xDE,0xFF,0xEE,0xFF,0xEE,0x01,0xFD,0xFF,0x68,0x07,0xAD,0x77,0xAD,0xB7,0xED,0xF7,
0xD0,0x01,0xDD,0x77,0x1D,0xB7,0xDD,0xF7,0xDC,0x01,0xDF,0xF7,0xDF,0xD7,0xDF,0xEF,

//--  文字:  璐  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFF,0xDF,0x08,0x5F,0xDB,0x43,0xDB,0x1B,0xDB,0x57,0xD8,0x67,0x05,0xEF,0xDD,0xD7,
0xDC,0xB9,0xD5,0x43,0xD5,0xDB,0xC5,0x5B,0x34,0xDB,0xE3,0xC3,0xFF,0xDB,0xFF,0xFF,

//--  文字:  柯  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xEF,0xFF,0xEF,0xFF,0xEC,0x01,0xEF,0xFB,0x03,0xFB,0xEE,0x1B,0xC6,0xDB,0xCA,0xDB,
0xAA,0xDB,0xAE,0x1B,0x6F,0xFB,0xEF,0xFB,0xEF,0xFB,0xEF,0xFB,0xEF,0xEB,0xEF,0xF7,

//--  文字:  宏  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFE,0xFF,0xFF,0x7F,0xC0,0x01,0xDD,0xFB,0xBC,0xF7,0xFD,0xFF,0x80,0x01,0xFD,0xFF,
0xFB,0x7F,0xFB,0x7F,0xF6,0xFF,0xEE,0xEF,0xDD,0xF7,0xBB,0x03,0xF0,0x77,0xFF,0xFF,

//--  文字:  电  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xC0,0x07,0xDE,0xF7,0xDE,0xF7,0xC0,0x07,0xDE,0xF7,
0xDE,0xF7,0xDE,0xF7,0xC0,0x07,0xDE,0xF7,0xFE,0xFD,0xFE,0xFD,0xFF,0x01,0xFF,0xFF,

//--  文字:  子  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFF,0xFF,0xC0,0x0F,0xFF,0xDF,0xFF,0xBF,0xFF,0x7F,0xFE,0xFF,0xFE,0xFF,0xFE,0xFB,
0x00,0x01,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFE,0xFF,0xFA,0xFF,0xFD,0xFF,

//--  文字:  有  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFE,0xFF,0xFE,0xFF,0x80,0x01,0xFD,0xFF,0xFB,0xFF,0xF0,0x0F,0xE7,0xEF,0xD7,0xEF,
0xB0,0x0F,0x77,0xEF,0xF7,0xEF,0xF0,0x0F,0xF7,0xEF,0xF7,0x6F,0xF7,0x8F,0xF7,0xDF,

//--  文字:  限  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFF,0xFF,0x04,0x07,0x6D,0xF7,0x6C,0x07,0x5D,0xF7,0x5D,0xF7,0x6C,0x07,0x75,0x7F,
0x75,0xB7,0x55,0xAF,0x6D,0xDF,0x7D,0xDF,0x7D,0xEF,0x7D,0x71,0x7C,0xFB,0x7D,0xFF,

//--  文字:  公  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFF,0xFF,0xFB,0xBF,0xF9,0xBF,0xFB,0xBF,0xF7,0xDF,0xF7,0xEF,0xEF,0xE7,0xDD,0xF1,
0xBC,0xFB,0xFD,0xFF,0xFB,0xDF,0xF7,0xEF,0xEE,0x07,0xC0,0xE7,0xEF,0xEF,0xFF,0xFF,

//--  文字:  司  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFF,0xFF,0xC0,0x03,0xFF,0xFB,0xFF,0xFB,0x80,0x1B,0xFF,0xFB,0xFF,0xFB,0xC0,0x3B,
0xDF,0xBB,0xDF,0xBB,0xC0,0x3B,0xDF,0xBB,0xDF,0xFB,0xFF,0xEB,0xFF,0xF7,0xFF,0xFF,

//--  文字:  空  --//
//--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --//
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF

};

const u8 row_scan_table[16] = {0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0};

void port_init(void);
void enable_display(void);
void disable_display(void);
void row_scan(u8 disrow);
void hc595_data(u8 r1data,u8 r2data,u8 g1data,u8 g2data,u8 colour);
void left_shift_data(u8 *in_pointer,u8 *out_pointer,u8 *temp,u8 size);
void right_shift_data(u8 *in_pointer,u8 *out_pointer,u8 *temp,u8 size);
struct struct_led{
    u8  disrow;                    //0-15行,行显示,不需要对应的EEPROM
    u8  dissize;                   //显示尺寸,这个需要对应的EEPROM, //5个字/10个字
        //u8  move;                     
        u8  r1data[BUFFER_SIZE*32];   //缓冲区12个汉字空间
        u8  r1data_buff[BUFFER_SIZE*32]; //数据缓冲区,屏移动的时候才去用它
        u8  r2data[BUFFER_SIZE*32];
        u8  r2data_buff[BUFFER_SIZE*32];
        u8  g1data[BUFFER_SIZE*32];
        u8  g1data_buff[BUFFER_SIZE*32];
        u8  g2data[BUFFER_SIZE*32];
        u8  g2data_buff[BUFFER_SIZE*32];
        u8  status;       //0静态 1左移 2右移 3雪花  
        u8  colour;       //0RED 1GREEN 2YELLOW
        u16 speed;        //
        u16  delay;
}led;

volatile u8 read_data_flag = 0;    //0读取XXdata[XXX],1读取XXdata_buff[XXX]
volatile u8 buffer_data_completed = 0;
volatile u8 size = 0;
u8 r1buffer[16];
u8 r2buffer[16];
u8 g1buffer[16];
u8 g2buffer[16];

#define Fcpu                   (12000000)
#define BASE_TIME              (1)               //ms
#define BASE_TIME_DIV          (64)               //2= 8;3= 64;4= 256;5= 1024;
//#define BASE_TIMERCOUNT        ((BASE_TIME*Fcpu)/(1000000*BASE_TIME_DIV))
#define BASE_TIMERCOUNT        (188)               //((12000)/(1*64))
   
#define LOW_SPEED               (1000)  //1000*BASE_TIME = 1S
#define MIDDLE_SPEED            (500)  //500*BASE_TIME = 500mS
#define HIGH_SPEED              (100)   //100*BASE_TIME = 100mS

void base_timer0_initial(void);


void eeprom_write(u16 address,u8 data);
u8 eeprom_read(u16 address);
void write_data_eeprom(void);
void led_parameter_initial(void);




void main(void){
    u16 i = 0,num = 0;
        write_data_eeprom();
        led_parameter_initial();
        /*
        for(i=0;i<12*32;i++){
            led.r1data = dis16X16;
                led.r2data = dis16X16;
                led.g1data = dis16X16;
                led.g2data = dis16X16;
                led.r1data_buff = dis16X16;
                led.r2data_buff = dis16X16;
                led.g1data_buff = dis16X16;
                led.g2data_buff = dis16X16;
        }
        led.status = RIGHT_MOVE;  //左移
        led.colour = GREEN;  //绿色
        led.dissize = DISPLAY_SIZE; //5个字的长度
        */
        base_timer0_initial();
        port_init();
        disable_display();
        
        while(1){
            while(TCNT0!=BASE_TIMERCOUNT);  //1ms一次循环,这样就可执行1ms*12000=12000个机器周期指令
               
                TCNT0 = 0;
                //每隔1ms扫描一行,这样每行的扫描频率即为1s/16ms=62,5HZ
               
                disable_display();                   //1关显示
                if(++led.disrow==16){                //2指向下一行   
                        led.disrow = 0;
            }
                //静态显示
                if(led.status==NO_MOVE){
                    for(num=0;num<led.dissize;num++){   //3送要发送的数据
                        hc595_data(led.r1data[2*led.disrow + num*32],led.r2data[2*led.disrow + num*32],led.g1data[2*led.disrow + num*32],led.g2data[2*led.disrow + num*32],led.colour);
                            hc595_data(led.r1data[(2*led.disrow+1) + num*32],led.r2data[(2*led.disrow+1) + num*32],led.g1data[(2*led.disrow+1) + num*32],led.g2data[(2*led.disrow+1) + num*32],led.colour);
            }
                        RCK_LOW;                             //4将要发送的数据锁存到595中
                    RCK_HIGH;
                    row_scan(led.disrow);                //5送扫描行数据
                    enable_display();                    //6打开显示   
                }
                //移动显示
                else{//if(led.status!=0)
               
                    if(read_data_flag==0){
                            for(num=0;num<led.dissize;num++){   //3送要发送的数据
                            hc595_data(led.r1data[2*led.disrow + num*32],led.r2data[2*led.disrow + num*32],led.g1data[2*led.disrow + num*32],led.g2data[2*led.disrow + num*32],led.colour);
                                hc595_data(led.r1data[(2*led.disrow+1) + num*32],led.r2data[(2*led.disrow+1) + num*32],led.g1data[(2*led.disrow+1) + num*32],led.g2data[(2*led.disrow+1) + num*32],led.colour);
                        
                                }
                                RCK_LOW;                             //4将要发送的数据锁存到595中
                        RCK_HIGH;
                        row_scan(led.disrow);                //5送扫描行数据
                        enable_display();   
                        }
                        else if(read_data_flag==1){
                            for(num=0;num<led.dissize;num++){   //3送要发送的数据
                            hc595_data(led.r1data_buff[2*led.disrow + num*32],led.r2data_buff[2*led.disrow + num*32],led.g1data_buff[2*led.disrow + num*32],led.g2data_buff[2*led.disrow + num*32],led.colour);
                                hc595_data(led.r1data_buff[(2*led.disrow+1) + num*32],led.r2data_buff[(2*led.disrow+1) + num*32],led.g1data_buff[(2*led.disrow+1) + num*32],led.g2data_buff[(2*led.disrow+1) + num*32],led.colour);
                        }
                                RCK_LOW;                             //4将要发送的数据锁存到595中
                        RCK_HIGH;
                        row_scan(led.disrow);                //5送扫描行数据
                        enable_display();                                 
                        }
                        
                        if(++led.speed==HIGH_SPEED){
                            led.speed = 0;
                            if(buffer_data_completed = 1){
                                    buffer_data_completed = 0;
                                    read_data_flag ^= 0x01;
                                        read_data_flag &= 0x01;  
                                }
                                else{
                                    led.speed--;
                                }
                        }
                        
                        ///////////////////////////////////////////////////////////
                        if(read_data_flag==0){
                            if(led.status==0){//静态,不移动
                                    
                                }
                                else if(led.status==LEFT_MOVE){//左移
                                    if(led.colour==RED){
                                        left_shift_data(led.r1data,led.r1data_buff,r1buffer,size);
                                            left_shift_data(led.r2data,led.r2data_buff,r2buffer,size);
                                    }
                                    else if(led.colour==GREEN){
                                        left_shift_data(led.g1data,led.g1data_buff,g1buffer,size);
                                            left_shift_data(led.g2data,led.g2data_buff,g2buffer,size);
                                    }
                                    else if(led.colour==YELLOW){
                                        left_shift_data(led.r1data,led.r1data_buff,r1buffer,size);
                                            left_shift_data(led.r2data,led.r2data_buff,r2buffer,size);
                                        left_shift_data(led.g1data,led.g1data_buff,g1buffer,size);
                                            left_shift_data(led.g2data,led.g2data_buff,g2buffer,size);
                                    }
                                    if(++size==12){
                                        size = 0;
                                        buffer_data_completed = 1;   
                                    }
                                    else{
                                    }
                                }

                                else if(led.status==RIGHT_MOVE){//右移
                                    if(led.colour==RED){
                                        right_shift_data(led.r1data,led.r1data_buff,r1buffer,size);
                                            right_shift_data(led.r2data,led.r2data_buff,r2buffer,size);
                                    }
                                    else if(led.colour==GREEN){
                                        right_shift_data(led.g1data,led.g1data_buff,g1buffer,size);
                                            right_shift_data(led.g2data,led.g2data_buff,g2buffer,size);
                                    }
                                    else if(led.colour==YELLOW){
                                        right_shift_data(led.r1data,led.r1data_buff,r1buffer,size);
                                            right_shift_data(led.r2data,led.r2data_buff,r2buffer,size);
                                        right_shift_data(led.g1data,led.g1data_buff,g1buffer,size);
                                            right_shift_data(led.g2data,led.g2data_buff,g2buffer,size);
                                    }
                                    if(++size==12){
                                        size = 0;
                                        buffer_data_completed = 1;   
                                    }
                                    else{
                                    }
                                }
                        }
            else if(read_data_flag==1){
                            if(led.status==0){
                                    //不移动
                                }
                                else if(led.status==LEFT_MOVE){
                                    if(led.colour==RED){
                                        left_shift_data(led.r1data_buff,led.r1data,r1buffer,size);
                                            left_shift_data(led.r2data_buff,led.r2data,r2buffer,size);
                                    }
                                    else if(led.colour==GREEN){
                                        left_shift_data(led.g1data_buff,led.g1data,g1buffer,size);
                                            left_shift_data(led.g2data_buff,led.g2data,g2buffer,size);
                                    }
                                    else if(led.colour==YELLOW){
                                        left_shift_data(led.r1data_buff,led.r1data,r1buffer,size);
                                            left_shift_data(led.r2data_buff,led.r2data,r2buffer,size);
                                        left_shift_data(led.g1data_buff,led.g1data,g1buffer,size);
                                            left_shift_data(led.g2data_buff,led.g2data,g2buffer,size);
                                    }
                                    if(++size==12){
                                        size = 0;
                                        buffer_data_completed = 1;   
                                    }
                                    else{
                                    }   
                                }
               
                            else if(led.status==RIGHT_MOVE){
                                    if(led.colour==RED){
                                        right_shift_data(led.r1data_buff,led.r1data,r1buffer,size);
                                            right_shift_data(led.r2data_buff,led.r2data,r2buffer,size);
                                    }
                                    else if(led.colour==GREEN){
                                        right_shift_data(led.g1data_buff,led.g1data,g1buffer,size);
                                            right_shift_data(led.g2data_buff,led.g2data,g2buffer,size);
                                    }
                                    else if(led.colour==YELLOW){
                                        right_shift_data(led.r1data_buff,led.r1data,r1buffer,size);
                                            right_shift_data(led.r2data_buff,led.r2data,r2buffer,size);
                                        right_shift_data(led.g1data_buff,led.g1data,g1buffer,size);
                                            right_shift_data(led.g2data_buff,led.g2data,g2buffer,size);
                                    }
                                    if(++size==12){
                                        size = 0;
                                        buffer_data_completed = 1;   
                                    }
                                    else{
                                    }   
                                }
                        }
                        ///////////////////////////////////////////////////////////
                }
        }
}

void base_timer0_initial(void){
    TCCR0A = 0x00;
        TCCR0B = 0x00;
        TCNT0  = 0x00;
        TCCR0B = 3;     //3= 64;4= 256;5= 1024;
}


void port_init(void){
    DDRD |= (1<<A) | (1<<B) | (1<<C) | (1<<D) | (1<<RCK) | (1<<SCK) | (1<<OE);
        DDRC |= (1<<G1DATA) | (1<<R1DATA) | (1<<G2DATA) | (1<<R2DATA);
}

void enable_display(void){
    OE_LOW;
}

void disable_display(void){
    OE_HIGH;
}

void row_scan(u8 disrow){

        PORTD = ( (PORTC&0x0f) | row_scan_table[disrow] );
}
/***********************************************************************
测试发现hc595_data()函数在12MHZ晶振下,运行花费YELLOW:38uS;RED/GREEN:30.8uS.
***********************************************************************/
void hc595_data(u8 r1data,u8 r2data,u8 g1data,u8 g2data,u8 colour){
    u8 i = 0;
        switch(colour){
            case RED:
                          //8位字节数据,先发最低位,最后发最高位
                      //for(i=0x01;i!=0;i=i<<1){
                          for(i=0x80;i!=0;i=i>>1){
                          if(r1data&i){
                                  R1DATA_1;
                              }
                              else{
                                  R1DATA_0;
                              }
                              if(r2data&i){
                                  R2DATA_1;
                              }
                              else{
                                  R2DATA_0;
                              }
                                          
                                          G1DATA_1;
                                          G2DATA_1;
                              
                                          SCK_LOW;
                          SCK_HIGH;
                      }
                                  break;
                case GREEN:
                          for(i=0x80;i!=0;i=i>>1){
                          if(g1data&i){
                                  G1DATA_1;
                              }
                              else{
                                  G1DATA_0;
                              }
                              if(g2data&i){
                                  G2DATA_1;
                              }
                              else{
                                  G2DATA_0;
                              }
                                          R1DATA_1;
                                          R2DATA_1;
                                          
                              SCK_LOW;
                          SCK_HIGH;
                      }
                                  break;
                case YELLOW:
                          for(i=0x80;i!=0;i=i>>1){
                          if(r1data&i){
                                  R1DATA_1;
                              }
                              else{
                                  R1DATA_0;
                              }
                              if(r2data&i){
                                  R2DATA_1;
                              }
                              else{
                                  R2DATA_0;
                              }
                          if(g1data&i){
                                  G1DATA_1;
                              }
                              else{
                                  G1DATA_0;
                              }
                              if(g2data&i){
                                  G2DATA_1;
                              }
                              else{
                                  G2DATA_0;
                              }
                              SCK_LOW;
                          SCK_HIGH;
                      }
                                  break;
                default:
                         break;                                                              
                        
        }
}
/***********************************************************************
测试发现left_shift_data()函数在12MHZ晶振下,运行花费2880uS.
***********************************************************************/
//适用16x16点阵显示的汉字
void left_shift_data(u8 *in_pointer,u8 *out_pointer,u8 *temp,u8 size){
    unsigned int i = 0;
                if(size==0){
                    for(i=0;i<16;i++){
                            temp = in_pointer[i*2];
                            out_pointer[i*2+size*32]     = (in_pointer[i*2+size*32]<<1)     | (in_pointer[(i*2+1)+size*32]>>7);
                                out_pointer[(i*2+1)+size*32] = (in_pointer[(i*2+1)+size*32]<<1) | (in_pointer[(i*2+32)+size*32]>>7);   
                        }
                }
                else if(size>0 && size<11){
                    for(i=0;i<16;i++){
                            out_pointer[i*2+size*32]     = (in_pointer[i*2+size*32]<<1)     | (in_pointer[(i*2+1)+size*32]>>7);
                                out_pointer[(i*2+1)+size*32] = (in_pointer[(i*2+1)+size*32]<<1) | (in_pointer[(i*2+32)+size*32]>>7);   
                        }
                }
                else if(size==11){
                    for(i=0;i<16;i++){
                            out_pointer[i*2+size*32]     = (in_pointer[i*2+size*32]<<1)     | (in_pointer[(i*2+1)+size*32]>>7);
                                out_pointer[(i*2+1)+size*32] = (in_pointer[(i*2+1)+size*32]<<1) | (temp>>7);   
                        }
                }
}

void right_shift_data(u8 *in_pointer,u8 *out_pointer,u8 *temp,u8 size){
    unsigned int i = 0;
                if(size==0){
                    for(i=0;i<16;i++){
                                out_pointer[(i*2+1)+size*32] = (in_pointer[(i*2+1)+size*32]>>1) | (in_pointer[(i*2)+size*32]<<7);   
                        }
                }
                else if(size>0 && size<11){
                    for(i=0;i<16;i++){
                            out_pointer[(i*2)+size*32]   = (in_pointer[(i*2)+size*32]>>1)   | (in_pointer[(i*2+1)+size*32-32]<<7);
                                out_pointer[(i*2+1)+size*32] = (in_pointer[(i*2+1)+size*32]>>1) | (in_pointer[(i*2)+size*32]<<7);   
                        }
                }
                else if(size==11){
                    for(i=0;i<16;i++){
                            temp = out_pointer[(i*2+1)+size*32];
                        }
                    for(i=0;i<16;i++){
                            out_pointer[(i*2)+size*32]   = (in_pointer[(i*2)+size*32]>>1)   | (in_pointer[(i*2+1)+size*32-32]<<7);
                                out_pointer[(i*2+1)+size*32] = (in_pointer[(i*2+1)+size*32]>>1) | (in_pointer[(i*2)+size*32]<<7);   
                                out_pointer[(i*2)+0*32]      = (in_pointer[(i*2)+0*32]>>1)      | (temp<<7);
                        }
                }  
}



void eeprom_write(u16 address,u8 data)
{
/*wait for completion of previous write*/
while(EECR & (1<<EEWE));
/*set up address and data registers*/
EEAR = address;
EEDR = data;
/*write logical one to EEMWE*/
EECR |= (1<<EEMWE);
/*start eeprom write by setting EEWE*/
EECR |= (1<<EEWE);
}
u8 eeprom_read(u16 address)
{
/*wait for completion of pervious wirte*/
while(EECR & (1<<EEWE));
/*set up address register*/
EEAR = address;
/*start eeprom read by writing EERE*/
EECR |= (1<<EERE);
/*Return data from data register*/
return EEDR;
}

void led_parameter_initial(void){
    u16 i = 0,temp = 0,j = 0;
    led.dissize = eeprom_read(0x0001);
        led.status  = eeprom_read(0x0002);
        led.colour  = eeprom_read(0x0003);
        
        temp = eeprom_read(0x0000);
        if(temp==0){ //16X16字
            for(i=0;i<BUFFER_SIZE*32;i++){ //上下屏加一起可以存储12*2=24个字
                led.r1data      = eeprom_read(i+10);
                    led.r1data_buff = led.r1data;
                        led.g1data      = led.r1data;
                    led.g1data_buff = led.r1data;
                        
                    led.r2data      = eeprom_read(i+10+384);
                    led.r2data_buff = led.r2data;
                    led.g2data      = led.r2data;
                    led.g2data_buff = led.r2data;
            }
        }
        else if(temp==1){//32X32字
            for(j=0;j<6;j++){ //32X32的字只能存6个
                    for(i=0;i<16;i++){
                        led.r1data[0+2*i+j*64]     = eeprom_read(10+4*i+0+j*128);
                            led.r1data[1+2*i+j*64]     = eeprom_read(10+4*i+1+j*128);
                                led.r1data[0+2*i+32+j*64]  = eeprom_read(10+4*i+2+j*128);
                                led.r1data[1+2*i+32+j*64]  = eeprom_read(10+4*i+3+j*128);
                            led.r2data[0+2*i+j*64]     = eeprom_read(10+64+4*i+0+j*128);
                            led.r2data[1+2*i+j*64]     = eeprom_read(10+64+4*i+1+j*128);
                                led.r2data[0+2*i+32+j*64]  = eeprom_read(10+64+4*i+2+j*128);
                            led.r2data[1+2*i+32+j*64]  = eeprom_read(10+64+4*i+3+j*128);
                }      
                }
                for(i=0;i<BUFFER_SIZE*32;i++){
                    led.r1data_buff = led.r1data;
                        led.g1data      = led.r1data;
                    led.g1data_buff = led.r1data;
                        
                        led.r2data_buff = led.r2data;
                    led.g2data      = led.r2data;
                    led.g2data_buff = led.r2data;   
                }
        }
        
}

void write_data_eeprom(void){
    u16 i = 0;
        eeprom_write(0x0000,0);  //0代表16X16字,1代表32*32字
    eeprom_write(0x0001,10);  //显示屏宽度,5代表可以显示5个16X16的宽度,10代表可以显示10个16X16的宽度
        eeprom_write(0x0002,1);  //0 NO_MOVE;1 LEFT_MOVE;2 RIGHT_MOVE  
        eeprom_write(0x0003,0);  //0 RED; 1 GREEN;2 YELLOW  

        
        for(i=0;i<BUFFER_SIZE*32*2;i++){        //存储时就按字顺序存,读取的时候要区分16X16还是32X32;
            eeprom_write(i+10,dis16X16);   
        }
}
发表于 2012-4-18 00:02 | 显示全部楼层
本帖最后由 qiantu 于 2012-4-18 00:05 编辑

程序写的不错,我也有一块楼主一样的屏,楼主如可以搞一个32*80的万年历时钟就好了!
这样的布局就不错,并且可以加上秒。
https://www.yleee.com.cn/attachments/forumid_26/1204040152368f8f1708106690.jpg
 楼主| 发表于 2012-4-18 14:12 | 显示全部楼层
设计了一个简单的控制卡,板子发出去做了,回来就做个电子时钟,而且可以设置调整时间~

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-5-1 05:28 , Processed in 0.058122 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表