标签:
现有的驱动LED显示屏的资料,比较好的只有这个。但是它驱动的是08接口的室内显示屏,而我要驱动的是12接口的户外显示屏。两种屏幕的区别在于户外屏幕点阵比较稀疏,而且二者的扫描方式,驱动方式都不太一样。我花了一个下午才摸索出了它的使用方式,因此分享给大家,希望大家不必再绕弯路。
LED单元板使用的是5V的电源,但是它只提供了两个旋螺丝的地方供接电源。因此我们要进行如下焊接:USB公头的+,-接到导线的+,-。这样之后USB直接插入手机充电器/充电宝,导线链接到显示屏的电源上。
首先我们要知道12接口每个引脚的定义:
OE A
N B
N C
N CLK
N HS
N R
N G
GND D
接下来就是把它们连接到Arduino的引脚上了。我的库的默认设置如下:
const int A=2,const int B=3,const int CLK=12,const int STB=10,const int R=11,const int OE=9
当然,你也可以在库初始化的时候修改。
我自己写了一个库,代码如下:
#include <Arduino.h> #include "DotMatrix.h" class LEDScreenHelper { public: LEDScreenHelper(const int WIDTH=32, const int A=2,const int B=3,const int CLK=12, const int STB=10,const int R=11,const int OE=9): HEIGHT(16),WIDTH(WIDTH),A(A),B(B),SHCP(CLK),STCP(STB),DS(R),OE(OE){} void setup(){ pinMode(A,OUTPUT); pinMode(B,OUTPUT); pinMode(STCP,OUTPUT); pinMode(SHCP,OUTPUT); pinMode(DS,OUTPUT); pinMode(OE,OUTPUT); } void setRow(byte row){ digitalWrite(A,row&0x01); digitalWrite(B,row&0x02); } void sendColData(byte data){ for(int i = 0;i<8;++i){ digitalWrite(DS,(data&0x80)); data<<=1; digitalWrite(SHCP,0); digitalWrite(SHCP,1); } } void setOE(bool enable){ digitalWrite(OE, enable); } void display(DotMatrix &data){ for(int row = 0;row<4;++row){ digitalWrite(OE,0); for(int col = 0;col<WIDTH/2;++col){ byte val = data.get((12-((col&3)<<2)+row),(col>>2)); sendColData(~val); } setRow(row); digitalWrite(STCP,0); digitalWrite(STCP,1); digitalWrite(OE,1); } digitalWrite(OE,0); } private: const int HEIGHT,WIDTH; const int A,B,SHCP,STCP,DS,OE; };
其中需要#include "DotMatrix.h"如下:
#ifndef DOT_MATRIX #define DOT_MATRIX typedef unsigned char uchar; #define THROW(str) ; #define BYTE_LEN 8 #define CHECK_VAR(i,j) if((i)<0||(j)<0||(i)>=height||(j)>=width)THROW("Index out of Bound") #define POS(matrix,i,j) (*((matrix) + (i) * (width) + (j))) #define POS_BIT_GET(matrix,i,j) (POS((matrix),(i),(j)/BYTE_LEN) & (1<<(BYTE_LEN-(j)%BYTE_LEN-1))) #define POS_BIT_SET_TRUE(matrix,i,j) (POS((matrix),(i),(j)/BYTE_LEN) |= (1<<(BYTE_LEN-(j)%BYTE_LEN-1))) #define POS_BIT_SET_FALSE(matrix,i,j) (POS((matrix),(i),(j)/BYTE_LEN) &= (0xFF ^ (1<<(BYTE_LEN-(j)%BYTE_LEN-1)))) #define POS_BIT_SET(m,i,j,b) ((b)!=0)?POS_BIT_SET_TRUE((m),(i),(j)):POS_BIT_SET_FALSE((m),(i),(j)) /** * Remember: This class will only use `matrix` but NOT DELETE it */ class DotMatrix { public: DotMatrix(int w,int h,uchar *matrix, bool isNowClearMatrix=true): width(w),height(h),matrix(matrix){ if(isNowClearMatrix)clearData(); } DotMatrix(const DotMatrix &src){ Serial.println("DotMatrix copy construction - please avoid"); width = src.width; height = src.height; matrix = src.matrix; } ~DotMatrix(){} void clearData(){ memset(matrix,0,width*height*1); } inline void set(int i,int j,uchar val){ CHECK_VAR(i,j); POS(matrix,i,j) = val; } inline uchar get(int i,int j){ CHECK_VAR(i,j); return POS(matrix,i,j); } inline void setBit(int i,int jBit, bool b){ CHECK_VAR(i,jBit/8); POS_BIT_SET(matrix,i,jBit,b); } inline bool getBit(int i,int jBit){ CHECK_VAR(i,jBit/8); return POS_BIT_GET(matrix,i,jBit); } void fillTo(DotMatrix &fillTo, int xOffset, int yOffset, int scale){ this->fillTo(fillTo,xOffset,yOffset,scale,scale,0,0,width*BYTE_LEN,height); } /** * fill the rect [xSrcBeg,ySrcBeg,xSrcEnd,ySrcEnd] to `fillTo` by the `offset` and `scale` * @param The things by **bit** */ void fillTo(DotMatrix &fillTo, int xOffset, int yOffset, int xScale, int yScale, int xSrcBeg, int ySrcBeg, int xSrcEnd, int ySrcEnd) { for(int i = ySrcBeg;i<ySrcEnd;++i){ for(int j = xSrcBeg;j<xSrcEnd;++j){ for(int ii=0;ii<yScale;++ii){ for(int jj=0;jj<xScale;++jj){ //VAR_DUMP_INLINE(i);VAR_DUMP_INLINE(j);VAR_DUMP_INLINE(ii);VAR_DUMP(jj); fillTo.setBit(yOffset+(i-ySrcBeg)*yScale+ii, xOffset+(j-xSrcBeg)*xScale+jj, POS_BIT_GET(matrix,i,j)); } } } } } void print(){ for(int i = 0;i<height;++i){ for(int j = 0;j<width;++j){ for(int k = 7;k>=0;--k){ Serial.print((get(i,j) & (1<<k))!=0); } Serial.print(" "); } Serial.println(" "); } Serial.flush(); } int getWidth(){ return width; } int getHeight(){ return height; } uchar *getMatrix(){ return matrix; } private: int width,height; uchar *matrix; private: friend class DisplayHelper; }; #undef BYTE_LEN #undef POS #undef POS_BIT #endif
解释一下,DotMatrix这个类是一个二维矩阵的操作类,只要给它一个一维数组作为存储空间,它就可以模拟出一个二维的数组。这样可以减少Arduino上的内存分配与销毁。
#include <Arduino.h> #include "LEDScreenHelper.h" LEDScreenHelper helper; unsigned char data[4*16]; DotMatrix matrix(4,16,data); void setup(){ helper.setup(); for(int i = 0;i<16;++i){ for(int j = 0;j<4;++j){ matrix.set(i,j,i+j*16); } } } void loop(){ helper.display(matrix); }
例程如上。它的效果是把屏幕想象成一个左上角为(0,0)的坐标系,然后8个点(1byte)看成一块,每一块的0-3bit表示y坐标,4-5bit表示j坐标。
效果如下:
最新 Arduino 驱动 12接口/户外 LED显示屏/LED点阵屏/LED单元板
标签:
原文地址:http://www.cnblogs.com/turtlegood/p/4692534.html