当前位置:首页 > 单片机 > 单片机
[导读]从业近十年!手把手教你单片机程序框架 第80讲开场白:前面章节讲的内容全部都是用自构字库的,相当于使用液晶屏的图像模式。其实这个款12864液晶屏的驱动芯片是st7920,它内部是自带16x16字库的,可以显示16x16的汉字

从业近十年!手把手教你单片机程序框架 第80讲

开场白:

前面章节讲的内容全部都是用自构字库的,相当于使用液晶屏的图像模式。其实这个款12864液晶屏的驱动芯片是st7920,它内部是自带16x16字库的,可以显示16x16的汉字或者8x16的字符。这一节开始就跟大家讲讲这方面的内容。要教会大家四个知识点:

第一个:内部字库的真实坐标体系的本质。当我们用内部字库的时候,它的坐标体系跟前面讲的自造字库坐标不一样,不再是256x32的液晶屏。它还原成为128x64的液晶屏,横坐标x轴坐标没办法精确到每个点,只能以16个点(2个字节)为一个单位,因此128个点的x轴坐标范围是0至8。而y轴的坐标也是以16个点(2个字节)为一个单位,因此64个点的x轴坐标范围是0至3。把12864液晶屏分成4行8列,每个数代表一个坐标点。

第二个:在使用内部字库时,C51编译器暗地里干了啥?如果使用液晶屏内部自带字库,编程的时候只要在源代码里直接写入所需要的汉字或者字符,就可以自动调用相对应的字库了。但是细心的网友一定会问,为什么在源代码上直接写入某个汉字就可以调用到这个汉字的字库?其实,表面上我们写下具体的某个汉字或者字符,但是C51编译器会自动对数组内的汉字翻译成 机内码(2字节),会自动对数组内的字符翻译成 ASCII码(1字节)。

第三个:12864的控制芯片st7920内部有两套驱动显示指令方式,一种是前面章节讲的自构字库模式,也是图像模式。另外一种就是本节讲的用内部字库模式。在切换模式的时候,发送命令字0x0c表示用内部字库模式,发送命令字0x36表示用自构字库模式。

第四个:12864整屏有4行8列,一共32个坐标点,每个坐标点可以显示一个16x16的汉字,但是在显示8x16字符时候,必须一次显示2个字符筹够16x16的点阵。例如,只想达到显示一个字符的时候,应该在另外一个空位置上显示空字符来填充。

具体内容,请看源代码讲解。

(1)硬件平台:基于朱兆祺51单片机学习板。

(2)实现功能:

开机上电后,液晶屏第一行调用直接汉字书写方式的数组来显示(馒头V5)的内容。第四行调用机内码和ASCII码的数组来显示(馒头V5)的内容。

(3)源代码讲解如下:

#include "REG52.H"

sbit LCDCS_dr = P1^6; //片选线

sbit LCDSID_dr = P1^7; //串行数据线

sbit LCDCLK_dr = P3^2; //串行时钟线

sbit LCDRST_dr = P3^4; //复位线

void SendByteToLcd(unsigned char ucData); //发送一个字节数据到液晶模块

void SPIWrite(unsigned char ucWData, unsigned char ucWRS); //模拟SPI发送一个字节的命令或者数据给液晶模块的底层驱动

void WriteCommand(unsigned char ucCommand); //发送一个字节的命令给液晶模块

void LCDWriteData(unsigned char ucData); //发送一个字节的数据给液晶模块

void LCDInit(void); //初始化 函数内部包括液晶模块的复位

void display_clear(void); // 清屏。4行8列的坐标点全部显示2个空字符相当于清屏了。

void display_hz1616(unsigned int x,unsigned int y,const unsigned char *ucArray);

void display_double_zf816(unsigned int x,unsigned int y,const unsigned char *ucArray1,const unsigned char *ucArray2);

void delay_short(unsigned int uiDelayshort); //延时

/* 注释一:内部字库的真实坐标体系的本质。

* 当我们用内部字库的时候,它的坐标体系跟前面讲的自造字库坐标不一样,不再是256x32的液晶屏。

* 它还原成为128x64的液晶屏,横坐标x轴坐标没办法精确到每个点,只能以16个点(2个字节)为一个单位,

* 因此128个点的x轴坐标范围是0至8。而y轴的坐标也是以16个点(2个字节)为一个单位,因此64个点的x轴

* 坐标范围是0至3。以下是坐标地址的位置编码。把12864液晶屏分成4行8列,每个数代表一个坐标点,

* 用深究具体含义,液晶驱动芯片ST7920的手册上有提到。

*/

code unsigned char ucAddrTable[]= //调用内部字库时,液晶屏的坐标体系,位置编码,是驱动内容,读者可以不用深究它的含义。

{

0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,

0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,

0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,

0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,

};

/* 注释二:在使用内部字库时,C51编译器暗地里干了啥?

* 如果使用液晶屏内部自带字库,以下编程的时候只要在源代码里直接写入所需要的汉字或者字符,

* 就可以自动调用相对应的字库了。但是细心的网友一定会问,为什么在源代码上直接写入某个汉字

* 就可以调用到这个汉字的字库?其实,表面上我们写下具体的某个汉字或者字符,但是C51编译器

* 会自动对数组内的汉字翻译成 机内码(2字节),会自动对数组内的字符翻译成 ASCII码(1字节)。

* 本节程序会做这个实验来验证它。以下两种书写方式不一样,但本质是一样的。

*/

code unsigned char Hz1616_man[]="馒"; //对于数组内的汉字,编译会自动翻译成 机内码(2字节)

code unsigned char JN1616_man[]= //机内码 馒 网上有很多把汉字或者字符转换成相关编码的工具软件

{

0xC2,

0xF8,

};

code unsigned char Hz1616_tou[]="头"; //对于数组内的汉字,编译会自动翻译成 机内码(2字节)

code unsigned char JN1616_tou[]= //机内码 头 网上有很多把汉字或者字符转换成相关编码的工具软件

{

0xCD,

0xB7,

};

code unsigned char Zf816_V[]="V"; //对于数组内的字符,编译会自动翻译成 ASCII码(1字节)

code unsigned char ASCII816_V[]= //ASCII码 V 网上有很多把汉字或者字符转换成相关编码的工具软件

{

0x56,

};

code unsigned char Zf816_5[]="5"; //对于数组内的字符,编译会自动翻译成 ASCII码(1字节)

code unsigned char ASCII816_5[]= //ASCII码 5 网上有很多把汉字或者字符转换成相关编码的工具软件

{

0x35,

};

code unsigned char Zf816_nc[]=" "; //对于数组内的字符,编译会自动翻译成 ASCII码(1字节)

code unsigned char ASCII816_nc[]= //ASCII码 空字符 网上有很多把汉字或者字符转换成相关编码的工具软件

{

0x20,

};

void main()

{

LCDInit(); //初始化12864 内部包含液晶模块的复位

/* 注释三:

* 12864的控制芯片st7920内部有两套驱动显示指令方式,一种是前面章节讲的自构字库模式,也是图像模式。

* 另外一种就是本节讲的用内部字库模式。以下是切换模式的命令,命令字0x0c表示用内部字库模式。

* 命令字0x36表示用自构字库模式。

*/

WriteCommand(0x0C); //命令字0x0c表示用内部字库模式。命令字0x36表示用自构字库模式。

display_clear(); // 清屏。4行8列的坐标点全部显示2个空字符相当于清屏了。

display_hz1616(0,0,Hz1616_man); //第一行,调用直接汉字书写方式的数组来显示(馒头V5),

display_hz1616(1,0,Hz1616_tou);

display_double_zf816(2,0,Zf816_V,Zf816_5);

display_hz1616(0,3,JN1616_man); //第四行,调用机内码和ASCII码的数组来显示(馒头V5),

display_hz1616(1,3,JN1616_tou);

display_double_zf816(2,3,ASCII816_V,Zf816_5);

while(1)

{

;

}

}

/* 注释四:在一个坐标点显示1个内部字库汉字的函数

* 第1,2个参数x,y是坐标体系。x的范围是0至8,y的范围是0至3.

* 第3个参数*ucArray是汉字机内码,是有2个字节的数组。

*/

void display_hz1616(unsigned int x,unsigned int y,const unsigned char *ucArray)

{

WriteCommand(0x30); //基本指令集

WriteCommand(ucAddrTable[8*y+x]); //起始位置

LCDWriteData(ucArray[0]);

LCDWriteData(ucArray[1]);

}

/* 注释五:在一个坐标点显示2个内部字库字符的函数

* 注意,由于一个坐标点是16x16点阵,而一个字符是8x16点阵的,所以务必要显示2个字符筹够1个坐标点。

* 第1,2个参数x,y是坐标体系。x的范围是0至8,y的范围是0至3.

* 第3个参数*ucArray1是左边第1个字符ASCII码,是有1个字节的数组。

* 第4个参数*ucArray2是右边第2个字符ASCII码,是有1个字节的数组。

*/

void display_double_zf816(unsigned int x,unsigned int y,const unsigned char *ucArray1,const unsigned char *ucArray2)

{

WriteCommand(0x30); //基本指令集

WriteCommand(ucAddrTable[8*y+x]); //起始位置

LCDWriteData(ucArray1[0]);

LCDWriteData(ucArray2[0]);

}

void display_clear(void) // 清屏。4行8列的坐标点全部显示2个空字符相当于清屏了。

{

unsigned int i,j;

for(i=0;i<4;i++)

{

for(j=0;j<8;j++)

{

display_double_zf816(j,i,Zf816_nc,ASCII816_nc); //Zf816_nc与ASCII816_nc本质是一样的,只是书写方式不一样。

}

}

}

void SendByteToLcd(unsigned char ucData) //发送一个字节数据到液晶模块

{

unsigned char i;

for ( i = 0; i < 8; i++ )

{

if ( (ucData << i) & 0x80 )

{

LCDSID_dr = 1;

}

else

{

LCDSID_dr = 0;

}

LCDCLK_dr = 0;

LCDCLK_dr = 1;

}

}

void SPIWrite(unsigned char ucWData, unsigned char ucWRS) //模拟SPI发送一个字节的命令或者数据给液晶模块的底层驱动

{

SendByteToLcd( 0xf8 + (ucWRS << 1) );

SendByteToLcd( ucWData & 0xf0 );

SendByteToLcd( (ucWData << 4) & 0xf0);

}

void WriteCommand(unsigned char ucCommand) //发送一个字节的命令给液晶模块

{

LCDCS_dr = 0;

LCDCS_dr = 1;

SPIWrite(ucCommand, 0);

delay_short(90);

}

void LCDWriteData(unsigned char ucData) //发送一个字节的数据给液晶模块

{

LCDCS_dr = 0;

LCDCS_dr = 1;

SPIWrite(ucData, 1);

}

void LCDInit(void) //初始化 函数内部包括液晶模块的复位

{

LCDRST_dr = 1; //复位

LCDRST_dr = 0;

LCDRST_dr = 1;

}

void delay_short(unsigned int uiDelayShort) //延时函数

{

unsigned int i;

for(i=0;i

{

;

}

}

总结陈词:

通过本节的实验,我们发现汉字的识别本质是机内码,字符的识别本质是ASCII码。不管是机内码还是ASCII码,这些都是16进制的数字,也就是我们手机平时接收和发送的信息本质都是这些数字编码,但是机内码是2个字节,ASCII码是1个字节,如果在一串随机的信息中,同时包含汉字和字符两种数字信息,我们的程序又该如何能筛选和识别它们,会不会把机内码和ASCII码搞混乱了?不会的。其实这两种编码都是有规律可以筛选识别的,欲知详情,请听下回分解-----液晶屏显示串口发送过来的任意汉字和字符。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

7月29日消息,LG Display已将其在美国的70项LCD液晶显示器相关专利转让给三星显示,值得注意的是,三星显示已于三年前退出LCD业务。

关键字: LCD 三星

HT16K24操作电压为2.4V~5.5V,内建I²C通信接口,提供三种LCD显示与按键模式:24SEG × 4COM + 24 KEY;22SEG × 6COM + 22 KEY;20SEG × 8COM + 20 K...

关键字: LCD MCU 蜂鸣器

离线GPS工具:跟踪、保存和查找具有距离和方位的航路点——没有网络,没有云,您的数据,您的规则。

关键字: GPS设备 LCD 微控制器 Arduino Uno

在技术上,LCD和OLED各有其独特之处。液晶电视通过控制液态晶体实现图像显示,其原理是在两片玻璃基板中夹入液态晶体,通过细小的电线控制水晶分子的方向。而OLED凭借自发光二极管带来更优的视角与色彩表现,其RGB色彩信号...

关键字: OLED LCD

双锁系统,通过键盘输入密码开门,客人来了用短信开门

关键字: LCD 双锁系统 L293D 变压器

在汽车显示系统领域,TFT LCD显示屏目前是车载显示面板的主流选择。与此同时,OLED和micro-LED显示屏也逐渐吸引了市场的广泛关注。为了适应不同的显示技术,我们需要开发相应的电源技术。TFT LCD显示屏通常使...

关键字: LCD OLED micro-LED

如今,汽车行业对先进显示屏的需求空前高涨,亟需能够实现更大尺寸、更高亮度、曲面设计、更高分辨率和更高对比度的解决方案。与此同时,各类新型车载显示屏也日益受到青睐。目前,TFT LCD是汽车平板显示技术的主流选择。OLED...

关键字: LCD OLED micro-LED

大家好,欢迎回来。在这个项目中,我们将学习如何使用键盘和LCD显示制作一个安全的基于Arduino的门锁。你可以用它来保护你的办公室、房间或家里的保险箱。要锁门和开锁,你需要在安全系统中输入密码。这确保了只有经过授权的人...

关键字: 键盘 LCD Arduino 电子门锁

April 1, 2025 ---- 乐金显示广州LCD 8.5代线今日(4月1日)正式交割至TCL华星光电,并改名为t11。至此,TCL华星光电将拥有2条6代、4条8.5代、1条8.6代和2条10.5代LCD产线。Tr...

关键字: 电视 PID面板 LCD

将您的树莓派Pico变成带有触摸屏界面的USB-HID设备!在这个项目中,我们将在Arduino IDE中设置编程环境,为3.5”Pico Touch LCD屏蔽配置库,测试基本功能,创建简单的按钮(用于复制和粘贴),显...

关键字: 树莓派 触摸屏 LCD Windows
关闭