Chenmin 发表于 2012-6-21 10:02:25

求高手修改下 8051的LED点阵程序为arduino程序。

感谢 [email protected] 的代码。程序已经测试正常。
http://player.youku.com/player.php/sid/XNDIwMTEyNTA0/v.swf



以上为该 模块的 资料。
以下为原始代码。
/*16*16点阵屏的显示*/

#include <reg51.h>
#include <intrins.h>       

#define DATE_OUT P2                        //指定P2口做为输出
sbit DATA=DATE_OUT^0;                //列数据输出位       
sbit SCLH=DATE_OUT^1;                //列扫描时钟位
sbit SCLT=DATE_OUT^2;                //列数据锁存位
sbit AB=DATE_OUT^3;                //行数据输出位
sbit SCK =DATE_OUT^4;                //行扫描时钟位


unsigned char date;                //32字节RAM做为16*16点阵屏显示缓存
void display();                                //做为点阵扫描函数,将显示缓存的数据输出到点阵屏
void display_time(unsigned int timer);                        //指定时间扫描显示


code unsigned char zuo={//左
0x02,0x00,0x02,0x00,0x02,0x08,0x0FF,0x0FC,
0x04,0x00,0x04,0x00,0x04,0x00,0x08,0x10,
0x0F,0x0F8,0x10,0x80,0x10,0x80,0x20,0x80,
0x40,0x80,0x80,0x84,0x7F,0x0FE,0x00,0x00};

code unsigned char you={//右
0x02,0x00,0x02,0x00,0x02,0x04,0x0FF,0x0FE,
0x04,0x00,0x04,0x00,0x08,0x00,0x08,0x08,
0x1F,0x0FC,0x28,0x08,0x48,0x08,0x88,0x08,
0x08,0x08,0x08,0x08,0x0F,0x0F8,0x08,0x08};

code unsigned char sha={//刹
0x20,0x84,0x11,0x84,0x0A,0x24,0x04,0x24,
0x0A,0x24,0x11,0x0A4,0x64,0x0A4,0x04,0x24,
0x0FF,0x0E4,0x04,0x24,0x15,0x24,0x14,0x84,
0x24,0x84,0x44,0x04,0x14,0x14,0x08,0x08};

code unsigned char ting={//停
0x10,0x80,0x10,0x48,0x17,0x0FC,0x20,0x00,
0x23,0x0F8,0x62,0x08,0x0A3,0x0F8,0x20,0x00,
0x2F,0x0FE,0x28,0x02,0x33,0x0F4,0x20,0x40,
0x20,0x40,0x20,0x40,0x21,0x40,0x20,0x80};


void main(void)
{
        unsigned char i=0,j=0;       
        while(1)
                {       
                for(i=0;i<32;i++)
                        date=zuo;//将"左"字数据复制到显示缓存
                display_time(2);        //显示约2秒

                for(i=0;i<32;i++)
                        date=you;//将"右"字数据复制到显示缓存
                display_time(2);        //显示约2秒

                for(i=0;i<32;i++)
                        date=sha;//将"刹"字数据复制到显示缓存
                display_time(2);        //显示约2秒

                for(i=0;i<32;i++)
                        date=ting;//将"停"字数据复制到显示缓存
                display_time(2);        //显示约2秒
                }
}

/*   显示函数   */
void display()
{       
        unsigned char i,ia,j,tmp;                //定义变量
        DATE_OUT=0XFF;                                        //置位高电平做准备
        AB=0;                                                        //将行数据位清0,准备移位
        for(i=0;i<16;i++)                          //循环输出16行数据
        {               
                SCK=0;                                //为行移位做准备
                SCLT=0;                                //为列锁存做准备
                for(ia=2;ia>0;)                //每行16个点,循环位移两个字节
                {       
                        ia--;                        //循环两次
                        tmp=~date;                //读取点阵数据做输出,这里用到ia目的是先读取点阵数据的第二位字节,因一行16个点由两个字节组成,
                                                                  //电路中的移位寄存器最后一位对应最后一列,所以要先输出一行中的第二个字节数据
                        for(j=0;j<8;j++)                 //循环两次,每次移一个字节,
                                {       
                                SCLH=0;                                //为列移位做准备
                           DATA=tmp&0x01;           //将数据低位做输出,由电路图可知,移位寄存器的最后一位对应最后一列,因此先移最后一位
                                tmp>>=1;                        //将数据缓冲右移一位,为下次输出做准备
                           SCLH=1;                                //将DATA上的数据移入寄存器
                        }                                        //移入单字节结束
                }                                                        //移入两个字节结束
                DATE_OUT|=0X14;                                //此句可以用以下两句来理解,如果不将两句合为一句,将出现拖影现像
                //SCK=1;                                        //SCK拉高,行数据移位,相应行拉低,三极管导通输出电量到相应行点阵管阳极(共阳)
                //SCLT=1;                                        //SCLT拉高,将数据锁存输出到相应列的点阵发光管显示,显示一行后将保持到下一行显示开始
                AB=1;                                                //行数据位只在第一行时为0,其它时候都为1,当将这个0移入寄存器后,从第一位开始一直移位最后一位,
        }                                                                //移位的过程,AB就必需是1,这是因为不能同时有两个及两个以上0的出现,否则显示出乱       
        j=64;
        while(j--);                //每一行的显示,保持两个字节的移位时间,因此,最后一行的显示,也要加入保持时间,补尝显示的亮度
        SCK=0;                        //
        SCK=1;                        //将最后一行数据移出
}

/*   timer=1时,为1s左右的延时   */
void display_time(unsigned int timer)        //指定时间扫描显示
{
        unsigned char i;       
        while(timer--)
        {               
                i=130;               
                while(i--)
                        display();
        }
}



这是我改的。。好像还是 不对
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.

This example code is in the public domain.
*/

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

unsigned char i=0,j=0;       
//ck:P24
//ab:P23
//rck: P22
//srcl:P21
//ser: P20

static const int DATA=9;                //列数据输出位        灰
static const int SCLH=10;                //列扫描时钟位紫
static const int SCLT=11;                //列数据锁存位蓝
static const int AB=12;                //行数据输出位绿
//static const int SCK =13;                //行扫描时钟位黄



unsigned char date;                //32字节RAM做为16*16点阵屏显示缓存
void display();                                //做为点阵扫描函数,将显示缓存的数据输出到点阵屏
void display_time(unsigned int timer);                        //指定时间扫描显示


unsigned char zuo={//左
0x02,0x00,0x02,0x00,0x02,0x08,0x0FF,0x0FC,
0x04,0x00,0x04,0x00,0x04,0x00,0x08,0x10,
0x0F,0x0F8,0x10,0x80,0x10,0x80,0x20,0x80,
0x40,0x80,0x80,0x84,0x7F,0x0FE,0x00,0x00};

unsigned char you={//右
0x02,0x00,0x02,0x00,0x02,0x04,0x0FF,0x0FE,
0x04,0x00,0x04,0x00,0x08,0x00,0x08,0x08,
0x1F,0x0FC,0x28,0x08,0x48,0x08,0x88,0x08,
0x08,0x08,0x08,0x08,0x0F,0x0F8,0x08,0x08};

unsigned char sha={//刹
0x20,0x84,0x11,0x84,0x0A,0x24,0x04,0x24,
0x0A,0x24,0x11,0x0A4,0x64,0x0A4,0x04,0x24,
0x0FF,0x0E4,0x04,0x24,0x15,0x24,0x14,0x84,
0x24,0x84,0x44,0x04,0x14,0x14,0x08,0x08};

unsigned char ting={//停
0x10,0x80,0x10,0x48,0x17,0x0FC,0x20,0x00,
0x23,0x0F8,0x62,0x08,0x0A3,0x0F8,0x20,0x00,
0x2F,0x0FE,0x28,0x02,0x33,0x0F4,0x20,0x40,
0x20,0x40,0x20,0x40,0x21,0x40,0x20,0x80};



// the setup routine runs once when you press reset:
void setup() {               
// initialize the digital pin as an output.
pinMode(led, OUTPUT);   
}

// the loop routine runs over and over again forever:
void loop() {
digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
delay(1000);               // wait for a second
digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
delay(1000);               // wait for a second
show();
}

void high(int led){
digitalWrite(led, HIGH);
}

void low(int led){
digitalWrite(led, LOW);
}

void highAll(){
high(DATA);
high(SCLH);
high(SCLT);
high(AB);
high(SCK);
}

void show( )
{
       
       
                for(i=0;i<32;i++)
                        date=zuo;//将"左"字数据复制到显示缓存
                display_time(2);        //显示约2秒

                for(i=0;i<32;i++)
                        date=you;//将"右"字数据复制到显示缓存
                display_time(2);        //显示约2秒

                for(i=0;i<32;i++)
                        date=sha;//将"刹"字数据复制到显示缓存
                display_time(2);        //显示约2秒

                for(i=0;i<32;i++)
                        date=ting;//将"停"字数据复制到显示缓存
                display_time(2);        //显示约2秒
               
}


/*   显示函数   */
void display()
{       
        unsigned char i,ia,j,tmp;                //定义变量
        highAll();//DATE_OUT=0XFF;                                        //置位高电平做准备
        low(AB);//AB=0;                                                        //将行数据位清0,准备移位
        for(i=0;i<16;i++)                          //循环输出16行数据
        {               
                low(SCK);//SCK=0;                                //为行移位做准备
                low(SCLT);//SCLT=0;                                //为列锁存做准备
                for(ia=2;ia>0;)                //每行16个点,循环位移两个字节
                {       
                        ia--;                        //循环两次
                        tmp=~date;                //读取点阵数据做输出,这里用到ia目的是先读取点阵数据的第二位字节,因一行16个点由两个字节组成,
                                                                  //电路中的移位寄存器最后一位对应最后一列,所以要先输出一行中的第二个字节数据
                        for(j=0;j<8;j++)                 //循环两次,每次移一个字节,
                                {       
                                low(SCLH);//SCLH=0;                                //为列移位做准备
                           //DATA=tmp&0x01;           //将数据低位做输出,由电路图可知,移位寄存器的最后一位对应最后一列,因此先移最后一位
                                if(tmp&0x01==1){
                                  high(DATA);
                              }else{
                                 low(DATA);
                              }
                              tmp>>=1;                        //将数据缓冲右移一位,为下次输出做准备
                           high(SCLH);//SCLH=1;                                //将DATA上的数据移入寄存器
                        }                                        //移入单字节结束
                }                                                        //移入两个字节结束
                ////DATE_OUT|=0X14;                                //此句可以用以下两句来理解,如果不将两句合为一句,将出现拖影现像
                //SCK=1;                                        //SCK拉高,行数据移位,相应行拉低,三极管导通输出电量到相应行点阵管阳极(共阳)
                //SCLT=1;                                        //SCLT拉高,将数据锁存输出到相应列的点阵发光管显示,显示一行后将保持到下一行显示开始
                high(DATA);//AB=1;                                                //行数据位只在第一行时为0,其它时候都为1,当将这个0移入寄存器后,从第一位开始一直移位最后一位,
        }                                                                //移位的过程,AB就必需是1,这是因为不能同时有两个及两个以上0的出现,否则显示出乱       
        j=64;
        while(j--);                //每一行的显示,保持两个字节的移位时间,因此,最后一行的显示,也要加入保持时间,补尝显示的亮度
        low(SCK);//SCK=0;                        //
        high(SCK);//SCK=1;                        //将最后一行数据移出
}

/*   timer=1时,为1s左右的延时   */
void display_time(unsigned int timer)        //指定时间扫描显示
{
        unsigned char i;       
        while(timer--)
        {               
                i=13000;               
                while(i--)
                        display();
        }
}

[email protected] 发表于 2012-6-23 17:23:13

诶~你怎么也用这个啊是74hc595+74hc164吧
我前几天才做好的,才把软件改好想放教程就来这个
算了给你来吧
这三个字是我很重要的人的名字请不要改
中间因为无法同时改变电平所以有拖影
若不亮请改变接口定义#define DS 30      //列数据输出位 DS_595
#define SHCP 32      //列扫描时钟位 SHCP_595
#define STCP 34      //列数据锁存位 STCP_595   
#define AB 36   //行数据输出位 AB_164
#define CLK 38      //行扫描时钟位 CP_164   

unsigned char date;                //32字节RAM做为16*16点阵屏显示缓存
unsigned char i=0,j=0;

unsigned char code1={//lu
0x00,0x20,0x7C,0x20,0x44,0x28,0x49,0xFC,
0x48,0x20,0x50,0x20,0x48,0x24,0x4B,0xFE,
0x44,0x20,0x45,0x24,0x45,0x24,0x69,0x24,
0x51,0x24,0x41,0x24,0x41,0xFC,0x41,0x04};

unsigned char code2={//jia
0x01,0x08,0x7F,0xFC,0x01,0x00,0x3F,0xF8,
0x00,0x00,0x1F,0xF0,0x10,0x10,0x1F,0xF0,
0x04,0x44,0xFF,0xFE,0x10,0x08,0x7E,0xFC,
0x12,0x88,0x12,0x88,0x2A,0xF8,0x44,0x88};

unsigned char code3={//nan
0x20,0x40,0x20,0x40,0x20,0x44,0x2F,0xFE,
0xF8,0x40,0x20,0x44,0x37,0xFE,0x6D,0x14,
0x64,0xA4,0xA5,0xF4,0x24,0x44,0x24,0x44,
0x27,0xFC,0x24,0x44,0x24,0x54,0x24,0x08
};

/*unsigned char code4={//
0x00,0x80,0x20,0x80,0x20,0x80,0x20,0x80,
0x20,0x84,0x3F,0xFE,0x20,0x00,0x20,0x00,
0x3F,0xC0,0x20,0x40,0x20,0x40,0x20,0x40,
0x20,0x40,0x20,0x40,0x40,0x40,0x80,0x40};

unsigned char code5={//
0x01,0x00,0x11,0x00,0x11,0x10,0x1F,0xF8,
0x11,0x00,0x21,0x00,0x01,0x04,0xFF,0xFE,
0x03,0x00,0x05,0x80,0x09,0x40,0x11,0x30,
0x21,0x0E,0xC1,0x04,0x01,0x00,0x01,0x00
};
*/
void setup(){
pinMode(DS,OUTPUT);
pinMode(STCP,OUTPUT);
pinMode(SHCP,OUTPUT);
pinMode(CLK,OUTPUT);
pinMode(AB,OUTPUT);
}

void loop(){
for(i=0;i<32;i++){
    date=code1;
}
display_time(2);      //显示约2秒

for(i=0;i<32;i++){
    date=code2;
}
display_time(2);      //显示约2秒

for(i=0;i<32;i++){

    date=code3;
}
display_time(2);      //显示约2秒

/* for(i=0;i<32;i++){
    date=code4;
}
display_time(2);      //显示约2秒

for(i=0;i<32;i++){
    date=code5;
}
display_time(2);      //显示约2秒
   */
}

/*   显示函数   */
void display()    //做为点阵扫描函数,将显示缓存的数据输出到点阵屏
{      
unsigned char i,ia,j,tmp;                //定义变量
digitalWrite(AB,LOW);                        //将行数据位清0,准备移位
for(i=0;i<16;i++)                        //循环输出16行数据
{               
    digitalWrite(CLK,LOW);                //为行移位做准备
    digitalWrite(STCP,LOW);                //为列锁存做准备
    for(ia=2;ia>0;)                        //每行16个点,循环位移两个字节
    {      
      ia--;                              //循环两次
      tmp=~date;
      //读取点阵数据做输出,这里用到ia目的是先读取点阵数据的第二位字节,
      //因一行16个点由两个字节组成,
      //电路中的移位寄存器最后一位对应最后一列,
      //所以要先输出一行中的第二个字节数据

      shiftOut(DS,SHCP,LSBFIRST,tmp);
      
    }                                        //移入两个字节结束
    digitalWrite(CLK,HIGH);
    digitalWrite(STCP,HIGH);
    digitalWrite(AB,HIGH);
   
}               
j=64;
while(j--){               
    digitalWrite(CLK,LOW);                        
    digitalWrite(CLK,HIGH);
}
}

/*   timer=1时,为1s左右的延时   */

void display_time(unsigned int timer)      //指定时间扫描显示
{
unsigned char i;      
while(timer--)
{               
    i=130;               
    while(i--)
      display();
}
}

Chenmin 发表于 2012-6-25 12:59:32

:D:D:D:D,今晚回家试试,多谢了。

Randy 发表于 2012-6-25 17:41:58

双色的点阵和单色的点阵我也没有玩过,玩过RGB点阵,楼上的使出来发个效果图哦!

Chenmin 发表于 2012-6-26 14:50:45

本帖最后由 Chenmin 于 2012-6-26 15:19 编辑

http://player.youku.com/player.php/sid/XNDIwMTEyMTcy/v.swf

陆嘉楠 是你女朋友吗








estar 发表于 2012-11-13 13:02:42

同时改变电平可以参考这个帖子:http://www.geek-workshop.com/thread-389-1-1.html
页: [1]
查看完整版本: 求高手修改下 8051的LED点阵程序为arduino程序。