1、实验室有几个大屏LCD12864,不知道是不是带中文字库,这里不用中文,本身就屏幕不够大,所以之类显示英文或者字符,能显示更加多的内容。
2、为了节约管脚,这里使用了串行的方式进行通信和数据传输。博文后面的截图有说明。
3、利用stc8a8k芯片,下载的时候,选择22.1184Mhz晶振,所以需要设置好对应的延时函数,比如毫秒延时等,匹配。可以利用ISP软件的软件延时器生成的代码作为参考。
4、
实验目的:
利用LCD12864显示四行,分别显示字符,字符串,整数,浮点数。
多菜单的使用,如何实现多个页面,可以通过按键,切换页面。切换页面的时候,注意清屏。
接线
12864—开发板
GND–GND
VCC-5V
V0–5V
RS–P00
RW -P01
E–P02
DB0–DB7—不接。
PSB可以直接接GND,也可以通过单片机的IO口控制,当高电平的时候,并口控制用到DB0-DB7,当GND低电平的时候,串口控制。
NC不接。
RST不接,也可以通过单片机的IO口控制。复位,低电平复位。
VOUT可以不接。
A—5V
K–GND。
关键函数以及修改的地方说明。
第一个,
使用stc8a8k,22.1184Mhz晶振,由于是1T单片机,所以要和传统的89C52单片机(12T)的部分修改,主要是延时函数的修改。利用ISP的软件生成延时函数,作为参考。
第二个。
特别注意,特别注意的地方。特别注意的地方。
LCD12864是为了显示中文的多,所以本身是可以显示
0123456789012345共16个字符,但是当用坐标的设置,在那里显示的时候,y方向,横方向,注意当y=0的时候,包括了01这两个位置,当y=1的时候,显示在23这个位置。是多了一个。
因为一个中文等于两个字节。
例如我想显示一个字符,
LCD12864_set_xy(1,0);
LCD12864_Write_char( 1, 'a');
LCD12864_set_xy(2,1);
LCD12864_Write_char( 1, 'b');
LCD12864_set_xy(3,2);
LCD12864_Write_char( 1, 'c');
得到的效果是
得到的启示是什么呢?
显示数据的时候,比如小数等,需要在GUI规划的时候,显示在整整的地方,不然会被刷新掉。
这个时候,可以将上面修改成。
注意,LCD12864_Write_string函数,包括了setxy函数了。
多了一个冒号,那么后面的数据连接就很正常了。
第三个,
显示字符的步骤,首先要设置x,y位置。
参数1,x=1,2,3,4,四个中的一个,四行。
参数2,y=0,1,2,3,4,5,6,7,做多8个。因为上面说了,一个中文就两个字符。这里自己测试一下就行了。
LCD12864_Write_char( 1, ‘a’);
第一个必须是1,代表写数据,第二个是你想写的字符。。
上面不推荐用,建议用写字符串的函数。。
第四个,写字符串的函数。
参数1,参数2和上面的一样,
参数1范围在1,2,3,4之间,
参数2范围在0,1,2,3,4,5,6,7之间。
这个会自己加页的。最好一行显示一行显示,不要等到串行。
第五个函数,写整数。
后面的三,是3位数。
第6个函数。写小数。3个正,2个小数,如123.45
/********************************************************/
//999.99---99.99;---0. ik=32意思是3个整数,两个小数;
//ik=22,意思是2个整数,2个小数
void LCD12864_Write_Float(float float_temp,char ik)
{
int float_temp0;
unsigned char floatdisbuf[5];
switch(ik)
{
case 32://123.45
float_temp0=float_temp*100;
floatdisbuf[0]=float_temp0/10000;
floatdisbuf[1]=float_temp0/1000%10;
floatdisbuf[2]=float_temp0/100%10;
floatdisbuf[3]=float_temp0/10%10;
floatdisbuf[4]=float_temp0%10;
LCD12864_Write_number( floatdisbuf[0]);
LCD12864_Write_number( floatdisbuf[1]);
LCD12864_Write_number( floatdisbuf[2]);
LCD12864_Write_number(11);
LCD12864_Write_number( floatdisbuf[3]);
LCD12864_Write_number( floatdisbuf[4]);
break;
case 22://99.99
float_temp0=float_temp*100;
floatdisbuf[0]=float_temp0/1000;
floatdisbuf[1]=float_temp0/100%10;
floatdisbuf[2]=float_temp0/10%10;
floatdisbuf[3]=float_temp0%10;
LCD12864_Write_number(floatdisbuf[0]);
LCD12864_Write_number(floatdisbuf[1]);
LCD12864_Write_number(11);
LCD12864_Write_number( floatdisbuf[2]);
LCD12864_Write_number( floatdisbuf[3]);
break;
case 21://10.9
float_temp0=float_temp*100;
floatdisbuf[0]=float_temp0/1000;
floatdisbuf[1]=float_temp0/100%10;
floatdisbuf[2]=float_temp0/10%10;
floatdisbuf[3]=float_temp0%10;
LCD12864_Write_number(floatdisbuf[0]);
LCD12864_Write_number(floatdisbuf[1]);
LCD12864_Write_number(11);
LCD12864_Write_number( floatdisbuf[2]);
// LCD12864_Write_number( floatdisbuf[3]);
break;
default:break;
}
}
案例代码:
main.c
#include <stc8a8k.h>
#include <LCD12864B.h>
#include <delay.h>
#include <stdio.h>
//**********************************************************
//*******************************函数声明*********************
//****************************************************************
//*******************************主函数************************
int main()
{
int intnum=123456;
float flnum=895.32;
char chartemp='C';
//显示屏初始化
LCD12864_Init(); //初始化LCD
LCD12864_Clr_Scr();//清屏函数
LCD12864_Write_string(1,0 ,"0123456789012345");
delay_ms(1000);
LCD12864_Write_string(1,0 ,"....welcome ");
delay_ms(1000);
LCD12864_Write_string(1,0 ,"........welcome ");
delay_ms(1000);
LCD12864_Clr_Scr();//清屏函数
// LCD12864_Write_string(1, 0 ,"X:000.00 S0.00");
// LCD12864_Write_string(2, 0 ,"Y:000.00 mode:1");
// LCD12864_Write_string(3, 0 ,"vpuL55555 k11");
// LCD12864_Write_string(4, 1 ,"41aeafafa@#");
delay_ms(1000);
LCD12864_Clr_Scr();//清屏函数
delay_ms(1000);
LCD12864_set_xy(1,0);
LCD12864_Write_char( 1, 'a');
LCD12864_set_xy(2,1);
LCD12864_Write_char( 1, 'b');
LCD12864_set_xy(3,2);
LCD12864_Write_char( 1, 'c');
delay_ms(2000);
LCD12864_Clr_Scr();//清屏函数
//GUI界面
//0123456789012345
//>>sec:123456
//>>float:123.456
LCD12864_Write_string(1,7,">>sec:");
LCD12864_Write_string(2,7,">>float:");
intnum=0;
flnum=100.0f;
while(1)
{
//显示整数
LCD12864_set_xy(1,3);
LCD12864_Write_U16(intnum,3);
intnum++;
LCD12864_set_xy(2,4);
LCD12864_Write_Float(flnum,32);
flnum=flnum+0.01;
delay_ms(1000);
}
}
delay.c
#include <delay.h>
//
void delay_ms(unsigned int ms0) //@22.1184M
{ //
unsigned int i;
unsigned int tms;
for(tms=ms0;tms>0;tms--)
{
for(i=5000;i>0;i--)
{
}
}
}
delay.h
//
void delay_ms(unsigned int ms0) ; //@22.1184,stc8a8k
/
LCD12864.h
//引脚定义
#include <stc8a8k.h>
sbit LCD12864_CS = P0 ^ 0; //片选 高电平有效 单片LCD使用时可固定高电平
sbit LCD12864_SID = P0 ^ 1; //数据
sbit LCD12864_SCLK = P0^ 2; //时钟
sbit LCD12864_PSB = P0 ^3; //PSB
extern unsigned char LCD12864_num[13];
void LCD12864_Init(void); //初始化LCD
//****************************start=0 写指令,start=1,写数据
void LCD12864_Write_char(bit start, unsigned char ddata); //写指令或数据
void LCD12864_Send_byte(unsigned char bbyte); //发送一个字节
void LCD12864_Delaynms(unsigned int di); //延时
void LCD12864_Clr_Scr(void);//清屏函数
void LCD12864_set_xy( unsigned char x, unsigned char y );
void LCD12864_Write_string(unsigned char X,unsigned char Y,unsigned char *s);
void LCD12864_Write_number(unsigned char s);// 数字显示1个数的函数
//******************************************************
//u16temp是传来的数据,char i是多少位1-5
void LCD12864_Write_U16(int u16temp,char i);
/********************************************************/
//999.99---99.99;---0. ik=32意思是3个整数,两个小数;
//ik=22,意思是2个整数,2个小数
void LCD12864_Write_Float(float float_temp,char ik);
LCD12864.c
#include <LCD12864B.h>
unsigned char LCD12864_num[13]={"0123456789:.-"};
//**********************
/******************************************************************************/
void LCD12864_Delaynms(unsigned int di) //延时
{
unsigned int da,db;
for(da=0;da<di;da++)
for(db=0;db<5307;db++);
}
/******************************************************************************/
void LCD12864_Init(void) //初始化LCD
{
LCD12864_PSB = 0;
LCD12864_Delaynms(10); //启动等待,等LCM讲入工作状态
LCD12864_CS=1;
LCD12864_Write_char(0,0x30); //8 位介面,基本指令集
LCD12864_Write_char(0,0x0c); //显示打开,光标关,反白关
LCD12864_Write_char(0,0x01); //清屏,将DDRAM的地址计数器归零
}
//****************************
/******************************************************************************/
void LCD12864_Write_char(bit start, unsigned char ddata) //写指令或数据
{
unsigned char start_data,Hdata,Ldata;
if(start==0)
start_data=0xf8; //写指令
else
start_data=0xfa; //写数据
Hdata=ddata&0xf0; //取高四位
Ldata=(ddata<<4)&0xf0; //取低四位
LCD12864_Send_byte(start_data); //发送起始信号
LCD12864_Delaynms(2); //延时是必须的
LCD12864_Send_byte(Hdata); //发送高四位
LCD12864_Delaynms(1); //延时是必须的
LCD12864_Send_byte(Ldata); //发送低四位
LCD12864_Delaynms(1); //延时是必须的
}
//***************************************
/******************************************************************************/
void LCD12864_Send_byte(unsigned char bbyte) //发送一个字节
{
unsigned char i;
unsigned int j;
for(i=0;i<8;i++)
{
LCD12864_SID=bbyte&0x80; //取出最高位
LCD12864_SCLK=1;
for(j=0;j<30;j++);
LCD12864_SCLK=0;
for(j=0;j<30;j++);
bbyte<<=1; //左移
}
}
***************************************
///******************************************************************************/
//void LCD12864_Disp_img(unsigned char *img) //图形方式12864显示字模221 横向取膜
//{
// unsigned char i,j;
// unsigned int k = 0;
// LCD12864_Write_char(0,0x36); //图形方式
// for(i=0;i<32;i++)
// {
// LCD12864_Write_char(0,0x80+i);
// LCD12864_Write_char(0,0x80);
// for(j=0;j<16;j++)
// {
// LCD12864_Write_char(1,img[k++]);
// }
// }
// for(i=0;i<32;i++)
// {
// LCD12864_Write_char(0,0x80+i);
// LCD12864_Write_char(0,0x88);
// for(j=0;j<16;j++)
// {
// LCD12864_Write_char(1,img[k++]);
// }
// }
//}
//*******************
/******************************************************************************/
void LCD12864_Clr_Scr(void)//清屏函数
{
LCD12864_Write_char(0,0x01);
}
/******************************************************************************/
void LCD12864_set_xy( unsigned char x, unsigned char y )
{ //设置LCD显示的起始位置,X为行,Y为列
unsigned char address;
switch(x)
{
case 0: address = 0x80 + y; break;
case 1: address = 0x80 + y; break;
case 2: address = 0x90 + y; break;
case 3: address = 0x88 + y; break;
case 4: address = 0x98 + y; break;
default:address = 0x80 + y; break;
}
LCD12864_Write_char(0, address);
}
//***************************
/******************************************************************************/
void LCD12864_Write_string(unsigned char X,unsigned char Y,unsigned char *s)
{ // 中英文字符串显示函数
LCD12864_set_xy( X, Y );
while (*s)
{
LCD12864_Write_char( 1, *s );
s ++;
LCD12864_Delaynms(1);
}
}
/******************************************************************************/
void LCD12864_Write_number(unsigned char s)// 数字显示函数
{
LCD12864_Write_char(1,LCD12864_num[s]);
LCD12864_Delaynms(1);
}
//***************************
//******************************************************
//u16temp是传来的数据,char i是多少位1-5
//
void LCD12864_Write_U16(int u16temp,char i)
{
switch(i)
{
case 1://1位数
LCD12864_Write_number(u16temp);
break;
case 2://两位数
LCD12864_Write_number(u16temp/10);
LCD12864_Write_number(u16temp%10);
break;
case 3:
LCD12864_Write_number(u16temp/100);
LCD12864_Write_number(u16temp/10%10);
LCD12864_Write_number(u16temp%10);
break;
case 4:
LCD12864_Write_number(u16temp/1000);
LCD12864_Write_number(u16temp/100%10);
LCD12864_Write_number(u16temp/10%10);
LCD12864_Write_number(u16temp%10);
break;
case 5:
LCD12864_Write_number(u16temp/10000);
LCD12864_Write_number(u16temp/1000%10);
LCD12864_Write_number(u16temp/100%10);
LCD12864_Write_number(u16temp/10%10);
LCD12864_Write_number(u16temp%10);
break;
default:break;
}
}
/********************************************************/
//999.99---99.99;---0. ik=32意思是3个整数,两个小数;
//ik=22,意思是2个整数,2个小数
void LCD12864_Write_Float(float float_temp,char ik)
{
int float_temp0;
unsigned char floatdisbuf[5];
switch(ik)
{
case 32://123.45
float_temp0=float_temp*100;
floatdisbuf[0]=float_temp0/10000;
floatdisbuf[1]=float_temp0/1000%10;
floatdisbuf[2]=float_temp0/100%10;
floatdisbuf[3]=float_temp0/10%10;
floatdisbuf[4]=float_temp0%10;
LCD12864_Write_number( floatdisbuf[0]);
LCD12864_Write_number( floatdisbuf[1]);
LCD12864_Write_number( floatdisbuf[2]);
LCD12864_Write_number(11);
LCD12864_Write_number( floatdisbuf[3]);
LCD12864_Write_number( floatdisbuf[4]);
break;
case 22://99.99
float_temp0=float_temp*100;
floatdisbuf[0]=float_temp0/1000;
floatdisbuf[1]=float_temp0/100%10;
floatdisbuf[2]=float_temp0/10%10;
floatdisbuf[3]=float_temp0%10;
LCD12864_Write_number(floatdisbuf[0]);
LCD12864_Write_number(floatdisbuf[1]);
LCD12864_Write_number(11);
LCD12864_Write_number( floatdisbuf[2]);
LCD12864_Write_number( floatdisbuf[3]);
break;
case 21://10.9
float_temp0=float_temp*100;
floatdisbuf[0]=float_temp0/1000;
floatdisbuf[1]=float_temp0/100%10;
floatdisbuf[2]=float_temp0/10%10;
floatdisbuf[3]=float_temp0%10;
LCD12864_Write_number(floatdisbuf[0]);
LCD12864_Write_number(floatdisbuf[1]);
LCD12864_Write_number(11);
LCD12864_Write_number( floatdisbuf[2]);
// LCD12864_Write_number( floatdisbuf[3]);
break;
default:break;
}
}
附录:LCD12864手册截图。