完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
最近在做有关51的电子密码锁实验,正巧用到了12864与24C04。想在网上找找相关资料,要么讲的含糊不清,看的一知半解;要么太过复杂,难以理解。花了几天搞明白之后,把自己的看法简单分享一下。下面使用了我自己的代码进行讲解,但是各位朋友要能够真正的明白原理,而不是只会用我的代码。文中可能会有认识不全面的地方,请大家多多指教。
12864原理 所谓12864,顾名思义,为128x64的点阵组。在实际使用时,通常会把它分为左半屏和右半屏,每个半屏为64x64点阵。这里先扔掉我们的固有思维,不要用平日里的阅读习惯(从左到右,从上到下)去理解其显示方法,否则只会越学越糊涂。 需要知道的是,12864中使用了页这个概念。什么是页呢?以右半屏为例,我们应该都知道行和列的概念,在我的代码中,从第一行开始,往下数8个行,这8个行所构成的8x64点阵就是一页。虽然不同的操作函数设置的页的大小会有差别,但总体构成原理是相似的。话不多说,直接上图: 可以看到,每个半屏由8页组成,从上至下编号为0~7,一块完整的屏幕由16个页组成。而这些页的容量便取决于你的汉字字符有多大。说到这里,需要先重复一个常识:汉字(包括中文输入法下的标点符号)所占用的空间是英文字母、数字的2倍。知道了这一点,下面就比较好理解了。 在我写的代码中,一个页最多可以排列4个汉字,或是8个数字、字母。也就是说,一个汉字要占用8x16大小的点阵,四个汉字便占满了8x64的点阵。注意,这里我没有说一个汉字的大小是8x16,而是说一个汉字需要8x16大小的点阵来表示,要注意这两种说法的区别。 看到这里大家应该就明白了,在12864上显示的内容实际上是由不同的页里面的内容组合、拼凑而成的。有些朋友可能会问,那如果在屏幕的中间位置显示字符的话,不就涉及到了左右两块半屏了吗?没错,如果想要在屏幕的中间位置显示的话,左右半屏就需要各自显示内容的左半部分和右半部分。虽然这样听起来有些别扭,但既然是这样设计的,我们就只能这样去使用。 12864使用方法 下面直接把我用的12864的C文件代码贴上来,如果你是认真读到这里的,那么12864的基本原理应该理解得差不多了,只要我对函数的参数稍加解释,很快就可以理解并上手。至于代码是如何实现显示功能的就不讨论了,毕竟对于大多数人而言,只要能够使用便足矣。 #include #include #include "12864header.h" //直接往下翻到标有使用方法注释的操作函数部分,前面可以不用看 void busy()//忙检测函数,不用管 { P0=0X00; RS=0; RW=1; EN=1; while(P0&0X80); EN=0; } void wcmd(uchar cmd) { busy(); RS=0; RW=0; P0=cmd; EN=1;_nop_();_nop_(); EN=0; } void wdata(uchar dat) { busy(); RS=1; RW=0; P0=dat; EN=1;_nop_();_nop_(); EN=0; } void set_page(uchar page) { page=0xb8|page; wcmd(page); } void set_line(uchar line) { line=0xc0|line; wcmd(line); } void set_column(uchar column) { column=0x40|column; wcmd(column); } void set_onoff(uchar onoff) { onoff|=0x3e; wcmd(onoff); } void select_screen(uchar screen) { switch(screen) { case 0:CS1=0;CS2=0;break; case 1:CS1=0;CS2=1;break; case 2:CS1=1;CS2=0;break; default:break; } } void clear_screen(uchar screen) { uchar i,j; select_screen(screen); for(i=0;i<8;i++)? { set_page(i); set_column(0); for(j=0;j<64;j++) wdata(0x00); } } void init() //这里是12864初始化,需要在使用前调用1次 { busy(); select_screen(0); set_onoff(0); select_screen(0); set_onoff(1); select_screen(0); clear_screen(0); set_line(0); } void Show(uchar screen,uchar page,uchar column,uchar *p)//显示汉字的函数,各参数的含义在下面讲解 { uchar i; select_screen(screen); //选择要操作的是左半屏还是右半屏,1为左半屏,2为右半屏 set_page(page); //选择要操作的页,范围为0~7 set_column(column);//选择从哪个地方开始写,这个在下文中解释 for(i=0;i<8;i++) wdata(p);//p为指针,指向待写入内容的起始位置,这里推荐用数组 set_page(page+1); set_column(column); for(i=0;i<16;i++) wdata(p[i+16]); } void Show1(uchar screen,uchar page,uchar column,uchar *p)//显示数字或字母的函数,参数含义与上一个函数相同,不做赘述 { uchar i; select_screen(screen); set_page(page); set_column(column); for(i=0;i<8;i++) wdata(p); set_page(page+1); set_column(column); for(i=0;i<8;i++) wdata(p[i+8]); } 那么,这个函数要怎么使用呢?举个例子,假设在一个名为start的数组中,有如下两个汉字:“通”,编码如下(利用字模软件生成): 0x40,0x42,0xCC,0x00,0x00,0xE2,0x22,0x2A,0x2A,0xF2,0x2A,0x26,0x22,0xE0,0x00,0x00, 0x80,0x40,0x3F,0x40,0x80,0xFF,0x89,0x89,0x89,0xBF,0x89,0xA9,0xC9,0xBF,0x80,0x00, “信”,编码如下: 0x00,0x80,0x60,0xF8,0x07,0x00,0x04,0x24,0x24,0x25,0x26,0x24,0x24,0x24,0x04,0x00, 0x01,0x00,0x00,0xFF,0x00,0x00,0x00,0xF9,0x49,0x49,0x49,0x49,0x49,0xF9,0x00,0x00, 现在我的左半屏第1页中的第一个字为“通”,我想紧跟其后的显示“信”这个字,就可以这样来写: Show(1,1,2*8,start+1*32); (因为文本显示问题,下面都用乘来代替*) 这里面,第一个1表示在左半屏,第二个1表示在第1页,2乘8表示从第16位写起,因为第一个汉字“通”已经占据了8x16大小的点阵,也就是在横向的方向占据了2x8个点(纵向方向的不用在意,因为它们都占满了8个点),即0-15,那么下一个汉字就要从横向方向从左往右数的第16个点开始写起。而start+1乘32,则表示将指针指向数组中第二个字的起始位置,为什么是1乘32呢?观察一下上面每个字的编码,这里假设每个十六进制数占用一个数位,不难发现每个字的大小便是32个数位,那么就可以知道,第一个汉字“通”占用了数组的0-31数位,所以指针就需要指到第32个数位处,即1乘32。 12864就写到这里,过几天应该会把24C04的相关操作也写出来(最近陆陆续续的有考试,大概率会咕咕咕)。第一次写博客,不知道怎么写比较好,就随便写了一点,希望能够帮到大家,也欢迎大家来找我探讨交流电子类方面的问题。 |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2951 浏览 16 评论
3455 浏览 1 评论
8984 浏览 16 评论
4045 浏览 18 评论
1097浏览 3评论
567浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
564浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2299浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1855浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-20 20:25 , Processed in 1.143494 second(s), Total 79, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号