#申请原创# @21小跑堂
除了各种单色的点阵屏之外,还有相应规格的全彩点阵屏,图1所示的就是一种P10规格的插灯式全彩点阵屏,其型号为P10(1R1G1B)16*16-D-SH,显示分辨率为16*16点。
图1 点阵屏外观
该点阵屏所采用的接口为HUB75接口,见图2所示。
图2 HUB75接口
该点阵屏在电路设计上方面主要由芯片SM16126D(12片)、74HC245D(2片)和74HC138D(1片)所构成。 该点阵屏所使用的串并转换芯片为SM16126D,其引脚的排列方式与DP5020相兼容,见图3所示。
图3 引脚排列
该芯片的工作时序见图4所示:
图4 工作时
在工作方式上,该点阵屏与常规点阵屏的最大区别在于,它不是采用1/16的扫描方式,而是采用1/4的扫描方式,并采用蛇形方式,共分为上下2路进行控制。 由图5可知,这里所说的2路含义在于其每路输入信号只负责上或下8行的显示输出。
图5 工作时序
而1/4扫则是指它只有4个行扫描地址,也就是说1个行地址要控制2个显示行。 至于蛇形扫描方式就更奇特了,它在扫描输出时并非超着一个固定的方向,而是在不同的行沿着不同的方向,这就为编程设计增加了复杂的难道。 如果这样说你还不明白的话,可以参照图6所示来了解,该图案是向4个行地址都输出值同一个值0xF0CC00FF来实现。 图6 输出内容
那为什么会形成这样的结果呢? 由表1的数据排列方式即可看出其扫描输出的轨迹。
表1 数据排列及扫描方向
为驱动该点阵屏,所使用的是N76E003最小系统开发板,它与开发板的连接关系为: A --- P0.0 B --- P0.1 G1 --- P1. 4 G2 --- P1. 5 EN --- P0.5 STB--- P0. 6 CLK--- P0. 7 所作的相应定义如下: sbit LA=P0^0; sbit LB=P0^1; sbitLSCL=P0^7; sbitLSTB=P0^6; sbit LG1=P1^4; sbit LG2=P1^5; sbit LEN=P0^5;
实现图6所示效果的主程序为: void main (void)
{
Set_All_GPIO_Quasi_Mode;
set_CLOEN;
ScanRow=0;
while(1)
{
Display();
delay_us(100);
}
}
所涉及的相关函数有:SeleRow()、SM16126OutByte()及Display() 扫描点阵输出函数: void SeleRow(UINT8 d)
{
UINT8 n=d;
n=d%4;
LA=(n&0x01)>0 ?1:0;
LB=(n&0x02)>0 ?1:0;
}
串行数据发送函数: void SM16126 OutByte(void)
{
UINT32 dat=0xF0CC00FF ;
UINT8 i=0 ;
for(i=0;i<32;i++)
{
LSCL=0;
if(dat&0x80000000)
{
LG1=1;
}
else
{
LG1=0;
}
dat=dat<<1;
LSCL=1;
}
}
输出显示函数: void Display(void)
{
LEN=1;
LSTB=1;
LSTB=0;
SM16126 OutByte ();
SeleRow(ScanRow);
LEN=0;
ScanRow++;
if(ScanRow>3) ScanRow=0;
}
有了前面显示的基础,就可以着手解决汉字的显示问题了。
当依序输出数据0xF0CC00FF、0x0FCCFF00、0xFC0C00FF、0xFCC00F0F时,其输出效果如图7所示。 图7 显示效果
经分析可以发现,数据0xF0CC00FF被显示在第2行和第6行,数据0x0FCCFF00被显示在第3行和第7行,其它以此类推,也就是说向地址0发送的数据并没有显示在第1行。此外,向地址3所发送的数据0xFCC00F0F则被显示在第1行和第5行。
以显示“枫”字为例,可通过工具软件以图9的格式来提取字模。 图8 显示效果
图9 字模提取格式 所提取的字模则存放在数组中,其存储形式为: UINT8 code t[]={ 0x20,0x00,0x23,0xF8,0x22,0x08,0x22,0x08,0xFB,0x28,0x22,0xA8,0x22,0xA8,0x72,0x48, 0x6A,0x48,0xA2,0xA8,0xA2,0xA8,0x23,0x2A,0x24,0x0A,0x24,0x0A,0x28,0x06,0x30,0x02,/*"枫",0*/ }; 接下来需要解决的问题有: 1)方向问题 2)位置问题 3)间隔问题 4)调序问题 5)多彩处理 1. 方向问题 由于字模的提取是按固定模式来处理,因此蛇形的扫描方式是很难用一种定向的方式来读取字模的,需要利用正反2个读取函数来处理蛇形扫描。
正向扫描函数: void Z_OutByte(UINT8 dat1, UINT8 dat2)
{
UINT8 i=0 ;
for(i=0;i<8;i++)
{
LSCL=0;
if(dat1&0x80)
{
LG1=1;
}
else
{
LG1=0;
}
if(dat2&0x80)
{
LG2=1;
}
else
{
LG2=0;
}
dat1=dat1<<1;
dat2=da2<<1;
LSCL=1;
}
}
反向扫描函数: void F_OutByte (UINT8 dat1, UINT8 dat2)
{
UINT8 i=0 ;
for(i=0;i<8;i++)
{
LSCL=0;
if(dat1&0x01)
{
LG1=1;
}
else
{
LG1=0;
}
if(dat2&0x01)
{
LG2=1;
}
else
{
LG2=0;
}
dat1=dat1>>1;
dat2=dat2>>1;
LSCL=1;
}
}
2.位置调整
由于蛇形扫描的原因,本应在同一行的数据被放置在了不同的行,因此在输出数据时需对输出数据的实现加以调整,具体的变化见图10所示。 图10 交换数据顺序
3.间隔问题 由于一个地址的数据会被输送到2行来显示,且间隔了3行。因此在显示时,需要按显示要求来调整输出数据的位置。
例如地址0的数据被显示在第2行和第6行,地址1的数据被显示在第3行和第7行,因此要正确地显示地址0的内容就需把第6行的数据放到第3行的地址上,具体的交换关系如图11所示。 图11交换数据位置
4.调序问题 若按0~3的顺序来输出数据,则显示的数据分别位于2、6、3、7、4、8、1、5行,其显示效果如图12所示。
为完成显示要求的,需通过相应的函数来解决调序问题。 图12 显示效果
解决调序的函数为: void SeleRow(UINT8 d)
{
UINT8 n=d;
if(d==0) n=3;
if(d==1) n=0;
if(d==2) n=1;
if(d==3) n=2;
n=n%4;
LA=(n&0x01)>0 ?1:0;
LB=(n&0x02)>0 ?1:0;
}
修改后的汉字显示函数为: void Display(void)
{
UINT16 d,n;
UINT8 p;
LEN=1;
LSTB=1;
LSTB=0;
n=ScanRow/2;
d=ScanRow*2;
p=d;
F_OutByte(t[p],t[p+16]);
p=8+d;
Z_OutByte(t[p],t[p+16]);
p=1+d;
F_OutByte(t[p],t[p+16]);
p=8+1+d;
Z_OutByte(t[p],t[p+16]);
SeleRow(ScanRow);
LEN=0;
ScanRow++;
if(ScanRow>3) ScanRow=0;
}
在解决以上问题后,通过使用函数Display() 即可达到图8所示的显示效果。 5.多彩处理 若将G1和G2的输出信号连接到B1和B2或是连接到R1和R2则可得到图13所示的效果。
若感兴趣的话,还可以增添色彩控制函数以实现多种色彩的显示。 图13 显示效果
至此就完成了该点阵屏的显示驱动,当然在扩充字库的情况下,就可实现更多内容的显示。此外,还可为其添加滚动显示效果等。
|