📄 lcddrv.c
字号:
/****************************************************
** 液晶底层驱动
** 160*128
**版本: V1.02
**说明:包含最基本的液晶显示功能,包括清屏,矩形填充
**显示汉字及西文字符
******************************************************
**V1.01
**修正了初始化函数,将背光的产生,液晶初始化,清屏
统一到同一个函数 LCD_Init(uint16)
**V1.02
**修正了颜色显示问题(数据位数的问题)
部分函数名字修正 LCD_PutChar
GUI_RectangleFill
*****************************************************/
#include"GUICONFIG.h"
#include"guiconfig.h"
#if HZ
#include"GB16x16.h" //完全的汉字字库
#else
#include"GB1616.h" //部分选择的汉字字库
#endif
#include"8x8h.h"
#include"8x16.h"
volatile uint8 Font=1; //默认以大字体显示
//定义RST控制
#define SRST() IO0SET=LCD_RST
#define CRST() IO0CLR=LCD_RST
//定义CS控制
#define S_CS() IO0SET=LCD_CS
#define CCS() IO0CLR=LCD_CS
//定义RD控制
#define SRD() IO0SET=LCD_RD
#define CRD() IO0CLR=LCD_RD
//定义RS控制
#define SRS() IO1SET=LCD_RS
#define CRS() IO1CLR=LCD_RS
//定义RW控制
#define SRW() IO1SET=LCD_RW
#define CRW() IO1CLR=LCD_RW
/*----------------------------------------------------------*\
| Backlight Initialize 背光的初始化 |
\*----------------------------------------------------------*/
void BacklightOn(void)
{
PINSEL1 &= 0xFFFFF3FF;
PINSEL1 |= 0x00000400; // 设置PWM5连接到P0.21管脚
PWMPR = 0x00; // 不分频,计数频率为Fpclk
PWMMR0 = 50; // 设置PWM周期,PWMMR0=50
PWMMR5 = 6; // 设置PWM占空比,PWMMR5=8
PWMLER = 0x20; // PWMMR0、PWMMR5锁存,更新PWM占空比
PWMPCR = 0x2000; // 允许PWM5输出,单边PWM
PWMTCR = 0x09; // 启动定时器,PWM使能
}
/*----------------------------------------------------------*\
| Delay |
\*----------------------------------------------------------*/
void Delay1Ms(unsigned int tmr)
{
while( tmr )
{
unsigned int i;
for(i=0;i<10;i++);
tmr--;
}
}
/* ------ LOW LEVEL OPERATE ------ */
//对于液晶所用端口线的初始化
void LCD_Bus_Initial( void )
{
//PINSEL2 = 0x00000004;
//S_CS=0x03; //设置快速FGPIO
//FIO0MASK = ~(LCD_BUS_RST | LCD_BUS_CS | LCD_BUS_RD); // 允许快速I/O
IO0DIR = LCD_RST | LCD_CS | LCD_RD; //定义输出
//FIO1MASK = ~(LCD_RS | LCD_RW | LCD_DAT); // 允许快速I/O
IO1DIR = LCD_RS | LCD_RW;
IO0CLR = LCD_RST; //液晶复位
Delay1Ms( 20 );
IO0SET = LCD_RST | LCD_CS | LCD_RD;
IO1SET = LCD_RS | LCD_RW;
}
/************************************************
功能:在液晶上写一字节
**************************************************/
void LCD_Bus_Write_Byte( unsigned char Data )
{
unsigned int d = (((unsigned int)Data)<<16) & LCD_DAT;
IO1CLR = LCD_DAT; // data on bus
IO1SET = d;
//IO1PIN = ((unsigned int)Data)<<16;
IO1CLR = LCD_RW; // RW to LOW
//Delay1Ms( 1 );
IO1SET = LCD_RW; // RW to HIGH
}
/**************************************************
功能:在液晶上写一半字 在写液晶颜色的时候有用
****************************************************/
void LCD_Bus_Write_Data( uint16 Data )
{
LCD_Bus_Write_Byte(Data>>8);
LCD_Bus_Write_Byte(Data);
}
uint16 LCD_Bus_Read_Byte( void )
{
uint16 BusData;
CRD(); // RD to LOW
BusData = IO1PIN;
Delay1Ms( 1 );
SRD(); // RD to HIGH
return (BusData>>16)&0xFF;
}
/*****************************************
以下三个函数构成了液晶的基本驱动函数
******************************************/
/***********************************************
写命令子函数 RS为低电平时表示写命令
************************************************/
void LCD_WrCommand(unsigned int Cmd) //写命令
{
IO1DIR|=LCD_DAT;
CCS();
SRD();
CRS(); //RS=0 发送命令
LCD_Bus_Write_Byte(Cmd);
S_CS();
IO1DIR&=~LCD_DAT;
}
/***********************************************
写数据子函数 RS为高电平时表示写数据
************************************************/
void LCD_WrData(unsigned int Dat) //写数据
{
IO1DIR|=LCD_DAT;
CCS();
SRD();
SRS(); //RS=1 发送数据
LCD_Bus_Write_Byte(Dat);
S_CS();
IO1DIR&=~LCD_DAT;
}
/***********************************************
寄存器操作子函数,先写命令,确定是何种功
能,再讲对应数据写进去
************************************************/
void LCD_Write_Reg_Data(uint8 Cmd,uint8 Dat) //对寄存器进行操作
{
LCD_WrCommand(Cmd);
LCD_WrData(Dat);
}
/*----------------------------------------------------------*\
| LCD Initialize
液晶的初始化
这是一个低级函数,主要完成显示的初始化 |
\*----------------------------------------------------------*/
void LCD_Initial(void)
{
LCD_Bus_Initial(); //端口线初始化
LCD_WrCommand(0x11); // sleep out/power on(SLPOUT)
Delay1Ms(150);
LCD_WrCommand(0x20); // display inversion off
LCD_WrCommand(0x38); // ID mode off (IDMOFF)
LCD_WrCommand(0x13); // Normal display mode on (Partial mode off)
// color mode Interface pixel format (COLMOD)
LCD_Write_Reg_Data(0x3A,0x05); // 16-bit/pixel , 1-times data transfer
LCD_Write_Reg_Data(0xC0,0x03); // power control 1 (PWCTR1) , GVDD voltage set 4.65
LCD_Write_Reg_Data(0xC1,0x05); // VCOMH voltage set 4.10V
Delay1Ms(20);
LCD_Write_Reg_Data(0xC5,0xBA); // VCOMAC voltage set 4.35V
LCD_Write_Reg_Data(0xC6,0x10); // VCOMAC voltage set 4.35V
Delay1Ms(20);
// Gamma voltage adjustalbe level
//Gamma + Polarity correction characteristics set
LCD_WrCommand(0xE0);
LCD_WrData(0x01);
LCD_WrData(0x0A);
LCD_WrData(0x11);
LCD_WrData(0x23);
LCD_WrData(0x20);
LCD_WrData(0x01);
LCD_WrData(0x1E);
LCD_WrData(0x02);
LCD_WrData(0x06);
LCD_WrData(0x05);
LCD_WrData(0x0E);
LCD_WrData(0x0D);
LCD_WrData(0x01);
LCD_WrData(0x05);
LCD_WrData(0x03);
LCD_WrData(0x06);
//Gamma + Polarity correction characteristics set
LCD_WrCommand(0xE1);
LCD_WrData(0x01);
LCD_WrData(0x20);
LCD_WrData(0x23);
LCD_WrData(0x11);
LCD_WrData(0x0A);
LCD_WrData(0x01);
LCD_WrData(0x02);
LCD_WrData(0x1E);
LCD_WrData(0x06);
LCD_WrData(0x03);
LCD_WrData(0x05);
LCD_WrData(0x01);
LCD_WrData(0x0D);
LCD_WrData(0x0E);
LCD_WrData(0x05);
LCD_WrData(0x06);
// memory data access control (MADCTR)
LCD_Write_Reg_Data(0x36,0xA0); // MY=1; MX=0; MV=0; ML=0; RGB=0
LCD_WrCommand(0x37);
LCD_WrData(0x00);
LCD_WrData(0x00);
// display on
LCD_WrCommand(0x29);
}
/*******************************************************
函数名称:LCD_SetArea
功能:0x2A columset 0X2B row set 两条指令完成对应区域
的选定
*********************************************************/
void LCD_SetArea( uint8 x0, uint8 y0, uint8 x1, uint8 y1 )
{
LCD_WrCommand(0x2A); // colum address set
LCD_WrData(0x00);
LCD_WrData(x0+1);
LCD_WrData(0x00);
LCD_WrData(x1+1);
LCD_WrCommand(0x2B); //row address set
LCD_WrData(0x00);
LCD_WrData(y0+1);
LCD_WrData(0x00);
LCD_WrData(y1+1);
}
/**************************************************************
函数名称:LCD_Rectangle()
功能:实现矩形填充
***************************************************************
V1.01 修改函数名称为GUI_RectangleFill()
GUI_Rectangle()为显示一个空心矩形
***************************************************************/
void GUI_RectangleFill( uint8 x0, uint8 y0,uint8 x1, uint8 y1, uint16 Data )
{
int x,y;
LCD_SetArea(x0,y0,x1,y1);
LCD_WrCommand(0x2C); //Memory write
IO1DIR |= LCD_DAT;
CCS(); //chip selected
SRD();
SRS(); //send data
for(x=0;x<=x1-x0;x++)
{
for(y=0;y<=y1-y0;y++)
{
LCD_Bus_Write_Data(Data);
}
}
S_CS();
IO1DIR &= ~LCD_DAT;
}
//清屏子函数 选定所有液晶区域即可
void LCD_Clear_Screen( uint16 Data )
{
GUI_RectangleFill(0,0,159,128, Data );
}
/*******************************************
函数名称:液晶总初始化子函数
功能:写入入口参数为背景色即可
*******************************************/
void LCD_Init(uint16 color)
{
BacklightOn();
BacklightOn();
LCD_Initial();
LCD_Clear_Screen(color);
}
/********************************************
函数名称:GUI_Point()
功能 画点子函数
**********************************************/
void GUI_Point(uint8 x,uint8 y,uint16 color)
{
if(x>159)return ;
if(y>128)return ;
LCD_SetArea(x,y,x,y);
LCD_WrCommand(0x2c);
IO1DIR |= LCD_DAT;
CCS(); //chip selected
SRD();
SRS();
LCD_Bus_Write_Data(color);
S_CS();
IO1DIR &= ~LCD_DAT;
}
/*************************************************************
**以下程序为控制液晶显示西文及中文字符
**
*************************************************************/
/******************************
** 函数名称:显示1个8x8字符
**入口参数: x,y字符在液晶上的坐标位置
ch 字符
f face color
b Back color
********************************/
void LCD_Putchar8x8(uint8 x,uint8 y,uint8 ch,uint16 f,uint16 b)
{
register uint8 i,j; //使用很频繁的变量
LCD_SetArea(x,y,x+8-1,y+8-1);
LCD_WrCommand(0x2c);
IO1DIR |= LCD_DAT;
CCS(); //chip selected
SRD();
SRS();
for(i=0;i<8;i++)
{
unsigned char m=Font8x8[ch][i];
for(j=0;j<8;j++)
{
if((m&0x80)==0x80)
{
LCD_Bus_Write_Data(f); //如果该位为1,写表面颜色
}
else
{
LCD_Bus_Write_Data(b); //不为1,写背景颜色
}
m<<=1; //总共要判断8次
}
}
S_CS();
IO1DIR &= ~LCD_DAT;
}
/******************************
** 函数名称:显示1个8x16字符
**入口参数: x,y字符在液晶上的坐标位置
ch 字符
f face color
b Back color
********************************/
void LCD_Putchar8x16(uint8 x,uint8 y,uint8 ch,uint16 f,uint16 b)
{
register uint8 i,j; //使用很频繁的变量
LCD_SetArea(x,y,x+8-1,y+16-1);
LCD_WrCommand(0x2c);
IO1DIR |= LCD_DAT;
CCS(); //chip selected
SRD();
SRS();
for(i=0;i<16;i++)
{
unsigned char m=Font8x16[ch*16+i];
for(j=0;j<8;j++)
{
if((m&0x80)==0x80)
{
LCD_Bus_Write_Data(f); //如果该位为1,写表面颜色
}
else
{
LCD_Bus_Write_Data(b); //不为1,写背景颜色
}
m<<=1; //总共要判断8次
}
}
S_CS();
IO1DIR &= ~LCD_DAT;
}
/*显示单个字符,西文字符*/
void LCD_PutChar(unsigned short x, unsigned short y,unsigned char c, unsigned int f, unsigned int b)
{
if(Font)
{ //ASCII码小于127为西文字符
LCD_Putchar8x16(x,y,c,f,b); //显示8x16字符
}
else
{
LCD_Putchar8x8(x,y,c,f,b); //显示8x8字符
}
}
/***********部分汉字及西文的显示程序******************************/
#if !HZ //如果对汉字字库选择为0的话,选择编译这一部分程序
/******************************
** 函数名称:显示1个16x16字符
**入口参数: x,y字符在液晶上的坐标位置
ch 字符
f face color
b Back color
********************************/
void PutGB1616(uint8 x,uint8 y,uint8 c[2],uint8 f,uint8 b)
{
register uint8 i,j,k; //使用很频繁的变量
LCD_SetArea(x,y,x+16-1,y+16-1);
LCD_WrCommand(0x2c);
IO1DIR |= LCD_DAT;
CCS(); //chip selected
SRD();
SRS();
for (k=0;k<49;k++)
{
if ((codeGB_16[k].Index[0]==c[0])&&(codeGB_16[k].Index[1]==c[1]))
{
for(i=0;i<32;i++)
{
unsigned short m=codeGB_16[k].Msk[i];
for(j=0;j<8;j++)
{
if((m&0x80)==0x80)
{
LCD_Bus_Write_Byte(f>>8);
LCD_Bus_Write_Byte(f);
}
else
{
LCD_Bus_Write_Byte(b>>8);
LCD_Bus_Write_Byte(b);
}
m<<=1;
}
}
}
}
S_CS();
IO1DIR &= ~LCD_DAT;
}
/*显示一串字符串包括中文和西文字符*/
void LCD_PutString(unsigned short x, unsigned short y, unsigned char *s, unsigned int f, unsigned int b)
{
register unsigned char l=0;
while(*s)
{
if( *s < 0x80 )
{
LCD_PutChar(x+l*8,y,*s,f,b);
s++;
l++;
}
else
{
PutGB1616(x+l*8,y,(unsigned char *)s,f,b); //显示16x16汉字
s+=2;l+=2;
}
}
}
#else
/************************************************************************/
//选择编译汉字字库
extern const char data[];
void LCD_PutHZ(uint8 x,uint8 y,unsigned char *c,uint16 f, uint16 b)
{
uint32 ch,i;
uint8 m,j;
LCD_SetArea(x,y,x+16-1,y+16-1);
LCD_WrCommand(0x2c); //提示要把数据写进液晶内存里面
IO1DIR |= LCD_DAT;
CCS(); //chip selected
SRD();
SRS();
ch=(((*c-0xa1)*94)+((*(c+1)-0xa1)))<<5; //获取字码表的地址
for(i=ch;i<ch+32;i++)
{
m=data[i];
for(j=0;j<8;j++)
{
if((m&0x80)==0x80)
{
LCD_Bus_Write_Byte(f>>8);
LCD_Bus_Write_Byte(f);
}
else
{
LCD_Bus_Write_Byte(b>>8);
LCD_Bus_Write_Byte(b);
}
m<<=1;
}
}
}
void PutGBString(uint8 x, uint8 y, unsigned char *c, uint16 f,uint16 b)
{
unsigned char s[2];
uint8 i,j;
uint8 flag=0;
i=0; j=0;
while(*c)
{
if((*c&0x80)!=0) //对于汉字的显示处理
{
if((x+i*16+j*8)>(160-16))
{
i=0;
j=0;
y=y+16;
x=0;
flag++;
if(flag==8)y=0;
}
s[0]=*c;
s[1]=*(c+1);
LCD_PutHZ(x+i*16+j*8,y,s,f,b);
i=i+1;
c=c+2;
}
else
{
if((x+i*16+j*8)>(160-8))
{
i=0;
j=0;
y=y+16;
x=0;
flag++;
if(flag==8)y=0;
}
s[0]=*c;
LCD_PutChar(x+i*16+j*8,y,*s,f,b);
j=j+1;
c=c+1;
}
if((x+i*16+j*8)>160)
{
i=0;
j=0;
y=y+16;
x=0;
flag++;
if(flag==8)y=0;
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -