极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 97441|回复: 68

【Z】Arduino也能驱动LED显示屏,LED业界标准Arduino驱动方案解析

  [复制链接]
发表于 2013-6-29 16:59:53 | 显示全部楼层 |阅读模式
本帖最后由 zzz 于 2013-6-29 17:08 编辑

现在市面上有很多很多的LED显示屏,但大多都基于同一种,或者同一类型的驱动方式,简称08驱动方式,它内部有LED点阵,74HC595,以及138行扫芯片组成,但毫无例外的,是主控板都采用了STC方案,或者串口方案,而Arduino驱动却鲜有人用,今天,小Z就带了LED业界标准Arduino驱动方案的介绍与解析

市场上主流的显示屏有F3.75和F3.0两种,F后面代表的点阵屏单体LED的直径,而今天,小Z用的是F2.0的超密集进口点阵,显示效果个人很喜欢,下面是市场上常见的2种屏幕(F3.75 F3.0)和今天所使用的F2.0屏幕(分辨率均为16*64)的对比图,可以很轻松的看出大小的差别。


随后的重点便是行驱的模式,今天我推荐两种驱动模式,分别是16*16驱动模式,和16*64直接驱动模式,这两种模式各有特点,16*16即是汉字是一个一个取模,一个一个显示,而16*64是取模软件直接取出一幅完整的图像。如果是显示汉字的同学,推荐采用第一种,而显示图形的同学,推荐采用第二种。

下面,先把主体的演示代码发一下。
  1. #define RowA 2   
  2. #define RowB 3
  3. #define RowC 4
  4. #define RowD 5
  5. //业界所采用的ABCD 08驱动模式
  6. int hc138en=6; //EN口

  7. //使用了硬件SPI,以下脚不能更改
  8. #define R1 11          //数据出    MOSI
  9. #define CLK 13         //时钟    SCK
  10. #define STB 10         //595 刷新显示  SS
  11. #define DATAIN  12     //数据入,读FLASH时有用  MISO

  12. byte row=0;
  13. byte zzz[] =

  14. {
  15. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xF1,0xFF,0xE3,0xFF,0xC0,0x00,0x00,
  16. 0xFF,0xF1,0xFF,0xE3,0xFF,0xC0,0x00,0x00,0x00,0x70,0x00,0xE0,0x01,0xC0,0x00,0x00,
  17. 0x00,0xE0,0x01,0xC0,0x03,0x80,0x00,0x00,0x01,0xC0,0x03,0x80,0x07,0x00,0x00,0x00,
  18. 0x03,0x80,0x07,0x00,0x0E,0x00,0x00,0x00,0x07,0x00,0x0E,0x00,0x1C,0x00,0x00,0x00,
  19. 0x0E,0x00,0x1C,0x00,0x38,0x00,0x00,0x00,0x1C,0x00,0x38,0x00,0x70,0x00,0x00,0x00,
  20. 0x38,0x00,0x70,0x00,0xE0,0x00,0x00,0x00,0x70,0x00,0xE0,0x01,0xC0,0x00,0x00,0x00,
  21. 0xE0,0x01,0xC0,0x03,0x80,0x00,0x00,0x00,0xFF,0xF1,0xFF,0xE3,0xFF,0xC0,0x00,0x00,
  22. 0xFF,0xF1,0xFF,0xE3,0xFF,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  23. };



  24. void spi_transfer(volatile char data)
  25. {
  26.   SPDR = data;                    // Start the transmission
  27.   while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  28.   {
  29.   };
  30.   //return SPDR;                    // return the received byte
  31. }


  32. void hc138sacn(byte r){  //输出行线状态ABCD (A低,D高)
  33.     digitalWrite(RowA,(r & 0x01));
  34.     digitalWrite(RowB,(r & 0x02));
  35.     digitalWrite(RowC,(r & 0x04));
  36.     digitalWrite(RowD,(r & 0x08));
  37. }
  38.   
  39. void hc595senddata(byte data){// 高位在前  反相(1亮0灭)
  40. for (byte i=0; i<8;i++) {
  41.      digitalWrite(CLK,0);
  42.      if (data & 0x80) {
  43.          digitalWrite(R1, 0);     
  44.      } else {
  45.          digitalWrite(R1, 1);
  46.      }
  47.      data=data<<1;
  48.      digitalWrite(CLK,1);
  49. }

  50. }
  51.   
  52.   
  53. void setup () {

  54.     pinMode(RowA, OUTPUT);
  55.     pinMode(RowB, OUTPUT);
  56.     pinMode(RowC, OUTPUT);
  57.     pinMode(RowD, OUTPUT); //138片选
  58.     pinMode(hc138en, OUTPUT); //138 使能
  59.   
  60.     pinMode(R1, OUTPUT);//595 数据
  61.     pinMode(CLK, OUTPUT); //595 时钟
  62.     pinMode(STB, OUTPUT); //595 使能
  63.     pinMode(DATAIN, INPUT); //595 使能

  64.   
  65.      //digitalWrite(hc138d, HIGH);
  66.     Serial.begin(19200);

  67.     //SPI硬件设置
  68.     // SPCR = 01010000
  69.     //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  70.     //sample on leading edge of clk,system clock/4 rate (fastest)
  71.     SPCR = (1<<SPE)|(1<<MSTR);
  72.     delay(10);
  73. }
  74.   
  75. void loop () {
  76. if (Serial.available() > 0) {
  77. // read the incoming byte:
  78. row = Serial.read();

  79. // say what you got:
  80. Serial.print("I received: ");
  81. Serial.println(row, DEC);
  82. }

  83.   for(row=0;row<16;row++){

  84.       for (int i=0;i<8;i++){   
  85.          spi_transfer(~(zzz[i+row*8]));
  86.       }
  87.          

  88.       digitalWrite(hc138en, 1);  //关闭显示
  89.       hc138sacn(row);            //换行
  90.       digitalWrite(STB, 0);      //595刷新      
  91.       digitalWrite(STB, 1);
  92.       delayMicroseconds(500) ;   //节电用,
  93.       digitalWrite(hc138en, 0);  //开启显示

  94.       delayMicroseconds(500) ;  //刷新频率调,差不多60HZ,1/16间隔
  95.    
  96.   }  

  97. }
复制代码


从上面代码可以轻松的看出驱动原理并不复杂,其实就是把取模软件生成的字模,储存到一个数组里,然后调用arduino的硬件SPI通讯接口,把每8个LED看成是一个十六进制编码,然后一行一行的发送出去,发完一行后,再发出换行指令,就是这么简单。
置于16*16单个汉字取模显示,只要把主loop里的代码改为即可,其实就是简单的数学原理,把数组里的十六进制数按照一组一组提取显示而已~
  1.   for(row=0;row<16;row++){

  2.       for (int i=0;i<4;i++){//8片595
  3.          //硬件SPI  发送8字节耗时:22US         
  4.          spi_transfer(~(zzz[i*32+row*2]));  //硬件SPI      
  5.          spi_transfer(~(zzz[i*32+row*2+1]));  //硬件SPI        
  6.       }
复制代码


取模软件请选择横向顺序扫描~下载在附件哦~


下面就是小Z做的演示品~主控为Arduino Tiny~欢迎大家根据此来完成各种有趣的Ardunio点阵屏作品~希望此文能给大家拓宽一定的思维~







本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

评分

参与人数 2 +8 收起 理由
幻生幻灭 + 3 ZZZ 发帖,必属精品!
迷你强 + 5 好贴给力

查看全部评分

回复

使用道具 举报

发表于 2015-10-23 17:58:56 | 显示全部楼层
对楼上所有的楼主和访客表示感谢,提供了很多有用的资料。
我在此基础上实现了64*32LED阵列的显示,但是问题是用软件SPI刷新速度跟不上,屏幕呈闪烁状态。顾想通过软硬SPI一起执行,提高速率。但是失败了。用了硬件SPI就没法用软件SPI,用了软件SPI就没法用硬件SPI。(我对SPI通信不是很懂)望各位能不能提供好的方法提高刷新速度。

PS:刷 64 * 16 还算可以,可是64 * 32 就 不行了。

附上代码:
  1. int R1=11;
  2. int R2=9;
  3. int STR=10;
  4. int CLK=13;
  5. int EN=6;


  6. int dig0=2;
  7. int dig2=3;
  8. int dig4=4;
  9. int dig8=5;
  10. //int i,m;

  11. unsigned char jj,j;

  12. int down = 0;
  13. int row_ = 0;
  14. void setup()
  15. {
  16.   pinMode(R1,OUTPUT);
  17.    pinMode(R2,OUTPUT);
  18.   pinMode(STR,OUTPUT);
  19.   pinMode(CLK,OUTPUT);
  20.   pinMode(EN,OUTPUT);
  21.   pinMode(dig0,OUTPUT);
  22.   pinMode(dig2,OUTPUT);
  23.   pinMode(dig4,OUTPUT);
  24.   pinMode(dig8,OUTPUT);

  25. //Serial.begin(19200);

  26. //SPCR = (1<<SPE)|(1<<MSTR);
  27. //delay(10);

  28. }

  29. unsigned char zi[]={
  30. 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  31. 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  32. 0xFD,0xFE,0x1E,0x01,0xBF,0x7F,0x7F,0x7F,0xFD,0xFD,0xEF,0xFD,0xBE,0xFF,0x7F,0x7F,
  33. 0xF9,0xFB,0xF7,0xFB,0xBD,0xFF,0x7F,0x7F,0xFA,0xFB,0xFF,0xF7,0xBB,0xFF,0x6F,0x7B,
  34. 0x87,0x0D,0xFF,0xEF,0xB7,0xFF,0x70,0x07,0xEF,0xBE,0x1F,0xDF,0xAB,0xFF,0x7C,0x1F,
  35. 0xF7,0x7F,0xEF,0xDF,0x9D,0xFF,0x7E,0x3F,0xF7,0x7F,0xF7,0xBF,0xBD,0xFF,0x7C,0x1F,
  36. 0xF0,0x7B,0xF7,0x7F,0xBE,0xEF,0x7D,0xDF,0xF7,0x7D,0xEE,0xFF,0xBF,0x6F,0x7B,0xEF,
  37. 0xEF,0xBE,0x1E,0x01,0xBF,0xB0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  38. 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  39. 0xED,0xB7,0xFE,0xFF,0xFD,0xFF,0x90,0x07,0xE5,0x37,0xFF,0x7F,0xFE,0xFF,0xDF,0xF7,
  40. 0xF5,0xE0,0x40,0x01,0x80,0x03,0xFF,0xF7,0xC8,0x2F,0xDF,0xFD,0xBF,0xFB,0x60,0x37,
  41. 0xF1,0xCE,0xF8,0x07,0xF3,0x3F,0x6F,0xB7,0xCC,0x4E,0xFF,0xCF,0xE7,0xCF,0x6F,0xB7,
  42. 0xFB,0xF5,0xFF,0xBF,0x9F,0xE3,0x60,0x37,0xC0,0x75,0xFF,0x7F,0x3F,0xF9,0x6F,0xB7,
  43. 0xEE,0xF9,0x80,0x00,0xC0,0x07,0x6F,0xB7,0xEE,0xFB,0xFF,0x7F,0xFE,0xFF,0x60,0x37,
  44. 0xF1,0xF5,0xFF,0x7F,0xFE,0xFF,0x6F,0xF7,0xF0,0x4C,0xFF,0x7F,0xFE,0xFF,0x7F,0xF7,
  45. 0xCE,0x9F,0x78,0x7F,0x80,0x03,0x7F,0x87,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
  46. };

  47. void row1(int i)
  48. {
  49.         digitalWrite(dig0,(i&0x01));
  50.         digitalWrite(dig2,(i&0x02));
  51.         digitalWrite(dig4,(i&0x04));
  52.         digitalWrite(dig8,(i&0x08));
  53. }


  54. void spi_transfer(volatile char data)
  55. {
  56.   SPDR = data;                    // Start the transmission
  57.   while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  58.   {
  59.   };
  60.   //return SPDR;                    // return the received byte
  61. }

  62. void sendbyte(byte bbyte1){// 高位在前 反相(1亮0灭)
  63. for (byte i=0; i<8;i++) {
  64. digitalWrite(CLK,0);
  65. if ( bbyte1 & 0x80) {
  66. digitalWrite(R1, 1);
  67. } else {
  68. digitalWrite(R1, 0);
  69. }
  70. bbyte1= bbyte1<<1;
  71. digitalWrite(CLK,1);
  72. }

  73. }

  74. void sendbyte2(byte bbyte1){// 高位在前 反相(1亮0灭)
  75. for (byte i=0; i<8;i++) {
  76. digitalWrite(CLK,0);
  77. if ( bbyte1 & 0x80) {
  78. digitalWrite(R2, 1);
  79. } else {
  80. digitalWrite(R2, 0);
  81. }
  82. bbyte1= bbyte1<<1;
  83. digitalWrite(CLK,1);
  84. }

  85. }




  86. void loop()
  87. {
  88.         unsigned char row,m,k;
  89.        for(row=0;row<16;row++){
  90.          
  91.             for (int i=0;i<8;i++){
  92.                sendbyte(zi[i+down*8]);
  93.            }

  94. //          for(row=0;row<16;row++){
  95. //           
  96. //                for (int i=0;i<8;i++){   
  97. //                   //spi_transfer((zi[i+down*8]));
  98. //                }
  99.                
  100.               down++;
  101.                 digitalWrite(EN,1);
  102.                 row1(row);
  103.                 digitalWrite(STR,0);
  104.                 digitalWrite(STR,1);
  105.                 delayMicroseconds(0);
  106.                 digitalWrite(EN,0);
  107.                 delayMicroseconds(0);
  108.         }
  109.         
  110.          for(row=0;row<16;row++){
  111.          
  112.             for (int i=0;i<8;i++){
  113.                 sendbyte2(zi[i+down*8]);
  114.            }
  115.               down++;
  116.                 digitalWrite(EN,1);
  117.                 row1(row);
  118.                 digitalWrite(STR,0);
  119.                 digitalWrite(STR,1);
  120.                 delayMicroseconds(0);
  121.                 digitalWrite(EN,0);
  122.                 delayMicroseconds(0);
  123.         }
  124.         down = 0;
  125. }
复制代码
回复 支持 1 反对 0

使用道具 举报

发表于 2013-6-29 17:11:52 | 显示全部楼层
不错不错,我的就是stc的{:soso_e113:}
http://v.youku.com/v_show/id_XNDYyMzg1MjIw.html
现丑了
回复 支持 反对

使用道具 举报

发表于 2013-6-29 17:13:33 | 显示全部楼层
LZ几个屏哪里买的,喜欢那个小点的,我这个太大个头
回复 支持 反对

使用道具 举报

发表于 2013-6-29 17:21:36 | 显示全部楼层
其实我开始时候就是arduino控制的,2560 ,竟然忘了,后来改了stc,stc有点吃力,但是安装方便
http://v.youku.com/v_show/id_XMzk3NzMwNzg0.html


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2013-6-29 18:04:40 | 显示全部楼层
最大可以驱动多少点阵?
回复 支持 反对

使用道具 举报

发表于 2013-6-29 19:47:39 | 显示全部楼层
tingjie 发表于 2013-6-29 18:04
最大可以驱动多少点阵?

同问 分辨率64*128的可以驱动不?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-6-29 21:17:48 | 显示全部楼层
tingjie 发表于 2013-6-29 18:04
最大可以驱动多少点阵?

理论上arduino的刷新速度足够,稍微的改下代码中的行扫和列扫就行了~
回复 支持 反对

使用道具 举报

发表于 2013-6-30 10:17:11 | 显示全部楼层
可以滚屏么?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-6-30 11:50:25 | 显示全部楼层
pww999 发表于 2013-6-30 10:17
可以滚屏么?

基础程序放在这里了。。其他的随便自己加把~~~~
回复 支持 反对

使用道具 举报

发表于 2013-6-30 14:20:31 | 显示全部楼层
希望arduino越做越好
回复 支持 反对

使用道具 举报

发表于 2013-6-30 21:06:41 | 显示全部楼层
是不是不该放在这啊,如果惹LZ不高兴希望版主给删掉,继续问LZ,你的显示屏都是TB买的吗
回复 支持 反对

使用道具 举报

发表于 2013-7-2 07:52:44 | 显示全部楼层
不错。挺好的,希望arduino越做越好
回复 支持 反对

使用道具 举报

发表于 2013-7-2 11:24:46 | 显示全部楼层
楼主给个硬件链接呗、、、
回复 支持 反对

使用道具 举报

发表于 2013-7-2 18:16:21 | 显示全部楼层
楼主有原理图么?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-3 07:15:41 | 显示全部楼层
wangku001wei 发表于 2013-7-2 18:16
楼主有原理图么?

呃,等会我找找,应该有
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2022-10-8 06:58 , Processed in 0.051494 second(s), 32 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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