数码之家

 找回密码
 立即注册
搜索
查看: 267|回复: 13

[C51] 小白学单片机,LCD12864无字库显示大小字原理

[复制链接]
发表于 7 天前 | 显示全部楼层 |阅读模式
今天看到有网友做的数码字体很好看,
我也试着做了一下,
把LCD12864显示大小字的原理记录一下,以免忘记
先上效果图
这里小数字是8*16点阵的,中文是16*16点阵的,大数字是16*32点阵的,字体是宋体,



大数字改成数码体,感觉要好看得多,字体是网上下载的,



LCD12864的X方向有2个64点,共128点,Y方向有64点,分成8页,这样每页就是8个点
能显示4行16*16点阵的中文



8*16点阵和16*32点阵如下
8*16点阵分2页显示完,16*32点阵要分4页才能显示完



显示顺序如下:


8*16点阵字占16个字节,每个8位


16*32点阵字占64个字节,每个8位


再来看这2种字体驱动的区别

8*16点阵的,分2页写完,写第二页时,跳过前面8个字节,写后面8字节




16*32点阵的,分4页写完,共64个字节
写第二页时,跳过前面16个字节,写后面16字节
写第三页时,跳过前面32个字节,写后面16字节
写第四页时,跳过前面48个字节,写后面16字节


程序中的num表示第几个字 ,因为我是把所有字放在一个数组里,
比如要显示0那num就为0 要显示5那num就是5




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
发表于 7 天前 | 显示全部楼层
stc89c52写的
回复 支持 反对

使用道具 举报

发表于 6 天前 来自手机浏览器 | 显示全部楼层
不错不错…闲了我也得点屏玩玩…好久没玩这些了…
回复 支持 反对

使用道具 举报

发表于 6 天前 | 显示全部楼层
程序有没有问题不评价,起码审美有问题
回复 支持 反对

使用道具 举报

发表于 6 天前 | 显示全部楼层
不错,学习了
回复 支持 反对

使用道具 举报

发表于 6 天前 | 显示全部楼层
小白入门必修
回复 支持 反对

使用道具 举报

 楼主| 发表于 6 天前 | 显示全部楼层

对的,很久以前买的学习板,这个板有LCD13864接口
回复 支持 反对

使用道具 举报

 楼主| 发表于 6 天前 | 显示全部楼层

没有其它可练手的了,只能玩玩这些了
回复 支持 反对

使用道具 举报

发表于 6 天前 | 显示全部楼层
我淘的无字库屏好像是先显示屏的下半部从上到下4行,都是逐行从左到右显示。然后显示屏的上半部,从上往下4行,也是逐行从左到右。延时加大,可以看到像素慢慢移动
回复 支持 反对

使用道具 举报

 楼主| 发表于 5 天前 | 显示全部楼层
本帖最后由 hellozwt 于 2025-4-26 11:25 编辑

从上到下,还是从下到上,应该跟你写的驱动有关
这个是清屏程序,一次写64列,
如果是英文一次写8列,中文一次写16列




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 昨天 09:07 | 显示全部楼层
有空演练一下
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 20:24 | 显示全部楼层
屏驱动
  1. //lcd12864(ks0108) 无字库
  2. //128*64点阵液晶显示模块,汉字16*16点阵,字符8*16点阵
  3. #include <reg52.h>
  4. #include <intrins.h>         //_nop_()
  5. #include "delay.h"        //延时

  6. #define uchar unsigned char
  7. #define uint unsigned int
  8. #define port P2  //DB0~DB7数据口

  9. sbit lcd_rs=P0^4;          //命令数据选择
  10. sbit lcd_rw=P0^3;          //读/写选择
  11. sbit lcd_en=P0^2;          //使能
  12. sbit lcd_cs1=P0^1;          //左半屏选择,1有效
  13. sbit lcd_cs2=P0^5;          //右半屏选择,1有效
  14. sbit lcd_rst=P0^0;          //复位
  15. sbit busy=P2^7;        //忙信号


  16. //检查是否忙
  17. void check_busy (void)
  18. {
  19.         lcd_rs=0;  //0命令 1数据
  20.         lcd_rw=1;  //0写 1读
  21.         port=0x00;         //
  22.         lcd_en=1;         //使能,读出信号
  23.         while(port & 0x80);  //最高位DB7==1 为busy
  24.         lcd_en=0;
  25. }

  26. //写命令
  27. void lcd_write_cmd(uchar cmd)
  28. {                                          
  29.           check_busy ();
  30.         lcd_rs=0;        //0命令 1数据
  31.           lcd_rw=0;         //0写 1读
  32.           port=cmd;           //将命令写入P2口
  33.           _nop_();    //空操作,做短暂的延时
  34.           lcd_en=1;   //en先置高电平
  35.           _nop_();    //空操作,做短暂的延时
  36.           lcd_en=0;   //en的下降沿,数据写入
  37. }

  38. //写数据
  39. void lcd_write_dat(uchar dat)
  40. {
  41.           lcd_rs=1;                //0命令 1数据
  42.           lcd_rw=0;         //0写 1读
  43.           port=dat;                  //将数据写入P2口
  44.           _nop_();      //空操作,做短暂的延时
  45.           lcd_en=1;     //en先置高电平
  46.           _nop_();      //空操作,做短暂的延时
  47.           lcd_en=0;     //en的下降沿,数据写入

  48. }

  49. //初始化
  50. void lcd_init()
  51. {          
  52.           lcd_rst=0;      //液晶复位
  53.           delay_ms(2);     //适当延时
  54.           lcd_rst=1;      //复位结束
  55.           lcd_cs1=1;      //左半屏选通
  56.           lcd_cs2=1;      //右半屏选通       
  57.           delay_ms(2);     //适当延时
  58.           lcd_write_cmd(0x3f);    //0011 1111 开显示
  59.           //0x3e 关显示
  60.           //0xb8 页地址 X地址 1页8行 共64行        A0-A2 0-7共8页
  61.           //0x40 列地址        Y地址 1列一个点 A0-A5 0-63 共128点
  62.           //0xc0 起始行
  63.                  
  64. }

  65. //清屏
  66. void lcd_clear(uchar m)
  67. {
  68.           uchar j,k;
  69.           lcd_cs1=1;                              //左半屏选通
  70.           lcd_cs2=1;                               //右半屏选通
  71.           lcd_write_cmd(0x40+0);        //将起始列地址写入
  72.           for(k=0;k<8;k++)
  73.           {
  74.                     lcd_write_cmd(0xb8+k);    //将起始行地址写入       
  75.                     for(j=0;j<64;j++)               //每行的64列都写0,因为选了左右两屏,
  76.                     {
  77.                               lcd_write_dat(m); //64列同时写0
  78.                     }
  79.           }
  80. }

  81. //设定位置座标
  82. void lcd_set_pos(uchar page,column)         //页 列
  83. {
  84.           page = page & 0x07;     //按位与0000 0111限定范围,行不能超过8
  85.           column = column & 0x7f;     //按位与0111 1111限定范围,列不能超过128
  86.           
  87.           if(column<64)      //如果列小于64
  88.           {
  89.                     lcd_cs1=1;        //开左半屏
  90.                     lcd_cs2=0;        //关右半屏
  91.                     lcd_write_cmd(0x40+column);  //将列地址写入  
  92.           }
  93.           else
  94.           {
  95.                     lcd_cs1=0;        //关左半屏
  96.                     lcd_cs2=1;        //开右半屏
  97.                     column &= 0x3f;                  //按位与0011 1111     64变0 127变63
  98.                     lcd_write_cmd(0x40+column);  //将列地址写入         
  99.           }
  100.           lcd_write_cmd(0xb8+page);      //将起始行地址写入
  101.                  
  102. }

  103. //写入英文8*16点阵                                                                                                                                                          
  104. void lcd_write_en(uchar page,column,num,uchar *p)
  105. {
  106.     uchar col=0;           //列
  107.           lcd_set_pos(page,column);     //设定起始地址
  108.           for(col=0;col<8;col++)           //循环写8列
  109.           lcd_write_dat(p[num*16+col]);   //先写上半个字,8个字节

  110.           lcd_set_pos(page+1,column);          //设定起始地址,将行地址加1,写下行
  111.           for(col=0;col<8;col++)           //循环写8列
  112.           lcd_write_dat(p[num*16+8+col]); //再写下半个字,8个字节
  113. }


  114. //写入英文16*32点阵                                                                                                                                                          
  115. void lcd_write_num(uchar page,column,num,uchar *p)
  116. {
  117.         uchar col;
  118.         uchar k;
  119.         uchar n=0;           //列 页 字符数
  120.         for(k=0;k<4;k++)  //循环写入4页
  121.         {
  122.                  lcd_set_pos(page+k,column);     //设定起始地址
  123.                 for(col=0;col<16;col++)           //循环写16列
  124.             {
  125.                         lcd_write_dat(p[num*64+n+col]);
  126.                 }   //先写上半个字
  127.                 n=n+16;
  128.         }
  129. }


  130. //写入中文16*16点阵
  131. void lcd_write_cn(uchar page,column,num,uchar *p)
  132. {
  133.           uchar col=0;           //列       
  134.           lcd_set_pos(page,column);             //设定起始地址
  135.           for(col=0;col<16;col++)
  136.           lcd_write_dat(p[num*32+col]);    //先写上半个字,共16个字节
  137.           lcd_set_pos(page+1,column);           //设定起始地址,行地址加1,写下行
  138.           for(col=0;col<16;col++)
  139.           lcd_write_dat(p[num*32+16+col]); //再写下半个字,共16个字节
  140. }       


  141. //写入图片
  142. void lcd_write_pic(uchar *pic)
  143. {
  144.           uchar i,j;       
  145.           for(i=0;i<8;i++)
  146.           {
  147.                      lcd_cs1=1;        //开左半屏
  148.                   lcd_cs2=0;        //关右半屏
  149.                   lcd_write_cmd(0xb8+i);  //将列地址写入  
  150.                   for(j=0;j<64;j++)
  151.                   lcd_write_dat(pic[i*128+j]);

  152.                   lcd_cs1=0;        //开左半屏
  153.                   lcd_cs2=1;        //关右半屏
  154.                   lcd_write_cmd(0xb8+i);  //将列地址写入  
  155.                   for(j=64;j<128;j++)
  156.                   lcd_write_dat(pic[i*128+j]);
  157.           }         
  158. }       
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 20:25 | 显示全部楼层
所有代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 14 小时前 | 显示全部楼层
我觉得星期几,这个数字改为中文比较好看些
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-1 22:38 , Processed in 0.202800 second(s), 9 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表