单片机学习小组
登录
直播中
周必镜
7年用户
930经验值
私信
关注
12864的原理是什么?12864的使用方法是什么
开启该帖子的消息推送
单片机
12864
点阵
12864的原理是什么?12864的使用方法是什么?
回帖
(1)
杜元晓
2022-1-21 15:29:39
最近在做有关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的相关操作也写出来(最近陆陆续续的有考试,大概率会咕咕咕)。第一次写博客,不知道怎么写比较好,就随便写了一点,希望能够帮到大家,也欢迎大家来找我探讨交流电子类方面的问题。
最近在做有关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的相关操作也写出来(最近陆陆续续的有考试,大概率会咕咕咕)。第一次写博客,不知道怎么写比较好,就随便写了一点,希望能够帮到大家,也欢迎大家来找我探讨交流电子类方面的问题。
举报
更多回帖
rotate(-90deg);
回复
相关问答
单片机
12864
点阵
求助
12864
问题
2015-06-19
2613
LCD
12864
仿真
2016-05-04
5387
stm32 LCD
12864
串口无显示
2018-04-03
6631
12864
编程问题
2012-08-11
3097
用单片机控制
12864
屏幕很暗的问题
2013-08-06
11806
12864
液晶驱动源码
2019-06-28
1798
12864
显示问题
2017-05-23
2990
12864
显示中文
2019-06-04
2936
LCD
12864
和OLED
12864
有什么区别?
2023-10-09
372
LCD
12864
显示不全
2018-04-23
9059
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
首页
论坛版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分