led点阵书写点阵式led显示屏方案,光敏元件怎么实现对点阵屏上某点位置的确定?

自我控制的LED照明灯~发光二极管同时作为光敏二极管实验|创意DIY - 数码之家
查看完整版本: [--
&Pages: ( 6 total )
赞助商链接
首先大家都知道,LED有一个最明显的特性就是电致发光效应,说白了就是给LED通电,它就会发光但是不要忘了,LED本质上还是一个半导体二极管,有一个PN结我记得书上说过,PN结有一个很有意思的特性,就是很容易受到光线的“干扰”即当太阳光或其他光照射半导体的PN结时,就会在PN结的两边出现电压,前辈们给它起了个名字叫做光生伏打效应于是,光敏二极管、光敏三极管的出现替代了笨重娇气的光电管,更有甚者,把二极管做成片状追求光生伏打效应的最大化,叫做太阳能电池 既然LED能把电能转化成为光能,那么能不能也把光能转化成为电能呢?为了测试不同LED的光伏效应,对不同种类LED进行了粗略的测试 测试条件:2015年3月,天气:晴;时间:13:00;地点: 朝南阳光充足的房间分别于阳光直射下和室内环境进行测试,看看不同种类LED的光伏效应如何 首先是最普通的红色5mmLED室内环境下有33.1mV光生电压产生[attachment=5528382]这是放在窗口阳光直射下,输出暴涨,达到775mV[attachment=5528383] 普通5mm黄色LED,室内环境光生电压54mV[attachment=5528385] 阳光直射下光生电压1.465V[attachment=5528384] 普通5mm绿色LED,室内环境光生电压26mV[attachment=5528386] 阳光直射下光生电压1453mV[attachment=5528387] 最后来一个BOSS的,5W白光LED,内部是4颗核心两并两串阳光直射下能够产生4.61V的光生电压![attachment=5528381] 上面看了这么多,那么是不是LED就可以当太阳能电池用了呢?答案是否定的,太阳能电池追求的是尽可能高的光-电转换效率,输出较大的功率LED在这一点上是远远赶不上的,以刚才那颗在阳光直射下产生4.61V光生电压的5WLED来说产生的电流只有区区1mA不到。伟大领袖毛主席教导我们说:一切事物无不具有两重性,既然LED不能做太阳能电池,那做个光敏穿感器还是可以的 正好想到光控路灯,这种灯天亮就灭,天黑就亮其原理往往是利用光敏元件去控制照明电路而现在有这样一种元件,这种叫做发光二极管的元件通电会发光,遇光会发电那换一种方式,能不能让这个元件在照明的同时又能兼容光敏传感器,自己控制自己呢?伟大领袖毛主席继续教导我们说:任何新生事物的成长都是要经过艰难曲折的目标很简单:1、有光就灭,没光就亮&&&&&&&&&&&&2、LED既做光-电元件,又做电-光元件 经过反复试验,终于设计出了自我控制的LED电路说干就干,开始制作电路采用2颗非常常见的集成电路NE555和LM311还有少量电阻、电容等这次用洞洞板进行电路的搭建,懒得画板腐蚀了[attachment=5528497][attachment=5528516][attachment=5528498] [attachment=5528500] [attachment=5528499] 插上LED试试,LED采用插座,这样可以测试不同种类的LED[attachment=5528501] 基本完工[attachment=5528502] [attachment=5528503] [attachment=5528504] 最终做好的成品,可调电阻用于调整电路灵敏度[attachment=5528515][attachment=5528518][attachment=5528519] 电路设计采用5V供电,正好充满电的4.8V镍氢电池组输出大约5.5V用在这里非常合适[attachment=5528511] 出乎意料,测试一次成功这是昨天晚上测试的情况在环境黑暗条件下,LED自动点亮了[attachment=5528513]而用手电筒照射LED,自动熄灭了[attachment=5528512][attachment=5528514] 上午再次进行测试,地点:北京 朝南的房间内;天气:阴;首先是高亮绿色LED,在白天时LED不发光[attachment=5528520]用手遮挡,立刻亮了[attachment=5528521] 其次是草帽白光LED[attachment=5528522][attachment=5528523] 还有之前测试的黄色LED[attachment=5528525][attachment=5528524] 这是红色高亮LED[attachment=5528549][attachment=5528526] 测试还有很多,就不传上来了红的、黄的、绿的、蓝的、白的这些管子都能很好的工作甚至红外管和紫外管也可以实现自控!(用相机拍)当然,由于不同颜色的LED采用的半导体材料不同,因此它们的光伏特性也是不一样的就像上面测试,同样在直射阳光下,红色LED和黄色LED输出电压就不一样还有就是从测试表现看,LED的光伏特性曲线似乎很陡峭,而且对弱光的敏感度很低表现最好的应该是高亮红光LED,弱光下敏感度较其余高蓝色、白色最差,必须要很强光线照射才能关闭还有就是草帽管灵敏度比较低,估计是因为没有透镜的缘故而普通5mmLED因为有透镜,因此对直射光线灵敏度都较好,但对漫反射光线灵敏度就较差了 [attachment=5534923]
具体电路原理分析及电路图请见1楼
赞助商链接
下面上电路图[attachment=5528964] 图中间部分,NE555和100K电阻及0.1uF电容组成了单稳态电路该电路处于稳态是3脚输出低电平,LED不发光当被2脚输入的低电位触发时,3脚输出高电平,LED发光 图左半部分,LM311组成的电压比较器,电位器的作用是为了调整LM311反向输入端的基准电压同相输入端负责检测LED上产生的光生电压 系统上电时,LED不发光,此时LM311会将LED上的光生电压和基准电压比较当环境较暗时,LED端光生电压较低,当低于基准电压时,LM311的7脚输出低电平触发NE555,NE555进入暂态,LED发光,此时LED两端电压为工作电压,绝对高于基准电压LM311输出高电平,不会继续触发待暂态结束,NE555翻转,LED熄灭,此时LED端电压为光生电压,LM311继续比较,如果光生电压低于基准电压,则输出低电平继续点亮LED反之如果环境较亮,光生电压高于基准电压,LM311不会触发NE555,LED也就不会点亮实际工作中,单稳态电路的暂态时间为t=1.1RC=1.1×100K×0.1u=0.011s,LED实际上是一直在闪烁但是由于人眼的余晖效应,所以看起来LED是一直亮着的 PS:细心的兄弟一定会发现,这个电路的工作原理和白菜白光T12烙铁的工作原理是一样的&&&&白菜T12的电路稍稍改动些参数也可以做成自控LED
有兄弟说可以用红外接收管当作太阳能电池来用这个理论倒是头一次听说,那就试一下一颗5mm红外光敏二极管在正午阳光直射下,只有1mV电压产生[attachment=5534906] 还有就是有人说LED既然有光伏效应,那么能产生多大电流呢?这是那颗5W白光LED,正午阳光直射下可以产生4.54V电压[attachment=5534900]但是电流不行啊,只有几个uA[attachment=5534898] 普通高亮绿色LED可以产生1.57V电压[attachment=5534903]但是电流一样小的可怜[attachment=5534901]黄色的也好不到哪去 [attachment=5534904][attachment=5534905]
所以,用LED做太阳能电池就别想了,在照明的同时,业余兼职光敏二极管还是可以的 完
赞助商链接
很好的文章,这好好编辑一下,增加点原理介绍,支持楼主申精啊!
不知道LED还有这样的功能,楼主威武
简单实用精辟,求原理图,不知道器件好不好找
思路非常好,手工也不错,上个电路图更好。
我记得前年买了几个红外光控想改灯,一直没动手,白买了
楼主威武!无论实用性如何,这都是一个创造性的思路。lm311比较led电压,控制555双稳态翻转?
好东西 真心没想到还有这种用法我试试用在单片机上去lz的是用电压比较的原理吧 想不出lz的电路图....放出电路图吧
之前好像有个手写LED点阵&&用LED小草帽可以进行手写(说是手写,其实就是给光,进行开关某一个点)&&应该就是这个原理吧
謝謝分享,好思路,真想做个试试!
这个很神奇&&电路图
简单实用精辟,求原理图
拓展思路探究实验的好文章
我想知道LED是怎么熄灭的?T12白光的控制原理?
很巧妙的想法,可惜没有原理图
待机功耗有多大
看起来很厉害
这个很新奇
支持楼主的创意
楼主水平很牛啊
好创意 能上个测试视频就好了
以前也看到过用LED做光敏元件一直不知道其原理
与众不同的思路,学习了,用lm358来做应该也可以吧?
内容设计的奇妙,我还在想会不会自己发光也要触发
:与众不同的思路,学习了,用lm358来做应该也可以吧?&( 16:20)&当然可以,358做的白菜白光电路就行啦
间隙检测,555一旦触发就强制输出,直到6脚高电平,电容快速放电复位,再次等待检测触发,把每一个元件摸透确实很有必要
很棒 值得加分 可惜只能3分
優秀文章,认真学习了
没LM311,还有其它办法可以做吗
以前有人用红外接收管并联晒太阳, 为碱性电池充电的.
有营养,收藏了
建议楼主试一下红外接收管,电子报曾讨论也有人用几十颗红外接收管成功自制太阳能充电器。
優秀文章,楼主的电子技术真是高大上啊。
很精彩的自我取样控制电路,绝对值得借鉴效仿。谢谢分享。
简单实用精辟
长知识啦&&&&&&&&&&&& 字数补丁
LZ牛!!!这都弄出来了.
神一样的人物,实用性怎么说
楼主想法很独特啊,有创意
必须点一百个赞,从来没想过还能这么玩
LED照明灯~发光二极管同时作为光敏二极
为了检测LED两端的电压,还要一个单稳态电路,这个有点不值得。555的价格比LED贵吧。
311跟358有什么区别
谁说一芯不可二用
楼主高手,膜拜中!这电路很实用。
创意好啊!技术高。
要是核心面积能达到太阳能电池板的面积。。。。嘿嘿,发电也是可以滴
这样的话LED显示屏就可以做成发电系统了。
:与众不同的思路,学习了,用lm358来做应该也可以吧? ( 16:20) 理论上讲,是可以的。用358中的一个运放做成振荡器代替555,另一个仍然做比较器,这样就和楼主给出的图原理相同了
查看完整版本: [--
Powered by
Time 0.070897 second(s),query:5 Gzip enabled 上传我的文档
 下载
 收藏
粉丝量:30
该文档贡献者很忙,什么也没留下。
 下载此文档
LED点阵书写显示屏资料
下载积分:900
内容提示:LED点阵书写显示屏资料
文档格式:PDF|
浏览次数:199|
上传日期: 06:02:14|
文档星级:
全文阅读已结束,如果下载本文需要使用
 900 积分
下载此文档
该用户还上传了这些文档
LED点阵书写显示屏资料
关注微信公众号手写点阵屏的设计原理是什么
手写点阵屏的设计原理是什么
提问者采纳
33人见人爱
手写点阵屏是完全集成的混合信号系统级芯片,具有与8051兼容的微控制器内核,与MCS-51指令集完全兼容。其内部还集成了数据采集和控制系统中常用的模拟部件和其他数字外设及功能部件,并包括A/D和D/A模块,执行速度快,功能强大。  光笔选用光敏电阻作为感应器件,根据光敏电阻的光电特性,光敏电阻两瑞电压因光电阻的变化而变化。电压值经电压比较器LM324比较后可输出高/低电平。光电特性非线性易调节,且灵敏度较好。  LED与数码管同步使用,LED用于功能指示灯,数码管用于32×32点阵LED模块书写显示屏当前光笔所在的行/列坐标值。  点阵用微亮的光进行扫描,光笔用来感应。当光笔感应到光时,通过程序可获当前点阵光对应的坐
你好,很高兴为你解答。点阵手写屏主要由三个部分组成:行扫描电路、列扫描电路、光笔检测电路,光笔里面安装了一个光敏传感器,用来检测点阵上点的状态。同时还要有LED点阵书写显示屏,检测精度要求高且数据存储量大,选择适合的控制模块,能确保其快速是实现稳定及达到系统要求的基本条件。其实就是通过电路控制屏幕。
点阵内部结构及外形,8X8点阵共由64个发光二极管组成,且每个发光二极管是放置在行线和列线的交叉点上,当对应的某一行置1电平,某一列置0电平,则相应的二极管就亮;如要将第一个点点亮,则9脚接高电平13脚接低电平,则第一个点就亮了;如果要将第一行点亮,则第9脚要接高电平,而(13、3、4、10、6、11、15、16)这些引脚接低电平,那么第一行就会点亮;如要将第一列点亮,则第13脚接低电平,而(9、14、8、12、1、7、2、5)接高电平,那么第一列就会点亮。 &一般我们使用点阵显示汉字是用的16*16的点阵宋体字库,所谓16*16,是每一个汉字在纵、横各16点的区域内显示的。也就是说得用四个8*8点阵组合成一个16*16的点阵。如
led点阵屏如何滚动显示,以及滚动的原理,比如向左滚动显示,说说是怎么实现的,求指导啊
LED点阵屏的规格书主要有哪些内容?
关于双色LED点阵屏74HC244 74HC245 的问题?
自己做的16*128的LED点阵屏,总是闪烁,字体显示不完整!
用zigbee模块能直接驱动LED点阵屏么
铂翼急速手写王是根据什么原理制作的
手写屏的原理是什么?
手写臂的工作原理,哪位大神能解释一下?
叶镇造手写签名设计
电容笔的原理是什么?电容屏手写笔的价格怎么样吗?深圳有哪...
手写板与触摸屏原理上讲是一回事么?
平米装修报价专题
上海,55平米,装修,预算表,开间
石家庄,188平米,装修,报价表
西安,198平米,装修,报价表
石家庄,128平米,装修,报价单,3居
哈尔滨,130平米,装修,报价单,4居
装修预算专题
装修问答专题
一起装修网作为首家上市的互联网装修服务平台,为大家提供家装保障、主材品质保障、零增项保障、施工质量保障、施工延期保障、售后投诉保等家装相关保障。一起装修网全国一站式装修服务平台
7年服务过7000万用户
全国16家分公司
A轮融资2亿,成功登陆新三板
70%客户来自口碑介绍
通过以上信息希望您已获取到您关心的:手写点阵屏的设计原理是什么问题的信息。
http://www.17house.com/sb/jzsjwenda/207f79a30dd07a06.html|手写点阵屏的设计原理是什么&&|&& &&|&& &&|&&
LED点阵屏学习攻略
21:28:44 && 阅读:76425&&
LED点阵屏学习攻略
在经历了将近一个学期断断续续的点阵屏学习后,最后终于在AVR平台下完成了128*32点阵屏的无闪烁显示。现把整个学习过程总结如下:
无论是51单片机还是AVR单片机,点阵屏的显示原理是一样的,所以首先从51讲起。
说明:以下所有试验如无特殊说明均在Keil uVision3 + Proteus 6.9 SP5下仿真完成。
一.基于51的点阵屏显示:
(1)点亮第一个8*8点阵:
&&&& 1.首先在Proteus下选择我们需要的元件,AT89C52、74LS138、MATRIX-8*8-GREEN(在这里使用绿色的点阵)。在Proteus 6.9中8*8的点阵总共有四种颜色,分别为MATRIX-8*8-GREEN,MATRIX-8*8-BLUE,MATRIX-8*8-ORANGE ,MATRIX-8*8-RED。
在这里请大家牢记:红色的为上列选下行选;其它颜色的为上行选下列选!而所有的点阵都是高电平选中列,低电平选中行!也就是说如果某一个点所处的行信号为低,列信号为高,则该点被点亮!此结论是我们编程的基础。
&& 2.在选择完以上三个元件后,我们开始布线,具体如下图:
这里P2是列选,P3连接38译码器后作为行选。
选择38译码器的原因:38译码器每次可输出相应一个I/O口的低电平,正好与点阵屏的低电平选中行相对,并且节省了I/O口,大大方便了我们的编程和以后的扩展。
3.下面让我们把它点亮,先看一个简单的程序:
(将奇数行偶数列的点点亮,效果如下图)
下面是源代码:
/************8*8LED点阵屏显示*****************/
#include&reg52.h&
void delay(int z) //延时函数
&&&&&& int x,y;
&&&&&& for(x=0;x&z;x++)
&&&&&&&&&&&&& for(y=0;y&110;y++);
void main()
&&&&&& while(1)
&&&&&&&&&&&&& P3=0;&&&&&&&&&&&& && //行选,选择第一行
&&&&&&&&&&&&& P2=0x55;&&&&&& &&&&& //列选,即该行显示的数据
&&&&&&&&&&&&& delay(5); &&&& //延时&
&&&&&& /*****下同*****/
&&&&&&&&&&&&& P3=2;&&&&&&&&&&&& //第三行
&&&&&&&&&&&&& P2=0x55;
&&&&&&&&&&&&& delay(5);
&&&&&&&&&&&&& P3=4;&&&&& & &&& &//第五行
&&&&&&&&&&&&& P2=0x55;
&&&&&&&&&&&&& delay(5);
&&&&&&&&&&&&& P3=6;&&&&&&&&&&&& & //第七行
&&&&&&&&&&&&& P2=0x55;
&&&&&&&&&&&&& delay(5);
&&&&&& }&&&&
上面的程序实现了将此8*8点阵的奇数行偶数列的点点亮的功能。重点让我们看while循环内,首先是行选P3=0,此时38译码器的输入端为000,则输出端为,即B0端为低电平,此时选中了点阵屏的第一行,接着列选我们给P2口赋0x55,即,此时又选中了偶数列,紧接着延时。然后分别对第三、五、七行进行相同的列选。这样就点亮了此点阵屏奇数行偶数列交叉的点。
完成这个程序,我们会发现其实点阵屏的原理是如此简单,和数码管的动态显示非常相似,只不过换了一种方式而已。
4.完成了上面的点亮过程,下面我们让这个8*8的点阵屏显示一个汉字:&明&
先看效果图:
源代码如下:
/************8*8LED点阵屏显示*****************/
#include&reg52.h&
char code table[]={0x0f,0xe9,0xaf,0xe9,0xaf,0xa9,0xeb,0x11}; //&明&& 字编码
void delay(int z) //延时函数
&&&&&& int x,y;
&&&&&& for(x=0;x&z;x++)
&&&&&&&&&&&&& for(y=0;y&110;y++);
void main()
&&&&&& while(1)&& //循环显示
&&&&&&&&&&&&& &for(num=0;num&8;num++)&&&&&&& //8行扫描 P3行选,P2列选
&&&&&&&&&&&&& {
&&&&&&&&&&&&& & P3=&&&&&&&&&&& & //行选
&&&&&&&&&&&&& & P2=table[num];&& //列选
&&&&&&&&&&&&& & delay(5);&&&&&&&&&&& //延时
&&&&&&&&&&&&& }
&&&&&& }&&&&
因为要显示一个汉字,这里我们使用了一个数组table[ ]来存储该字的编码,重点还是来看while循环,首先在for循环内完成对8*8点阵屏的8行依次扫描。我们来分析第一行的情况即num=0的时候,首先P3=0,选中第一行,然后P2=table[0],即P2等于table数组中第一个数据0x0f,则此时就点亮了第一行相应的点。接着延时,其他行同理。这样我们就完成了一个最简单汉字的显示。
(2)16*16点阵的显示原理
1.虽然完成了上面8*8点阵的显示,但是由于点的数量太少以至于它的显示效果并不是很理想,事实上现在大部分点阵的汉字都是16*16显示的,下面让我们来学习16*16点阵的显示。和上面一样我们先选择元件:AT89C52,74LS138,,MATRIX-8*8-GREEN,因为要显示16*16的汉字,我们就不能再使用一个38译码器进行行选了,这里我们用两个38译码器组合成一个4选16的译码器(当然也可以使用74159)。而MATRIX-8*8-GREEN点阵需要4个。完成后如下图:
2.先来看看4选16的译码器是如何工作的,这里有4个输入端a、b、c、d,16个输出端H0~H15,如上图连线后即可完成类似于38译码器一样的工作。只不过扩展到了16行选。关于连线的原理这里不再赘述,只要明白38译码器的原理这个可以轻松理解。接着完成全部布线。如下图所示:
3.连好线后,P1作为行选,P2、P3一起作为列选。现在16*16的点阵被分成两块并不完整的部分,我们可以整体移动(包括点阵屏、连线以及连接点,)来方便我们观察显示的效果(最好同时去掉仿真中电平的指示灯)。接着我们来看一个程序,还是让此点阵屏显示一个汉字:&明&。
先看效果图:
源代码如下:
/************16*16LED点阵屏显示*****************/
#include&reg52.h&
char code table[]={0x00,0x20,0x20,0x7F,0x7E,0x21,0x22,0x21,
&&&&&&&&&&&&&&&&&&&& &&& 0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21,
&&&&&&&&&&&&&&&&&&&& &&& 0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21,
&&&&&&&&&&&&&&&&&&&& &&& 0x80,0x20,0x80,0x20,0x40,0x28,0x20,0x10}; // &明&
void delay(int z)
&&&&&& int x,y;
&&&&&& for(x=0;x&z;x++)
&&&&&&&&&&&&& for(y=0;y&110;y++);
void main()
&&&&&& while(1)
&&&&&& &&&&& &for(num=0;num&16;num++)
&&&&&&&&&&&&& {
&&&&&&&&&&&&& & P1=&&&& &&&&&&&&& //行选
&&&&&&&&&&&&& & P2=table[2*num];&& //列选
&&&&&&&&&&&&& & P3=table[2*num+1];& //列选
&&&&&&&&&&&&& & delay(2);
&&&&&&&&&&&&& }
&&&&&& }&&&&
4..先来看这次使用的table数组,因为是16*16的点阵,所以总共有32个数据,其中第1、2个数据用于第一行的显示,第2、3个数据用于第二行的显示,以此类推,总共16行。然后还是来看while循环内,同样for循环依次扫描16行,以第一行为例,即num=0时,首先P1=0,选中第一行,P2=table[0]、P3=table[1]送出列选数据,即第一行要显示的两个字节的数据。其他行同理。这样很轻松的我们就完成了16*16点阵的显示。程序虽然完成了,但是回过头来看一看就会发现,我们在这里使用了P2与P3口一起来做列选,浪费了大量的I/O/资源,而且现在点阵屏的大小还只有16*16,如果想要扩展的更大,已经没有足够的I/O口可用了。所以一定要想出更好的办法进行列选。
5.为了解决上面提到的问题,我们来学习一个新的元件:74HC595。它实质上是一个串行移位寄存器,能够实现&串入并出&的功能,关于它的使用我们还是用上一个列子来讲解,先来看看它的实现,如图:
可以看到这里我们仅使用了三个I/O口就完成了列选数据的发送。主要来看74HC595是如何实现&串入并出&的,这里我们使用了两个595进行了级联,即第二个595的数据输入端连接了第一个595的级联输出口Q7&。也就是说,我们只需要从第一个595的输入端串行输入数据,便可以实现把数据送入第二个595的功能。而且595的数量可以进行无限的级联,而不管有多少个595,我们只需要一个数据输入端就可以,这样就大大节省了I/O资源。对于595的具体使用还是来看程序。
源代码如下:
/************16*16LED点阵屏显示*****************/
#include&reg52.h&
sbit R=&P2&^0;&& & //数据输入端口
sbit CLK=&P2&^1;&&&& & // 时钟信号
sbit STB=&P2&^2;&&&&& & // 锁存端
char code table[]={0x00,0x20,0x20,0x7F,0x7E,0x21,0x22,0x21,
&&&&&&&&&&&&&&&&&&&& &&&&&& 0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21,
&&&&&&&&&&&&&&&&&&&& &&&&&& 0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21,
&&&&&&&&&&&&&&&&&&&& &&&&&& 0x80,0x20,0x80,0x20,0x40,0x28,0x20,0x10}; // &明&
void delay(int z)
&&&&&& int x,y;
&&&&&& for(x=0;x&z;x++)
&&&&&&&&&&&&& for(y=0;y&110;y++);
void WriteByte(char dat)&&&&&&&&&&&&&&&&&&&& //写一个字节的数据
&&&&&& for(i=0;i&8;i++)&&&&&&&&&&& //循环8次把编码传给锁存器
&&&&&&&&&&&&& {
&&&&&&&&&&&&& & dat=dat&&1;&&&&&& //右移一位,取出该字节的最低位
&&&&&&&&&&&&& & R=CY;&&&&&&&&&&&&&& //将该字节的最低位传给R
&&&&&&&&&&&&& & CLK=0;& && &&&&//将数据移入595,上升沿
&&&&&&&&&&&&& & CLK=1;&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&& }&&&&
void main()
&&&&&& while(1)
&&&&&& &&&&& &for(num=0;num&16;num++)
&&&&&&&&&&&&& {
&&&&&&&&&&&&& & WriteByte(table[2*num]);& & //送出一个字节&
&&&&&&&&&&&&& & WriteByte(table[2*num+1]);
&&&&&&&&&&&&& & P1=&&&& //行选
&&&&&&&&&&&&& & STB=1;&&&&&& & //输出锁存器中的数据,下降沿
&&&&&&&&&&&&& & STB=0;&&&&&&&&&&&&& &
&&&&&&&&&&&&& & delay(2);
&&&&&&&&&&&&& }
&&&&&& }&&&&
先来看不同之处,这里我们首先位定义了R、CLK、STB,分别对应于74HC595的DS、SH_CP、ST_CP用以实现串行数据输入、数据移位以及并行数据输出。然后来看WriteByte(char dat)函数,该函数实现了串行向595中输入一个字节数据的功能。来看for循环,首先dat=dat&&1,把要输入的数据右移一位,这样最低位便进入移位寄存器CY中,紧接着我们让R=CY,把该位传给595的输入端,CLK一个上升沿的跳变就实现了把该位数据移入595的功能。8次循环便可以将一个字节的数据送出。重点还是看while循环内,同样也是16行的扫描,然后就是WriteByte(table[2*num])等同于上面的P2=table[2*num],WriteByte(table[2*num+1])等同于P3=table[2*num+1],完成列选,接着行选,然后有一个STB的下降沿的跳变,这个变化能够实现并行输出移位寄存器中的数据。这样就完成了整个过程。
(3)16*16点阵的移位控制
点阵的移位一般有上、下、左、右的移动,这里我们重点讲上移和左移,其它同理。
1.&&&&&& 点阵的上移:
点阵的上移相对来说很简单,看效果图如下:
源代码:(该程序实现了循环上移显示&邢台&)
/************16*16LED点阵屏显示*****************/
#include&reg52.h&
sbit R=&P2&^0;&& & //数据输入端口
sbit CLK=&P2&^1;&&&& & // 时钟信号
sbit STB=&P2&^2;&&&&& & // 锁存端
char code table[]={
/*--& 文字:& 邢& --*/
/*--& 宋体12;& 此字体下对应的点阵为:宽x高=16x16&& --*/
&&&&& 0x00,0x00,0xFE,0x3E,0x48,0x22,0x48,0x22,
&&&&& 0x48,0x12,0x48,0x12,0x48,0x0A,0xFF,0x13,
&&&&& 0x48,0x22,0x48,0x42,0x48,0x42,0x48,0x46,
&&&&& 0x44,0x2A,0x44,0x12,0x42,0x02,0x40,0x02,
/*--& 文字:& 台& --*/
/*--& 宋体12;& 此字体下对应的点阵为:宽x高=16x16&& --*/
&&&&& & 0x40,0x00,0x40,0x00,0x20,0x00,0x10,0x04,
&&&&& 0x08,0x08,0x04,0x10,0xFE,0x3F,0x00,0x20,
&&&&& 0x00,0x08,0xF8,0x1F,0x08,0x08,0x08,0x08,
&&&&& 0x08,0x08,0x08,0x08,0xF8,0x0F,0x08,0x08,
void delay(int z)
&&&&&& int x,y;
&&&&&& for(x=0;x&z;x++)
&&&&&&&&&&&&& for(y=0;y&110;y++);
void WriteByte(char dat)&&&&&&&&&&&&&&&&&&&& //写一个字节的数据
&&&&&& for(i=0;i&8;i++)&&&&&&&&&&& //循环8次把编码传给锁存器
&&&&&&&&&&&&& {
&&&&&&&&&&&&& & dat=dat&&1;&&&&&& //右移一位,取出该字节的最低位
&&&&&&&&&&&&& & R=CY;&&&&&&&&&&&&&& //将该字节的最低位传给R
&&&&&&&&&&&&& & CLK=0;& && &&&&//将数据送出,上升沿
&&&&&&&&&&&&& & CLK=1;&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&& }&&&&
void main()
&&&&& int num,move,
&&&&&& while(1)
&&&&&& &&&&& &if(++speed&8)&& //移动速度控制
&&&&&&&&&&&&& &{
&&&&&&&&&&&&& &&&&& speed=0;
&&&&&&&&&&&&&&&&&&&& move++;&&& //移位
&&&&&&&&&&&&&&&&&&&& if(move&16)& //是否完成移位一个汉字
&&&&&&&&&&&&&&&&&&&&&&&&&&& move=0;& //从头开始
&&&&&&&&&&&&& &}
&&&&&&&&&&&&& &
&&&&&&&&&&&&& &for(num=0;num&16;num++)
&&&&&&&&&&&&& {
&&&&&&&&&&&&& & WriteByte(table[2*num+move*2]);&& & //送出一个字节&
&&&&&&&&&&&&& & WriteByte(table[2*num+1+move*2]);
&&&&&&&&&&&&& & P1=&&&& //行选
&&&&&&&&&&&&& & STB=1;&&&&&& & //输出锁存器中的数据,下降沿
&&&&&&&&&&&&& & STB=0;&&&&&&&&&&&&& &
&&&&&&&&&&&&& & delay(2);
&&&&&&&&&&&&& }
&&&&&& }&&&&
可以看到这个程序和静态显示的程序没有太大的差距,主要就是加入了一个move变量来控制移动,WriteByte(table[2*num+move*2])中当move变量变化的时候更改了写入595中的数据,正好实现了移动显示的效果。而speed变量的if判断语句能够控制移动速度的大小。下面重点讲左移。
2.&&&&&& 点阵的左移:
因为点阵的数据最终是一个一个字节的并行送出的,所以要实现点阵的左移,我们就需要考虑如何才能够动态的更改每一个发送字节的数据,而汉字的每一个字节的编码是固定的,这里我们可以使用一个数据缓冲区来完成点阵的左移。重点说一下点阵左移中关键的一步操作temp=(BUFF[s]&&tempyid) | (BUFF[s+1]&&(8-tempyid))。这里temp作为要发送的一个字节数据,它由数据缓冲区中的数据组合而成,并且动态的变化,大致来说就是首先第一个字节的数据右移tempyid位,第二个字节的数据左移8-tempyid位,两者相或后组成一个字节新的数据,只要我们一直不断地移位、相或、发送,就能实现左移的效果。不太好理解,先来看实例(循环左移显示&邢台学院&),效果图如下:
见源代码:
#include &AT89x51.H&
#define uchar unsigned char
#define uint unsigned int
uchar yid,h;&&&&&&&&&&&&&&&&& && //YID为移动计数器,H为行段计数器
&&&&&&&&&&& &&&&&& //字模计数器
uchar code hanzi[];&&&&&&& && //汉字字模
uchar BUFF[4];&&&&&&&&&&& && //缓存
void in_data(void);&&&&&&& && //调整数据
void rxd_data(void);&&&&& && //发送数据
void sbuf_out();&&&&&&&&&&& && //16段扫描
uchar code table[]={//篇幅有限,省略编码};
void main(void)
&uchar i,d=10;
&zimuo=0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&
&&&&&& while(yid&16)&&&&&&&&&&&&&&&&&&&&& &&&&&& //数据移位。
&&&&&&&&&&&&& for(i=0;i&d;i++)&&&&&&&&&&&&&&&&&& && //移动速度
&&&&&&&&&&&&& &{
&&&&&&&&&&&&& &sbuf_out();
&&&&&&&& }
&&&&&&&&&&&&& &yid++;&&&&&&&&&&&&&&&&&&&&&&& //移动一步
&& zimuo=zimuo+32;&&&&&&&&&&&&&&&&& & //后移一个字,
&& if(zimuo&=96)&&&&&&&&&&&&&&&&&&&&&& //到最后从头开始,有字数决定
&& zimuo=0;
/********************************/
void sbuf_out()
&&&&&& & {
&&&&&&&&&&&&& for(h=0;h&16;h++) & //16行扫描
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& in_data();&&&&&&&&&&&&&&&&&&&&&&&&&&& //调整数据
&&&&&&&&&&&&&&&&&&&& rxd_data();&&&&&&&&&&& &&& //串口发送数据
&&&&&&&&&&& P1=0x7f;&&&&&&& &&&&&&& //关闭显示。
&&&&&&&&&&& P1_7=1;&&&&&&&&&&&&&&&&&&&&&& //锁存为高,595锁存信号
&&&&&& &&& &&&&&& P1=h;&&&&&&&&&&&&&&&&&&& &&& //送行选
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&& }
/******************************************************/
void in_data(void)
&&&&&& for(s=1;s&=0;s--)&&&&&&&&&&&&&&&&& //h为向后先择字节计数器,zimuoo为向后选字计数器
&&&&&& &BUFF[2*s+1]=table[zimuo+1+32*s+2*h]; //把第一个字模的第一个字节放入BUFF0
//中,第二个字模的第一个字节放入BUFF2中
&&&&&& &BUFF[2*s]=table[zimuo+32*s+2*h];& && // 把第一个字模的第二个字节放入BUFF1中,
//第二个字模的第二个字节放入BUFF3中
/*******************************************************/
void rxd_data(void)&&&&&&&&&&&&& &&&&&&&&&&& //串行发送数据
& uchar inc,tempyid,
& if(yid&8)
&&& inc=0;
&&& inc=1;
& for(s=0+s&2+s++)&&&&&&&&&&&&&&& //发送2字节数据
&&&&&& & if(yid&8)
&&& &&tempyid=
&&&&& else
&&& &&tempyid=yid-8;
&&&& temp=(BUFF[s]&&tempyid)|(BUFF[s+1]&&(8-tempyid));//h1左移tempyid位后和h2右移8-tempyid相或,取出移位后的数据&&&&
&&&&&& SBUF=//把BUFF中的字节从大到小移位相或后发送输出。
&&&&&& while(!TI);& //注:这里使用了串口,串口数据的发送为最低位在前。
&&&&&& TI=0;&&&&& && //等待发送中断&
首先来看定义的数据缓冲区BUFF[ ],这里一开始将会存储第一个汉字与第二个汉字的第一行的编码,该缓冲区动态的存储点阵屏每一行要发送的数据,注意这里BUFF的大小为4个字节,比16*16点阵屏要显示的汉字多了一个汉字行的大小,这一点是必要的,这样我们才能实现利用该缓冲区进行左移控制,接着来看in_data(void)函数,利用该函数,我们实现了动态的修改缓冲区中的数据,这里不再详述过程,重点看程序的注释即可。然后看rxd_data(void)函数,该函数的作用正是利用串口串行发送数据,也就是上面提到的移位、相或然后发送,关于在移位过程中的具体实现细节以及如何协调的进行数据发送,首先来看inc变量,该变量决定了从BUFF缓冲区中的第一个还是第二个数据开始读取,当移位开始后,在移完一个字节的数据之前我们都从BUFF数据缓冲区中的第一个字节开始读取,当移完一个字节后,inc变成1,这时我们从BUFF数据缓冲区中的第二个字节开始读取,于此同时后一个字节总是在和前一个字节的数据进行移位相或,达到慢慢向前推进的效果,这里有一个临界点,就是当移位满16位后,即一个汉字移出点阵屏后,这时候我们就需要将数据缓冲区中的数据进行更新,即后移一个字,这时数据缓冲区中的数据就变成了第二个汉字和第三个汉字的第一行汉字的编码,以此类推。下面来看sbuf_out()函数,该函数实现了16行的扫描,最后来看while循环内,这时主函数内已经很简单了,首先在while(yid&16)内,有控制移动速度的for循环,即显示几次静态的画面移动一步,而zimuo变量为移位过程中汉字的选择变量,它每32位的变化,正好是一个16*16汉字的编码个数。这样就完成了整个点阵左移的控制(这里使用了串口实现点阵的左移,当然我们也可以不用串口,关于非串口实现的左移后面介绍),它的过程比较复杂,需反复思考。
(4)128*32点阵扩展显示
1.&&&&&& 128*32点阵的静态显示
完成了16*16点阵的静态与移动显示之后,就已经算是掌握了点阵屏显示的主要部分,以后不管想要操纵什么样的点阵屏,只要把握上面的原理,都能按照我们的想法进行显示。所以接下来的讲解不会再有上面那么详细。
下面来看128*32点阵是如何显示的。
这里的布线有点繁琐,首先来看一下64*16点阵的布线,如下图:
前面已经提到过,在该仿真环境下红色点阵为上列选下行选。理解了64*16的点阵布线,我们来看一下128*32的仿真图:
这是一个完整的128*32的点阵屏,只是在上面小屏的基础上级联了更多的595,因为只有一个4选16的译码器,而该点阵有32行,这里我们使用两个数据输入端,分别对应点阵屏的上、下半屏。下面以操作上半屏为例(下半屏同理)。
看效果图:
见源代码:
#include &AT89x51.H&
#define uchar unsigned char
#define uint unsigned int
uchar yid,h;&&&&&&&&&&&&&&&&& && //YID为移动计数器,H为行段计数器
&&&&&&&&&&& &&&&&& //字模计数器
uchar code hanzi[];&&&&&&& && //汉字字模
uchar BUFF[18];&&&&&&&&&& && //缓存
void in_data(void);&&&&&&& && //调整数据
void rxd_data(void);&&&&& && //发送数据
void sbuf_out();&&&&&&&&&&& && //16段扫描
uchar code table[]={//篇幅有限,省略编码};
void main(void)
&uchar i,d=10;
&zimuo=0;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&
&&&&&& while(yid&16)&&&&&&&&&&&&&&&&&&&&& &&&&&& //数据移位。
&&&&&&&&&&&&& for(i=0;i&d;i++)&&&&&&&&&&&&&&&&&& && //移动速度
&&&&&&&&&&&&& &{
&&&&&&&&&&&&& &sbuf_out();
&&&&&&&& }
&&&&&&&&&&&&& &yid++;&&&&&&&&&&&&&&&&&&&&&&& //移动一步
&& zimuo=zimuo+32;&&&&&&&&&&&&&&&&& & //后移一个字,
&& if(zimuo&=480)&&&&&&&&&&&&&&&&&&&&&&&&&&& //到最后从头开始,有字数决定
&& zimuo=0;
/********************************/
void sbuf_out()
&&&&&& & {
&&&&&&&&&&&&& for(h=0;h&16;h++) & //16行扫描
&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&&&&&&& in_data();&&&&&&&&&&&&&&&&&&&&&&&&&&& //调整数据
&&&&&&&&&&&&&&&&&&&& rxd_data();&&&&&&&&&&& &&& //串口发送数据
&&&&&&&&&&& P1=0x7f;&&&&&&& &&&&&&& //关闭显示。
&&&&&&&&&&& P1_7=1;&&&&&&&&&&&&&&&&&&&&&& //锁存为高,595锁存信号
&&&&&& &&& &&&&&& P1=h;&&&&&&&&&&&&&&&&&&& &&& //送行选
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&& }
/******************************************************/
void in_data(void)
&&&&&& for(s=8;s&=0;s--)&&&&&&&&&&&&&&&&& //h为向后先择字节计数器,zimuoo为向后选字计数器
&&&&&& &BUFF[2*s+1]=table[zimuo+1+32*s+2*h]; //把第一个字模的第一个字节放入BUFF0
//中,第二个字模的第一个字节放入BUFF2中
&&&&&& &BUFF[2*s]=table[zimuo+32*s+2*h];& && // 把第一个字模的第二个字节放入BUFF1中,
//第二个字模的第二个字节放入BUFF3中
/*******************************************************/
void rxd_data(void)&&&&&&&&&&&&& &&&&&&&&&&& //串行发送数据
& uchar inc,tempyid,
& if(yid&8)
&&& inc=0;
&&& inc=1;
& for(s=0+s&8+s++)&&&&&&&&&&&&&&& //发送8字节数据
&&&&&& & if(yid&8)
&&& &&tempyid=
&&&&& else
&&& &&tempyid=yid-8;
&&&& temp=(BUFF[s]&&tempyid)|(BUFF[s+1]&&(8-tempyid));//h1左移tempyid位后和h2右移8-tempyid相或,取出移位后的数据&&&&
&&&&&& SBUF=//把BUFF中的字节从大到小移位相或后发送输出。
&&&&&& while(!TI);& //注:这里使用了串口,串口数据的发送为最低位在前。
&&&&&& TI=0;&&&&& && //等待发送中断&
该程序同上面的左移程序大同小略,只有几处不同。它同样实现了上半屏循环左移显示一系列汉字的功能。对该程序,就不再详细讲解。
二.基于AVR的点阵屏显示
(1)静态显示
上面已经讲完了基于51的点阵屏显示,相信大家已经掌握了点阵屏显示的原理,下面仍然依据该原理,我们使用AVR单片机来进行控制。
下面的程序均在ICCAVR Version 6.31A环境下编写并均在点阵实验板上测试通过。
首先来看一下128*32点阵屏两行静态显示的程序,源代码如下:
#include&iom16.h&
#include&macros.h&
#define uchar unsigned char
#define uint unsigned int
#include &delay.h&
#include &code.h&
#pragma data: data
#define screen_size&&& 8&&&&&&&&&&& //半屏显示汉字个数:8& 32*128
uchar BUFF_1[screen_size*2+2];&&&&& //缓存
uchar BUFF_2[screen_size*2+2];&&&&& //缓存&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&& &&&&&&&//disrow 为16行变量
uchar temp_up,temp_
uchar Move_up,Move_
uchar temp_up,temp_
uint& zimo_up,zimo_
#define&&&& HC595_data1_H()&&&& PORTB |= BIT(0)
#define&&&& HC595_data1_L()&&&& PORTB &=~BIT(0)
#define&&&& HC595_data2_H()&&&& PORTB |= BIT(1)
#define&&&& HC595_data2_L()&&&& PORTB &=~BIT(1)
#define&&&& HC595_clk_H&&&&&&&& PORTB |= BIT(2)
#define&&&& HC595_clk_L&&&&&&&& PORTB &=~BIT(2)
#define&&&& HC595_lock_H&&&&&&& PORTB |= BIT(3)
#define&&&& HC595_lock_L&&&&&&& PORTB &=~BIT(3)
/********************************************************
*&&&&&&&&&&&& 函数说明:595发送一个字节数据&&&&&&&&&&&& *
********************************************************/
void HC595_send_2byte(uchar byte1,uchar byte2)
&HC595_lock_L;
&for (i=0x01;i!=0;i=i&&1)
&& if(byte1&i)
&&&&& HC595_data1_L();
&&&&& HC595_data1_H();
&& if(byte2&i)
&&& & HC595_data2_L();
&&& & HC595_data2_H();
&& HC595_clk_H;
&& HC595_clk_L;
/*********************************************************
函数名:void Move_Up(const uchar *p,uint f)
功能:上半屏缓存数据 左移
/*********************************************************/&&&&&&&&&&&&&&&&&&&
void Move_Up(const uchar *p,uint f)
&signed char
&&& for(s=screen_s&=0;s--)&&&&
&&& &BUFF_1[2*s]=p[f+32*s+2*disrow];&&&
&&& &BUFF_1[2*s+1]=p[f+1+32*s+2*disrow];&&&&&&& &&&
/*********************************************************
函数名:void Move_Down(const uchar *p,uint f)
功能:下半屏缓存数据 左移
/*********************************************************/
void Move_Down(const uchar *p,uint f)
&& signed char
&&& for(s=screen_s&=0;s--)&&&&
&&& &BUFF_2[2*s]=p[f+32*s+2*disrow];&&&
&&& &BUFF_2[2*s+1]=p[f+1+32*s+2*disrow];&&&&&&& &&&
/*********************************************************
函数名:void display(void)
功能:显示刷新
/*********************************************************/
void display(void)
& uchar i = Move_
& uchar j = Move_
& uchar inc,tempyid,temp1,temp2;
&&& inc=0;
&&& inc=1;
& for(s=0+s&screen_size*2+s++)&&&& &&&//发送16字节数据
&&& & if(i&8)
&&&&&&& tempyid=i;
&&&&& else
&&&&&& tempyid=i-8;
&&&&& temp1=((BUFF_1[s]&&tempyid)|(BUFF_1[s+1]&&(8-tempyid)));
&&& & temp2=((BUFF_2[s]&&tempyid)|(BUFF_2[s+1]&&(8-tempyid)));
&&& && HC595_send_2byte(temp1,temp2);&&& //发送数据
void port_init(void)
&PORTA = 0x00;
&DDRA& = 0xFF;
&PORTB = 0x00;
&DDRB& = 0xFF;
&PORTC = 0x00; //m103 output only
&DDRC& = 0xFF;
&PORTD = 0x00;
&DDRD& = 0xFF;
//call this routine to initialize all peripherals
void init_devices(void)
&//stop errant interrupts until set
后参与讨论
  13:21:47 
看不到图片啊
阅读:2401
阅读:2412
阅读:2589
阅读:2481

我要回帖

更多关于 led点阵显示屏原理图 的文章

 

随机推荐