第82节:调用液晶屏内部字库把一个任意数值的变量显示出来

发布者:心灵舞动最新更新时间:2016-03-16 来源: eefocus关键字:液晶屏  内部字库  任意数值  变量显示 手机看文章 扫描二维码
随时随地手机看文章
开场白:

本来这一节打算开始讲调用液晶屏内部字库时的反显程序,但是我担心跳跃太大,恐怕很多初学者跟不上,所以多插入这一节讲讲后面菜单程序中经常用到的基本功能,在调用内部字库的情况下,如何把一个任意数值的变量显示在液晶屏上。这一节的功能需求跟前面第76节是一模一样的,只不过前面的不是用自带字库,现在的是用自带字库而已。我们还是需要做一个变量转换成ASCII码的函数,以后只要调用这个转换函数就可以了。这一节就要把这个转换函数和框架思路教给大家。

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

(1)硬件平台:

基于朱兆祺51单片机学习板。

(2)实现功能:我们定义一个char型的全局变量,把它默认初始化为218,开机上电后,能看到正中间恰好显示这个全局变量的数值218。大家也可以试着更改它的默认初始值,只要不超过char型最大数值255范围,我们就会看到它上电后显示的就是这个初始值。

(3)源代码讲解如下:

#include "REG52.H"

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

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

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

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

sbit beep_dr=P2^7; //蜂鸣器的驱动IO口

void initial_myself(void);

void initial_peripheral(void);

void delay_long(unsigned int uiDelaylong);

unsigned char *number_to_ASCII(unsigned char ucBitNumber);

void display_service(void); //显示服务程序,在main函数里

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_double_code(unsigned int x,unsigned int y,const unsigned char ucArray1,const unsigned char ucArray2); //在一个坐标点显示1个汉字或者2个字符的函数

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

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,

};

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

code unsigned char ASCII816_1[]="1"; //1

code unsigned char ASCII816_2[]="2"; //2

code unsigned char ASCII816_3[]="3"; //3

code unsigned char ASCII816_4[]="4"; //4

code unsigned char ASCII816_5[]="5"; //5

code unsigned char ASCII816_6[]="6"; //6

code unsigned char ASCII816_7[]="7"; //7

code unsigned char ASCII816_8[]="8"; //8

code unsigned char ASCII816_9[]="9"; //9

code unsigned char ASCII816_nc[]=" "; //空格

/* 注释一:

* 以下变量就是本程序的任意变量,网友可以自己更改它的大小来测试本程序,不要超过255.

*/

unsigned char ucAnyNumber=218; //任意变量默认初始化为218。

unsigned char ucWd1Part1Update=1; //窗口1的第1个局部更新显示变量 1代表更新显示,响应函数内部会清零

void main()

{

initial_myself();

delay_long(100);

initial_peripheral();

while(1)

{

display_service(); //显示服务程序

}

}

/* 注释二:在一个坐标点显示1个汉字或者2个字符的函数

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

* 第3个参数ucArray1是第1个汉字机内码或者ASCII码。

* 第4个参数ucArray2是第2个汉字机内码或者ASCII码。

*/

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

{

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

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

LCDWriteData(ucArray1);

LCDWriteData(ucArray2);

}

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_code(j,i,0x20,0x20); //0x20是空格的ASCII码

}

}

}

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;

}

/* 注释三:

* 本程序的核心转换函数。

* 是可以把一位任意数字变量的函数转换成对应的ASCII码,由于ASCII码放在数组里,所以返回的是指针,代表数组的首地址。

*/

unsigned char *number_to_ASCII(unsigned char ucBitNumber)

{

unsigned char *p_ucAnyNumber; //此指针根据ucBitNumber数值的大小,分别调用不同的ASCII码。

switch(ucBitNumber) //根据ucBitNumber数值的大小,分别调用不同的ASCII码。

{

case 0:

p_ucAnyNumber=ASCII816_0;

break;

case 1:

p_ucAnyNumber=ASCII816_1;

break;

case 2:

p_ucAnyNumber=ASCII816_2;

break;

case 3:

p_ucAnyNumber=ASCII816_3;

break;

case 4:

p_ucAnyNumber=ASCII816_4;

break;

case 5:

p_ucAnyNumber=ASCII816_5;

break;

case 6:

p_ucAnyNumber=ASCII816_6;

break;

case 7:

p_ucAnyNumber=ASCII816_7;

break;

case 8:

p_ucAnyNumber=ASCII816_8;

break;

case 9:

p_ucAnyNumber=ASCII816_9;

break;

case 10:

p_ucAnyNumber=ASCII816_nc;

break;

default: //如果上面的条件都不符合,那么默认指向空格ASCII码

p_ucAnyNumber=ASCII816_nc;

break;

}

return p_ucAnyNumber; //返回转换结束后的指针

}

void display_service(void) //显示服务程序,在main函数里

{

/* 注释四:

* 这里的局部变量用static关键词修饰,是因为这个函数一直在主函数while(1)里循环扫描,我不希望它每次进来这个函数

* 都多花几条指令去初始化这些局部变量,这样会多耗掉几个指令,所以我就用static关键字避免了这种情况,让这些局部变量

* 只在上电那一刻就初始化了,以后每次进来这个函数不用再初始化这些变量。

*/

static unsigned char ucAnyNumber_1; //分解变量的个位

static unsigned char ucAnyNumber_10; //分解变量的十位

static unsigned char ucAnyNumber_100; //分解变量的百位

static unsigned char *p_ucAnyNumber_1; //经过数字转换成字模后,分解变量的个位字模首地址

static unsigned char *p_ucAnyNumber_10; //经过数字转换成字模后,分解变量的十位字模首地址

static unsigned char *p_ucAnyNumber_100; //经过数字转换成字模后,分解变量的百位字模首地址

if(ucWd1Part1Update==1) //窗口1的第1个局部更新显示变量,里面放一些经常需要刷新显示的内容

{

ucWd1Part1Update=0; //及时清零,避免一直更新

if(ucAnyNumber>=100) //有3位数以上

{

ucAnyNumber_100=ucAnyNumber/100; //百位

}

else //否则显示空

{

ucAnyNumber_100=10; //在下面的转换函数中,代码10表示空字模

}

if(ucAnyNumber>=10) //有2位数以上

{

ucAnyNumber_10=ucAnyNumber%100/10; //十位

}

else //否则显示空

{

ucAnyNumber_10=10; //在下面的转换函数中,代码10表示空字模

}

ucAnyNumber_1=ucAnyNumber%10/1; //个位

p_ucAnyNumber_100=number_to_ASCII(ucAnyNumber_100); //把数字转换成字符ASCII码

p_ucAnyNumber_10=number_to_ASCII(ucAnyNumber_10); //把数字转换成字符ASCII码

p_ucAnyNumber_1=number_to_ASCII(ucAnyNumber_1); //把数字转换成字符ASCII码

display_double_code(2,1,ASCII816_nc[0],p_ucAnyNumber_100[0]);//液晶屏的显示驱动函数 这里的ASCII816_nc[0]代表填充显示一个空格字符

display_double_code(3,1,p_ucAnyNumber_10[0],p_ucAnyNumber_1[0]);//液晶屏的显示驱动函数

}

}

void delay_short(unsigned int uiDelayShort)

{

unsigned int i;

for(i=0;i

{

;

}

}

void delay_long(unsigned int uiDelayLong)

{

unsigned int i;

unsigned int j;

for(i=0;i

{

for(j=0;j<500;j++) //内嵌循环的空指令数量

{

; //一个分号相当于执行一条空语句

}

}

}

void initial_myself(void) //第一区 初始化单片机

{

beep_dr=1; //用PNP三极管控制蜂鸣器,输出高电平时不叫。

}

void initial_peripheral(void) //第二区 初始化外围

{

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

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

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

}

总结陈词:

在液晶屏程序里,经常要用到反显的功能来表示选中某一项菜单。在调用内部字库时,这样的驱动程序又该怎么写?欲知详情,请听下回分解-----如何在调用液晶屏内部字库时让某行内容反显。

关键字:液晶屏  内部字库  任意数值  变量显示 引用地址:第82节:调用液晶屏内部字库把一个任意数值的变量显示出来

上一篇:第81节:液晶屏显示串口发送过来的任意汉字和字符
下一篇:第83节:矩阵键盘输入任意数字或小数点的液晶屏显示程序

推荐阅读最新更新时间:2024-03-16 14:47

STM8控制LCD12864液晶屏实验
第一部分 并口传输显示中英文 主要是以下几个函数: 首先:写一个LCD_write函数来给LCD发送数据.根据时序图,发送数据是RW要置0,E要产生下降沿,RS置1为数据,RS置0为命令,由于是并口传输PSB置1. 其次:能够给LCD发命令后,我们就要使用LCD_init函数发送初始化命令。初始化命令至少包括:1、设置显示,2、功能设定,3、初始化清屏3个部分。 写命令时注意每个命令都有自己的运行时间,记得保证足够延时。 第三:写一个LCD_display函数可以分行分列显示内容。 void LCD_write(u8 data,u8 cmd_flag); void LCD_init(void); void LCD_
[单片机]
STM8控制LCD12864<font color='red'>液晶屏</font>实验
三星32英寸液晶屏背光灯驱动电路分析
三星32英寸液晶屏内置16只灯管,随屏配套的灯管驱动电路板型号为KLS -320VE.该灯管驱动电路由两块BD9884及8组全桥架构功率输出电路组成,如图1所示。功率输出管采用内含N沟道和P沟道的Sp8M3型MOSFET模块。两只SP8M3模块及输出高压变压器T组成一个全桥输出架构电路。变压器初级绕组Ll接功率输出模块,次级高压绕组L2接冷阴极荧光灯管,次级低压绕组L3的感应电压作为取样电压送往BD9884FV的电压检测部分。 一、信号流程及工作原理简述 当数字板上的CPU发出"背光灯开"指令后,背光灯驱动板上的振荡器开始工作,产生频率约lOOkHz的振荡信号,送入调制器内部,对来自CPU的PWM亮度信号进行调制,调制
[电源管理]
三星32英寸<font color='red'>液晶屏</font>背光灯驱动电路分析
DS90CF364 LVDS发送/接收器在RGB液晶屏应用
  1 引言   当今,配备数字RGB接口的TFF液晶显示屏以其图像清晰、接口简单和亮度高等特点而在电脑笔记本、GPS、机顶盒、WebPad等设备中得到了广泛应用,但是由于驱动显示屏的视频信号频率较高而无法直接进行较远距离传输。为此,可以在图形控制器到LCD之间的FPD(Flat Panel Display)链路中采用LVDS(Low Voltage Differential Signaling)技术来克服这一问题,实际使用证明:经它引接后的传输距离可扩大至10米左右,从而充分满足了液晶屏的一般应用场合。   数字RGB视频信号中除了包括图像信号之外,还包括行同步、场同步、像素时钟等信号,其中像素时钟信号的最高频率可超过28MH
[嵌入式]
第76节:如何把一个任意数值变量显示液晶屏
开场白: 本来这一节打算开始讲液晶屏的菜单程序,但是我担心跳跃太大,恐怕很多初学者跟不上,所以多插入这一节讲讲后面菜单程序中经常用到的基本功能,如何把一个任意数值的变量显示在液晶屏上。我们需要做一个变量转换成字模的函数,以后只要调用这个转换函数就可以了。这一节就要把这个转换函数教给大家。 具体内容,请看源代码讲解。 (1)硬件平台: 基于朱兆祺51单片机学习板。 (2)实现功能:我们定义一个char型的全局变量,把它默认初始化为218,开机上电后,能看到正中间恰好显示这个全局变量的数值218。大家也可以试着更改它的默认初始值,只要不超过char型最大数值255范围,我们就会看到它上电后显示的就是这个初始值。 (3)源代码讲
[单片机]
PIC16F877单片机驱动1602液晶屏的数字时钟程序
4MHz时钟--PIC-KIT3。 main.c: #include #include #include Display.h #include main.h __CONFIG(WDTDIS & LVPDIS & HS & PWRTDIS & BORDIS); //设置877配置位 /************************定义显示字符*****************************************/ uchar Welcome_1 = { Welcome To Use }; //uchar Welcome_2 = { DSK-27 System ! }; //uchar Power_On1
[单片机]
51单片机——LCD1602液晶屏 C语言入门编程
LCD1602: 1602液晶也叫1602字符型液晶,它能显示2行字符信息,每行又能显示16个字符。它是一种专门用来显示字母、数字、符号的点阵型液晶模块。它是由若 干个5x7的点阵字符位组成,每个点阵字符位都可以用显示一个字符, 每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此,所以它不能很好的显示图片。 字符代码0x00~0x0F为用户自定义的字符图形RAM(对于5X8点阵的字符,可以存放8组,5X10点阵的字符,存放4组),就是CGRAM了。0x20~0x7F为标准的ASCII码,0xA0~0xFF为日文字符和希腊文字符,其余字符码(0x10~0x1F及0x80~0x9F)没有定义。写入
[单片机]
51单片机——LCD1602<font color='red'>液晶屏</font> C语言入门编程
【51单片机】(手把手教你)1602液晶屏-基础篇
1602液晶简介 1602液晶也叫1602字符型液晶,16x02,每行16个字符显示两行。它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自定义CGRAM,显示效果也不好)。 #度娘告知 引脚接口说明 1602液晶上有16个引脚,上面依次标了上述符号,与单片机上的接口依次对应连接即可,如图: 原理图 想知道如何操作液晶屏就需要看清楚自己单片机上与液晶屏连接引脚的控制原理图,我使用的是郭天祥的51单片
[单片机]
【51单片机】(手把手教你)1602<font color='red'>液晶屏</font>-基础篇
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多精选电路图
换一换 更多 相关热搜器件
更多每日新闻
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved