历史上的今天
今天是:2025年11月12日(星期三)
2022年11月12日 | 【51单片机】1602自定义字符原理及示例(”汉“、爱心及摄氏度示例)
2022-11-12 来源:csdn
原理
设置1602屏幕的对比度的时候我们能够看到5*8的点阵,其实液晶显示的都是字符的字模(下图),而CGROM里面都是已经定义好的,只能读不能写,而RAM是可以读写的所以我们只要将我们自定义的字符字模写入对应的CGRAM中就好,CGRAM一共有8个对应的地址分别为(0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78),因为每个字模对应8行所以每写完一个字模以后要加8,按照指令写入CGRAM时需要加0x40所以对应地址就如上了,然而其实CGRAM的实际地址是0x00-0x07所以在后面写入数据的时候需要按照实际地址来写入。CGROM中的字模也是同样的原理
字模代码:1602显示模式为5*7点阵型,字模代码对应于字模图形的8行,每行的前三位都是0,最后一行都是0x00,所以摄氏度的字符代码为:0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00
字模代码的获取可以用ZIMO221字模提取软件。
示例代码
#include #include //为各不同位数变量类型定义自定义符号 #define uint8 unsigned char #define uint16 unsigned short int #define uint32 unsigned long int #define int8 signed char #define int16 signed short int #define int32 signed long int #define uint64 unsigned long long int #define int64 signed long long int //定义1602中一些常用的指令,方便不同的读者可以根据自己的修改 #define SETMODE 0x38 //16*2显示,5*7点阵,8位数据接口 #define DISOPEN 0x0C //显示开,不显示光标,光标不闪烁 #define DISMODE 0x06 //读写字符后地址加1,屏显不移动 #define SETADDR 0x80 //设置数据地址指针初始值 #define CLEAR 0x01 //清屏,数据指针清零 #define RET 0x02 //回车,数据指针清零 #define PORT P0 //I/O口 sbit RS = P3^5; sbit E = P3^4; sbit dula = P2^6; sbit wela = P2^7; void delay(uint16 time); void Write1602_Com(uint8 com); void Write1602_Dat(uint8 dat); void Init1602(void); void Write1602_Str(uint8 addr,uint8 length,uint8 *pbuf); uint8 code xin[8]={ //心字模 0x00,0x1B,0x1F,0x1F,0x1F,0x0E,0x04,0x00 }; uint8 code hot[8]={ //摄氏温度字模 0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00 }; uint8 code zuo[8]={ //汉的左部分字模 0x00,0x02,0x01,0x02,0x01,0x01,0x02,0x00 }; uint8 code you[8]={ //汉的右部分字模 0x00,0x1e,0x12,0x0c,0x0a,0x11,0x00,0x00 }; uint8 i; void main() { Init1602(); //初始化1602 //自定义CGRAM Write1602_Str(0x40,8,hot); //摄氏温标->CGRAM的内存000中 Write1602_Str(0x48,8,zuo); //汉的左部分->CGRAM的内存001中 Write1602_Str(0x50,8,you); //汉的右部分->CGRAM的内存010中 Write1602_Str(0x58,8,xin); //心->CGRAM的内存011中 Write1602_Com(0x80); //设置DDRAM地址,即显示的位置 for(i=0;i<8;i++) Write1602_Dat(0); for(i=0;i<8;i++) Write1602_Dat(3); Write1602_Com(0xc0); //同上 for(i=0;i<16;i++) Write1602_Dat(1+i%2); while(1); } void delay(uint16 time) { uint8 i,j; for(i=time;i>0;i--) for(j=0;j<110;j++); } void Init1602(void) { dula=0; //关闭数据管的显示,因为我的51对应的是数据管的输入 wela=0; //所以需要锁存器锁定来关闭影响 Write1602_Com(SETMODE); //模式设置 delay(5); Write1602_Com(DISOPEN); //显示设置 delay(5); Write1602_Com(DISMODE); //显示模式 delay(5); Write1602_Com(CLEAR); //清屏 delay(5); } void Write1602_Dat(uint8 dat) { E=0; RS=1; //数据 delay(5); //延时 PORT=dat; //端口赋值 delay(5); E=1; //高脉冲 delay(5); E=0; } void Write1602_Com(uint8 com) { E=0; RS=0; //命令 delay(5); //延时 PORT=com; //端口赋值 delay(5); E=1; //高脉冲 delay(5); E=0; } void Write1602_Str(uint8 addr,uint8 length,uint8 *pbuf) { uint8 i; Write1602_Com(addr); for(i=0;i { Write1602_Dat(pbuf[i]); } } 效果 有点丑。。。。字模的问题,所以大家可以自己去设计。 总结: 1.设计自定义字符的字模并获取字符代码 2.在CGRAM对应的位置写入字符代码 3.在DDRAM中写入CGRAM对应的地址 
史海拾趣
|
Tsu/Tco 在Quartus II 的报告中有两种不同含义. 片内的Tsu/Tco 是指前级触发器的Tco 和后级触发器的Tsu, 一般来说都是几百ps 级别的. 可以通过“List Paths”命令查看。这里的Tsu/Tco 主要由器件工艺决定, 工作时在受到温度,电压的影响略有变化.( ...… 查看全部问答> |
|
void CfullscreenDlg::setfullscreen(HWND hDlg ) { HWND lpClassName; RECT rc; lpClassName = ::FindWindow(_T(\"menu_worker\"),NULL); &nbs ...… 查看全部问答> |
|
我的意思是,最近看STM32的示例源代码,发现系统开始的配置都是标准的函数库,各种参数也都有规律可循,是不是可以开发一个PC端程序,通过勾选、填写各种参数来自动生成一个工程所需要的开始源代码结构?类似Visual Studio里面那样?我觉 ...… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 02:55 编辑 史上最全的小车资料:源程序,各模块详解,电路图,统统一网打尽!!! [ 本帖最后由 帅帅的友哥哥 于 2011-8-29 16:02 编辑 ] … 查看全部问答> |
|
设计并制作FPGA开发板,核心器件为ALTERA公司的CYCLONE系列芯片。该开发板具有独立电源、独立下载功能,引脚开放,支持二次开发。 开发板包含的硬件模块为:1、FPGA核心板(包括ALTERA公司的CYCLONE系列芯片、开放的IO引脚、有独立工作时钟、独 ...… 查看全部问答> |




