📄 lcd12864点.c
字号:
/***************************************************************************
标题: LCD12864程序
效果: 本程序在LCD12864液晶屏显示图形内容
******************************************************************************/
#include "AT89X52.H"
/********IO引脚定义***********************************************************/
sbit LCD_RS=P1^0;
sbit LCD_RW=P1^1;
sbit LCD_E=P1^2;
sbit PSB =P1^6; //PSB脚为12864-12系列的串、并通讯功能切换,我们使用8位并行接口,PSB=1
/********宏定义***********************************************************/
#define LCD_Data P0
/********函数声明*************************************************************/
void WriteDataLCD(unsigned char WDLCD); //写数据
void WriteCommandLCD(unsigned char WCLCD); //写指令
unsigned char ReadDataLCD(void); //读数据
void LCDInit(void); //初始化
void LCDClear(void); //清屏
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void DisplayImage (unsigned char DData); //输出128*64点阵数据
void Delay100us(void);
void Delay1ms(unsigned int c); //延时1毫秒
void LCDhuadian( unsigned char X, unsigned char Y,unsigned char color); //画点 color=1,点亮;color=0,擦除
void LCDshuipin( unsigned char X0, unsigned char X1, unsigned char Y,unsigned char color); //画水平线:
void LCDchuizhi( unsigned char X, unsigned char Y0, unsigned char Y1,unsigned char color); //画垂直线:
void LCDhuaxian(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char color);
/********数据定义*************************************************************/
code unsigned char uctech[] = {"我的单片机实验板"};
/***********主函数开始********************************************************/
void main(void)
{
Delay1ms(400); //启动等待,等LCD讲入工作状态
LCDInit(); //LCD初始化
while(1)
{
LCDClear(); //清屏
// Delay1ms(1000);
DisplayImage(255); //显示满屏点阵
Delay1ms(1000); //延时2000毫秒
LCDClear();
DisplayListChar(0,1,uctech); //显示字库中的中文数字
Delay1ms(1000);
LCDClear();
// LCDhuadian(6,10); //X坐标(0--127),Y坐标(0--63)
LCDshuipin( 0, 127 , 0 , 1 ); ; //画水平线:
LCDshuipin( 0, 127 , 15 ,1 ) ;
LCDshuipin( 0, 127 , 31 ,1 ) ;
LCDshuipin( 0, 127 , 47 ,1 ) ;
LCDshuipin( 0, 127 , 63 ,1 ) ;
LCDchuizhi( 0, 0 , 63 ,1 ) ; //画垂直线:
LCDchuizhi( 31, 0 , 63 ,1 ) ;
LCDchuizhi( 64, 0 , 63, 1 ) ;
LCDchuizhi( 96, 0 , 63 ,1 ) ;
LCDchuizhi( 127, 0 , 63 ,1 );
Delay1ms(2000);
LCDClear();
LCDhuaxian( 0, 0, 127, 63 , 1 ) ;
LCDhuaxian( 0, 0, 32, 63 , 1 ) ;
LCDhuaxian( 32, 0, 127, 63 , 1 ) ;
Delay1ms(2000);
}
}
/***********写数据********************************************************/
void WriteDataLCD(unsigned char WDLCD)
{
Delay100us(); //延时100微秒,检测忙
LCD_RS = 1;
LCD_RW = 0;
LCD_Data = WDLCD;
LCD_E = 1;
LCD_E = 1;
LCD_E = 1;
LCD_E = 0;
}
/***********写指令********************************************************/
void WriteCommandLCD(unsigned char WCLCD)
{
Delay100us(); //延时100微秒,检测忙
LCD_RS = 0;
LCD_RW = 0;
LCD_Data = WCLCD;
LCD_E = 1;
LCD_E = 1;
LCD_E = 1;
LCD_E = 0;
}
/***********读数据********************************************************/
unsigned char ReadDataLCD(void)
{
unsigned char LCDDA;
LCD_Data=0xff;
Delay100us(); //延时100微秒,检测忙
LCD_RS = 1;
LCD_RW = 1;
LCD_E = 1;
LCD_E = 1;
LCDDA=LCD_Data;
LCD_E = 0;
return(LCDDA);
}
/***********初始化********************************************************/
void LCDInit(void)
{
WriteCommandLCD(0x34);
WriteCommandLCD(0x30); //显示模式设置,开始要求每次检测忙信号
WriteCommandLCD(0x01); //显示清屏
WriteCommandLCD(0x06); // 显示光标移动设置
WriteCommandLCD(0x0C); // 显示开及光标设置
}
/***********清屏********************************************************/
void LCDClear(void)
{
WriteCommandLCD(0x01); //显示清屏
WriteCommandLCD(0x34); // 显示光标移动设置
WriteCommandLCD(0x30); // 显示开及光标设置
}
//**************画点函数**************//X坐标(0--127),Y坐标(0--63)color=1,点亮;color=0,擦除
void LCDhuadian( unsigned char X, unsigned char Y ,unsigned char color)
{
unsigned char x_1, lcd_x , lcd_y, yushu;
unsigned char Read_H, Read_L ;
WriteCommandLCD( 0x34 ) ; //设置扩充指令集,关闭绘图
WriteCommandLCD( 0x36 ) ; // 扩充指令集,打开绘图
lcd_x=X/16;
yushu=X % 16;
if( Y < 32 )
{
lcd_y=Y ;
x_1=0x80;
}
else
{
lcd_y = Y - 32;
x_1=0x88;
}
WriteCommandLCD( 0x80+lcd_y) ;
WriteCommandLCD( x_1+lcd_x) ;
// WriteCommandLCD( 0x30 ) ;
ReadDataLCD() ;
Read_H = ReadDataLCD() ;
Read_L = ReadDataLCD() ;
if (color)
{
if( yushu < 8 )
{
Read_H|=(1<<(7-yushu));
}
else
{
Read_L|=(1<<(15-yushu));
}
}
else
{
if( yushu < 8 )
{
Read_H&=~(1<<(7-yushu));
}
else
{
Read_L&=~(1<<(15-yushu));
}
}
// WriteCommandLCD( 0x34 ) ; //设置扩充指令集,关闭绘图
WriteCommandLCD( 0x80+lcd_y) ;
WriteCommandLCD( x_1+lcd_x) ;
// WriteCommandLCD( 0x30 ) ;
WriteDataLCD( Read_H ) ;
WriteDataLCD( Read_L ) ;
// WriteCommandLCD( 0x36 ) ; //设置扩充指令集,打开绘图
WriteCommandLCD( 0x30 ) ;
}
//*********画水平线:X0起始X1结束坐标(0--127),Y坐标(0--63)
void LCDshuipin( unsigned char X0, unsigned char X1, unsigned char Y,unsigned char color )
{ unsigned char Temp ;
if( X0 > X1 )
{
Temp = X1 ;
X1 = X0 ;
X0 = Temp ;
}
for( ; X0 <= X1 ; X0++ )
LCDhuadian( X0, Y,color) ;
}
//*********画垂直线:X坐标(0--127),Y0起始Y1结束坐标(0--63)
void LCDchuizhi( unsigned char X, unsigned char Y0, unsigned char Y1,unsigned char color)
{
unsigned char Temp ;
if( Y0 > Y1 )
{
Temp = Y1 ;
Y1 = Y0 ;
Y0 = Temp ;
}
for( ; Y0 <= Y1 ; Y0++)
LCDhuadian( X, Y0,color) ;
}
//************Bresenham画线算法画线
/*函数说明:使用Bresenham法,画任意两点间的直线
传入参数:(x0,y0),竖直线的起点;(x1,y1)竖直线的终点
color=1,点亮;color=0,擦除
传出参数:无
返回值: 无
*************************************************************/
void LCDhuaxian(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char color)
{
int dx; // 直线x轴差值变量
int dy; // 直线y轴差值变量
char dx_sym; // x轴增长方向,为-1时减值方向,为1时增值方向
char dy_sym; // y轴增长方向,为-1时减值方向,为1时增值方向
int dx_2; // dx*2值变量,用于加快运算速度
int dy_2; // dy*2值变量,用于加快运算速度
int di; // 决策变量
dx = x1-x0; // 求取两点之间的差值
dy = y1-y0;
if (dx<0) dx_sym=-1;
else
{
if(dx>0) dx_sym=1;
else
{
(x0,y0,y1,color);
return;
}
}
if(dy>0) dy_sym=1;
else
{
if(dy<0) dy_sym=-1;
else
{
LCDshuipin(x0,y0,x1,color);
return;
}
}
dx=dx_sym*dx;
dy=dy_sym*dy;
dx_2=dx*2;
dy_2=dy*2;
if(dx>=dy)
{
di=dy_2-dx;
while(x0!=x1)
{
LCDhuadian(x0,y0,color);
x0+=dx_sym;
if(di<0) di+=dy_2;
else {di+=dy_2-dx_2;y0+=dy_sym;}
}
LCDhuadian(x0,y0,color);
}
else
{
di=dx_2-dy;
while(y0!=y1)
{
LCDhuadian(x0,y0,color);
y0+=dy_sym;
if(di<0) di+=dx_2;
else {di+=dx_2-dy_2;x0+=dx_sym;}
}
LCDhuadian(x0,y0,color);
}
}
/***********按指定位置显示一个字符*******************************************/
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
if(Y<1)
Y=1;
if(Y>4)
Y=4;
X &= 0x0F; //限制X不能大于16,Y不能大于1
switch(Y)
{
case 1:X|=0X80;break;
case 2:X|=0X90;break;
case 3:X|=0X88;break;
case 4:X|=0X98;break;
}
WriteCommandLCD(X); //发送地址码
WriteDataLCD(DData);
}
/***********按指定位置显示一串字符*****************************************/
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
unsigned char ListLength,X2;
ListLength = 0;
X2=X;
if(Y<1)
Y=1;
if(Y>4)
Y=4;
X &= 0x0F; //限制X不能大于16,Y在1-4之内
switch(Y)
{
case 1:X2|=0X80;break; //根据行数来选择相应地址
case 2:X2|=0X90;break;
case 3:X2|=0X88;break;
case 4:X2|=0X98;break;
}
WriteCommandLCD(X2); //发送地址码
while (DData[ListLength]>=0x20){ //若到达字串尾则退出
if (X <= 0x0F)
{ //X坐标应小于0xF
WriteDataLCD(DData[ListLength]);
ListLength++;
X++;
Delay1ms(5);
}
}
}
/********输出128*64点阵数据************************************************/
void DisplayImage (unsigned char DData)
{
unsigned char x,y,i;
WriteCommandLCD(0x34);
for(i=0;i<9;) //分两屏,上半屏和下半屏,因为起始地址不同,需要分开
{
for(y=0;y<32;y++) //32行
// WriteCommandLCD(0x34);
// WriteCommandLCD(0x80+y); //列地址
// WriteCommandLCD(0x80+i); //行地址,下半屏,即第三行地址0X88
// WriteCommandLCD(0x30);
for(x=0;x<8;x++)
{
WriteCommandLCD(0x80+y); //列地址
WriteCommandLCD(0x80+x+i);
WriteDataLCD(DData);//读取数据写入LCD
WriteDataLCD(DData);//读取数据写入LCD
}
i+=8;
}
WriteCommandLCD(0x36); //扩充功能设定
WriteCommandLCD(0x30);
}
//************100微秒延时*******************************************************
void Delay100us(void) //误差 0us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=47;a>0;a--);
}
//****************(i x 1毫秒延时)******************************************
void Delay1ms(unsigned int c) //延时函数误差 0us
{
unsigned char a,b;
for(;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -