开场白:
原本这一节计划开端讲调用液晶屏内部字库时的反显程序,可是我忧虑跳动太大,恐怕许多初学者跟不上,所以多刺进这一节讲讲后边菜单程序中常常用到的根本功用,在调用内部字库的状况下,怎样把一个恣意数值的变量显现在液晶屏上。这一节的功用需求跟前面第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个空字符相当于清屏了。
}
总结陈词:
在液晶屏程序里,常常要用到反显的功用来表明选中某一项菜单。在调用内部字库时,这样的驱动程序又该怎样写?欲知概况,请听下回分化—–怎样在调用液晶屏内部字库时让某行内容反显。