【简介】
本工程是基于HK32F103CBT6的双色LED点阵学习板,能够完成以下功能:
1.静态显示文字(程序已完成)
2.左移显示(程序待开发)
3.点阵书写(程序已完成)
4.灰度显示(程序待开发)
5.点阵时钟(程序待开发)
————————————————————————————————————————————————————————————
————————————————————————————————————————————————————————————
【硬件】
硬件整体结构如图所示:
整个电路结构其实还是比较简单的,主要部分是HK32最小系统和LED点阵
下面重点讲一下LED点阵部分的电路:
本设计中的16*32点阵由8块8*8共阳极点阵组成
LED点阵通常采用动态行列扫描来进行驱动,即按照顺序逐行显示,由于人眼的视觉暂留现象,
当扫描速度足够快的时候看起来画面就是静止的。
行扫描电路通常采用译码器来实现,因为某一个时刻只有一行是被选中的。
本设计中点阵的行数为16,所以需要使用4-16译码器,但是为了方便布线,并没有直接使用4-16译码器
而是采用两片3-8译码器级联,具体型号为74HC1 3 8。
由于1 3 8译码器输出有效电平为低电平,且输出能力不够,所以需要使用PMOS来进行反相及电流放大:
为了实现全局亮度调节还加入了PWM调光电路:
LED点阵的列驱动通常采用大家熟悉的74HC595串转并芯片,但是该芯片并非专门为LED点阵设计的,
当每一行的点亮数量不同时会出现亮度不均匀的现象,所以这里我改用了M B I 5024这款芯片,
它能够实现16通道的可编程恒流输出,亮度均匀,一致性好。同时它自带反相,很适合共阳极点阵:
其余电路均为常见设计,在此不做赘述。
————————————————————————————————————————————————————————————
————————————————————————————————————————————————————————————
【软件】
1.静态显示
前面提到LED点阵的驱动是通过行列扫描来实现的,整个过程并不复杂
首先需要在程序中建立一个二维数组作为显示缓存,与点阵的行列分别对应,
在扫描到某一行的时候将该行的数据发送出去再显示一小段时间就可以了,
只要扫描的速度够快,人眼看到的画面就是静止的了。
具体程序如下:
void Display()
{
char i,j;
EN = 1; //
关显示
for(i=0;i<16;i++) //
行扫描循环
{
Scan(i); //
行扫描
for(j=0;j<2;j++) //
列扫描循环,每次发送4字节数据
{
SendByte(Red_Buff[i][j*2]
,Green_Buff[i][j*2]);
SendByte(Red_Buff[i][j*2+1]
,Green_Buff[i][j*2+1]);
}
LT = 1; //
发送时钟让数据移出
LT = 0;
EN = 0; //
显示一小段时间
delay_us(50);
EN = 1;
}
}
显示效果如下图:
——————————————————————————————————————————————————
2.点阵书写
LED点阵书写显示屏其实是很多年前一次电赛的题目,其实现原理并不复杂。
当我们把Pen(这个字中文违规了)放在点阵屏上,只要能够检测到Pen所在的位置,然后将对应位置的LED点亮即可。
那么,怎样才能够检测到Pen所在的位置呢?
首先,需要一支特殊的Pen:当它检测到一定强度的光照时,会输出一个信号。
光Pen电路如下图所示:
光敏元件使用3DU5C光敏三极管,响应速度更快。无光照情况下比较器同相电压比反相高,输出高电平,
当光敏三极管检测到LED点亮后导通,E极由低电平变为高电平,比较器输出极性反转,输出信号给单片机。
检测位置则可以使用扫描的方式来实现:
首先从上到下逐行点亮该行的所有LED,如果在点亮某一行的时候光Pen输出了信号,则说明光Pen在这一行,
这样就知道光Pen的Y轴坐标了,此时再从左到右逐个点来点亮这一行的LED,
当光Pen检测到时,就确定了X轴坐标了。
扫描示意见GIF图:
通过这样的方式获取到光Pen所在的位置后,再将对应的LED点亮就可以实现LED点阵书写了。
需要注意的是,再扫描获取光Pen位置的时候会点亮很多点,如果扫描的时间和正常显示的时间一样的话,
肯定就区分不出来哪些点是点亮的,所以需要在程序中控制扫描时间和显示时间的比例,
当扫描时间比显示时间少很多的时候,扫描时候的亮度就不如正常显示的时候了,这样就能区分出扫描和正常显示了。
获取光Pen坐标的程序如下:
u16 GetPos()
{
u16
i=0,j=0;
u16
pos=0x0000;
LT = 1;
SendByte(0xff, 0x00); //
一行红色全亮
SendByte(0xff, 0x00);
SendByte(0xff, 0x00);
SendByte(0xff, 0x00);
LT = 0;
EN=0;
//
行扫描之前先开显示
while(i<16)
{
Scan(i);//
扫描某一行
delay_us(20); //
延时一小段时间
if(PEN == 1) {PEN = 0; EN = 1; break ;}//
扫描到了光Pen,关显示,退出行扫描
i++;
}
if(i==16)
{PEN = 0; EN=1; return 0xffff;}//16
行都没有扫描到光Pen,关显示退出扫描
EN=0;//
列扫描之前先开显示
while(j<32)
{
Scan_Col(j);
delay_us(20); //
延时一段时间,不然检测不到
if(PEN == 1)
{
delay_us(30);
if(PEN == 1) {PEN = 0; EN = 1; break ;}//
扫描到了光Pen,关显示,退出列扫描
}
j++;
}
if(j==32)
{PEN = 0; EN=1; return 0xffff;}//32
列都没有扫描到光Pen,关显示退出扫描
EN = 1;//
正常扫描结束之后,关显示
pos =
(i<<8) | j;//
计算坐标
return
pos;
}
实际书写效果如下图:
上图演示的是点亮模式,如果不小心写错了则需要使用点灭模式,原理类似。
——————————————————————————————————————————————————
3.待续。
由于本次训练营时间有限,仅完成两个DEMO程序,灰度显示和时钟后续会抽时间完成并更新。
————————————————————————————————————————————————————————————
————————————————————————————————————————————————————————————
【实物照片】
————————————————————————————————————————————————————————————
————————————————————————————————————————————————————————————
【源码】
代码见附件
!注意:请使用浏览器自带下载,迅雷等下载软件可能无法下载到有效资源。
欢迎加入EEWorld参考设计群,也许能碰到搞同一个设计的小伙伴,群聊设计经验和难点。 入群方式:微信搜索“helloeeworld”或者扫描二维码,备注:参考设计,即可被拉入群。 另外,如您在下载此设计遇到问题,也可以微信添加“helloeeworld”及时沟通。
EEWorld Datasheet 技术支持