当前位置:文档之家› LCDDRIVE

LCDDRIVE

/****************************************************************************************
* 文件名:LCDDRIVE.C
* 功能:图形液晶160*160驱动(驱动型号为uc1698)。显示是横向字节,高位
* 在前。
* 说明:图形液晶采用UC1698为LCD控制芯片,内带负压产生器,单3.3伏供电,并行接口(使用stm32f103rbt6驱动)。
* 硬件连接: D0--D7 <===> GPIOA0--GPIOA7
* /WR <===> GPIOB1
* /RD <===> GPIOB6
* /CS <===> GPIOB7
* C/D <===> GPIOB8
* /RST <===> GPIOB0
****************************************************************************************/
#include "config.h"





TCOLOR gui_disp_buf[GUI_LCM_YMAX][GUI_LCM_XMAX/8]; // 声明GUI显示缓冲区

INT8U Display_On = 0 ;


//=============================================================================
//函 数 名: LCD_GPIO_Config
//功 能:
//入口参数:
//出口参数: 无
//返 回 值: 无
//=============================================================================

void LCD_GPIO_Config(void)
{
LCD_DATA_DIR = 0xff;
LCD_DATA_OUT = 0x00; //设置8位数据端口
LCD_RST_DIR |= LCD_RST;
LCD_CS_DIR |= LCD_CS;


LCD_A0_DIR |= LCD_A0;
LCD_E_DIR |= LCD_E;
LCD_RW_DIR|= LCD_RW;
}
//=============================================================================
//函 数 名: WriteCommandUC1698U()
//功 能: 写命令到UC1698U
//入口参数: CmdData:命令码
//出口参数: 无
//返 回 值: 无
//=============================================================================
void WriteCommandUC1698U(INT8U CmdData)
{
LCD_E_LO;
_NOP();
_NOP();
LCD_A0_LO;
_NOP();
_NOP();
LCD_RW_LO;
_NOP();
_NOP();
LCD_CS_LO;
_NOP();
_NOP();
LCD_DATA_DIR=0XFF; // 数据输出口
LCD_DATA_OUT=CmdData;
_NOP();
_NOP();
LCD_E_HI;
_NOP();
_NOP();
LCD_E_LO;
_NOP();
_NOP();
LCD_CS_HI;
_NOP();
_NOP();



}
//=============================================================================
//函 数 名: WriteDataUC1698U()
//功 能: 写数据到UC1698U
//入口参数: CmdData:写入的数据
//出口参数: 无
//返 回 值: 无
//=============================================================================
void WriteDataUC1698U(INT8U Data)
{ //StatusCheckUC1698U();
LCD_E_LO;
_NOP();
_NOP();
LCD_A0_HI;
_NOP();
_NOP();
LCD_RW_LO;
_NOP();
_NOP();
LCD_CS_LO;
_NOP();
_NOP();
LCD_DATA_DIR=0XFF; // 数据输出口
LCD_DATA_OUT=Data;
_NOP();
_NOP();
LCD_E_HI;
_NOP();
_NOP();
LCD_E_LO;
_NOP();
_NOP();
LCD_CS_HI;
_NOP();
_NOP();


}
//=============================================================================
//函 数 名: ReadDataUC1698U()
//功 能: 写数据到UC1698U
//入口参数: CmdData:写入的数据
//出口参数: 无
//返 回 值: 无
//====================

=========================================================
INT8U ReadDataUC1698U()
{ //StatusCheckUC1698U();

INT8U data;
LCD_DATA_OUT=0XFF;
LCD_E_LO;
_NOP();
_NOP();
LCD_A0_HI;
_NOP();
_NOP();
LCD_RW_HI;
_NOP();
_NOP();
LCD_CS_LO;
_NOP();
_NOP();
LCD_DATA_DIR=0X00; // 数据输入口
// data=LCD_DATA_IN;
//LCD_DATA_OUT=Data;
//_NOP();
//_NOP();
LCD_E_HI;
_NOP();
_NOP();
LCD_E_LO;
_NOP();
_NOP();
data=LCD_DATA_IN;


LCD_CS_HI;
_NOP();
_NOP();
return data;

}























/* 以下为LCM的用户接口层,主要负责解释用户命令,并发送到LCM,为用户编程提供接口 */


/***********************************************************************
* 名称:LCD_Initialize()
* 功能:LCM初始化,将LCM初始化为纯图形模式,显示起始地址为0x0000,。
* 入口参数:无
* 出口参数:无
* 说明:函数会设置LCM数据总线为输出方式
***********************************************************************/
void LCD_Initialize(void)
{

#define BR 0X01 //Set LCD Bias Ratio:1/10 bias
#define PC1 0X03 //power control set as internal power
#define TC 0x00 //set temperate compensation as 0%
//#define PM 192 //Set Vbias Potentiometer
//#define PM 100
#define PM 80
#define LC_210 0X05 //set LCD Control
#define LC_43 0x03
#define LC_5 0X01
#define LC_76 0x01
#define LC_8 0X00
#define NIV 0X10 //n-line inversion
#define CSF 0X02 //23:enable FRC,PWM,LRM sequence
//#define WPC0 0x25 //Starting Column Address
//#define WPP0 0 //Starting Row Address
//#define WPC1 0x5A //Ending Column Address
//#define WPP1 159 //Ending Row Address
#define WPC0 0x00 //Starting Column Address
#define WPP0 0 //Starting Row Address
#define WPC1 200 //Ending Column Address
#define WPP1 140 //Ending Row Address
#define AC 0x01 //Address Control
//#define CEN 159 //COM scanning end (last COM with full line cycle,0 based index)
#define CEN 139 //COM scanning end (last COM with full line cycle,0 based index)

LCD_GPIO_Config();

LCD_RST_LO;
Delay_ms(1);
LCD_RST_HI;
Delay_ms(100);
WriteCommandUC1698U(0XE2);
Delay_ms(100);
// LCD_BL_ON();
//WriteCommandUC1698U(0xE8|(BR&0X03));
//WriteCommandUC1698U(0xE2);
WriteCommandUC1698U(0XC4);
WriteCommandUC1698U(0x28|(PC1&0X03));
WriteCommandUC1698U(0x24|(TC&0x03));
WriteCommandUC1698U(0x81);
WriteCommandUC1698U(PM );
WriteCommandUC1698U(0xc0|(LC_210&0X07) );
WriteCommandUC1698U(0xa0|(LC_43 &0X03) );
WriteCommandUC1698U(0xd0|(LC_5 &0X01) );
//WriteCommandUC1698U(0xd4|(LC_76 &0X03) );
WriteCommandUC1698U(0xd5);
WriteCommandUC1698U(0xd4|(LC_76 &0X03) );
WriteCommandUC1698U(0x84|(LC_8 &0X01) );


WriteCommandUC1698U(0xc8 );
WriteCommandUC1698U( NIV );
WriteCommandUC1698U(0xd8|(CSF&0X07) );
WriteCommandUC1698U(0xf4 );
WriteCommandUC1698U(WPC0 );
WriteCommandUC1698U(0xf6 );
WriteCommandUC1698U(WPC1 );
WriteCommandUC1698U(0xf5 );
WriteCommandUC1698U(WPP0 );
WriteCommandUC1698U(0xf7 );
WriteCommandUC1698U(WPP1 );
WriteCommandUC1698U(0xf8|((AC>>3)&0x01) );
WriteCommandUC1698U(0x88| (0x07&AC) );
WriteCommandUC1698U(0xf1 );
WriteCommandUC1698U(CEN );
WriteCommandUC1698U(0xad );


}


//=============================================================================
//函 数 名: Write8DotsUC1698U()
//功 能: UC1698U横向写8个点的子函数
//入口参数: Data:要显示的数据
//出口参数: 无
//返 回 值: 无
//=============================================================================
void Write8DotsUC1698U(INT8U Data)
{
INT8U TempData = 0;


if(Data & 0x80)
TempData=0xf0;
if(Data & 0x40)
TempData|=0x0f;
WriteDataUC1698U(TempData);

TempData=0;
if(Data & 0x20)
TempData=0xf0;
if(Data & 0x10)
TempData|=0x0f;
WriteDataUC1698U(TempData);

TempData=0;
if(Data & 0x08)
TempData=0xf0;
if(Data & 0x04)
TempData|=0x0f;
WriteDataUC1698U(TempData);

TempData=0;
if(Data & 0x02)
TempData=0xf0;
if(Data & 0x01)
TempData|=0x0f;
WriteDataUC1698U(TempData);

}

//=============================================================================
//函 数 名: GUI_UpdateDisplay()
//功 能: 更新数据到UC1698U,每次更新16*8点,在定时器中断中每1ms调用一次
//入口参数: 无
//出口参数: 无
//返 回 值: 无
//=============================================================================
void GUI_UpdateDisplay(void)
{

static INT16U i=0;
INT16U j;
static INT8U *p;

if(Display_On == 0) //检测显示开关标志
return;

if(i == 0)
{
p =(INT8U*)gui_disp_buf;
WriteCommandUC1698U(0x60); //row address LSB
WriteCommandUC1698U(0x70); //row address MSB
WriteCommandUC1698U(0x05); //Column address LSB
WriteCommandUC1698U(0x12); //Column address MSB
}
for(j=0;j<16;j++) //每次刷新16*8点,可以任意设置,但要保证定时器时间大于刷屏时间
{
Write8DotsUC1698U(*p++);
i++;
if(i%20==0)
{
WriteDataUC1698U(0x00);
}
if(i == 3200) i = 0;
}
}




/****************************************************************************
* 与LCM相关的GUI接口函数
****************************************************************************/


/****************************************************************************
* 名称:GUI_FillSCR()
* 功能:全屏填充。直接使用数据填充

显示缓冲区。
* 入口参数:dat 填充的数据(对于黑白色LCM,为0的点灭,为1的点显示)
* 出口参数:无
****************************************************************************/
void GUI_FillSCR(uint8 dat)
{ uint32 i, j;



for(i=0; i{ for(j=0; j{ gui_disp_buf[i][j] = dat; // 填充数据
}
}
//GUI_RefreshSCR();
}


/****************************************************************************
* 名称:GUI_Initialize()
* 功能:初始化GUI,包括初始化显示缓冲区,初始化LCM并清屏。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void GUI_Initialize(void)
{
Display_On = 0; //关显示刷新
LCD_Initialize(); // 初始化LCM模块工作模式,纯图形模式
GUI_FillSCR(0x00); // 初始化缓冲区为0x00,并输出屏幕(清屏)
Display_On = 1; //开显示刷新
}



/****************************************************************************
* 名称:GUI_ClearSCR()
* 功能:清屏。
* 入口参数:无
* 出口参数:无
* 说明:用户根据LCM的实际情况编写此函数。
****************************************************************************/
void GUI_ClearSCR(void)
{
GUI_FillSCR(0x00);
}

uint8 const DCB_HEX_TAB[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};

/****************************************************************************
* 名称:GUI_Point()
* 功能:在指定位置上画点。
* 入口参数: x 指定点所在列的位置
* y 指定点所在行的位置
* color 显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 出口参数:返回值为1时表示操作成功,为0时表示操作失败。(操作失败原因是指定地址超出有
* 效范围)
* 说明:用户根据LCM的实际情况编写此函数。对于单色,只有一个位有效,则要使用左移的方法
* 实现point_dat = (point_dat&MASK_TAB [i]) | (color<* 处理。
****************************************************************************/

/*uint8 GUI_Point(uint32 x, uint32 y, TCOLOR color)
{
INT8U DataTemp;
if(x>=GUI_LCM_XMAX) return(0);
if(y>=GUI_LCM_YMAX) return(0);

设置缓冲区相应的点
if( (color&0x01) != 0 )
gui_disp_buf[y][x>>3] |= DCB_HEX_TAB[x&0x07];
else
gui_disp_buf[y][x>>3] &= (~DCB_HEX_TAB[x&0x07]);

x = (x/3)*3; //得到能被三整除的列坐标
LCD_SetAddress(x,y) ; //设置显示RAM地址

if(gui_disp_buf[y][x>>3]&DCB_HEX_TAB[x&0x07]) //获取第一个点的数据
DataTemp = 0xf0;
else
DataTemp = 0x00;
x++;
if(gui_disp_buf[y][x>>3]&DCB_HEX_TAB[x&0x07]) //获取第二个点的数据
DataTemp |=0

x0f;
else
DataTemp &=0xf0;
WriteDataUC1698U(DataTemp); //发送数据

x++;
if(gui_disp_buf[y][x>>3]&DCB_HEX_TAB[x&0x07]) //获取第三个点的数据
DataTemp = 0xf0;
else
DataTemp = 0x00;
WriteDataUC1698U(DataTemp);


return(1);
}
*/
/****************************************************************************
* 名称:GUI_Point_New()
* 功能:在指定位置上画点。
* 入口参数: x 指定点所在列的位置
* y 指定点所在行的位置
* color 显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 出口参数:返回值为1时表示操作成功,为0时表示操作失败。(操作失败原因是指定地址超出有
* 效范围)
* 说明:用户根据LCM的实际情况编写此函数。对于单色,只有一个位有效,则要使用左移的方法
* 实现point_dat = (point_dat&MASK_TAB [i]) | (color<* 处理。
****************************************************************************/


INT8U GUI_Point(uint32 x, uint32 y, TCOLOR color)
{ /* 参数过滤 */

if(x>=GUI_LCM_XMAX) return(0);
if(y>=GUI_LCM_YMAX) return(0);
INT8U data3=0,tempx=0,data_0=0,data_1=0,data_2=0;
INT16U data5=0,data2=0;
tempx=x;
x = (x/3)*3; //得到能被三整除的列坐标
LCD_SetAddress(x,y) ; //设置显示RAM地址
//WriteDataUC1698U(0xF0);
//WriteDataUC1698U(0x00);
INT8U DataTemp;

if(color==1)
{
if((tempx%3)==0)
data_0 |= 0xF0;
else
data_0=0x00;
if((tempx%3)==1)
data_1 |= 0x0F;
else
data_1=0x00;
if((tempx%3)==2)
data_2 |=0xF0;
else
data_2=0x00;

}
// data3=ReadDataUC1698U();

ReadDataUC1698U();
data2=ReadDataUC1698U();
data3=ReadDataUC1698U();
data5 = (data2<<8 | data3);


// if((data5>>15)==1) // 第一个点有显示数据
// data_0 |=0xF0;
//if(((data5&0x400)>>10)==1) // 第二个点有显示数据
// data_1 |=0x0F;
//if(((data5&0x10)>>4)==1) // 第三个点有显示数据
// data_2 |=0xF0;


if((data5&0xF800)!=0) // 第一个点有显示数据
data_0 |=0xF0;
if(((data5&0x7E0)!=0)) // 第二个点有显示数据
data_1 |=0x0F;
if(((data5&0x1F)!=0)) // 第三个点有显示数据
data_2 |=0xF0;


DataTemp=data_0 | data_1;
LCD_SetAddress(x,y); // 需要重新设置地址,否则会是虚线
WriteDataUC1698U(DataTemp);
WriteDataUC1698U(data_2);

return(1);
}















/****************************************************************************
* 名称:GUI_ReadPoint()
* 功能:读取指定点的颜色。
* 入口参数:x 指定

点所在列的位置
* y 指定点所在行的位置
* ret 保存颜色值的指针
* 出口参数:返回0时表示指定地址超出有效范围。
* 说明:对于单色,设置ret的d0位为1或0,4级灰度则为d0、d1有效,8位RGB则d0--d7有效,
* RGB结构则R、G、B变量有效。
****************************************************************************/
int GUI_ReadPoint(uint32 x, uint32 y, TCOLOR *ret)
{ TCOLOR bak;

/* 参数过滤 */
if(x>=GUI_LCM_XMAX) return(0);
if(y>=GUI_LCM_YMAX) return(0);

/* 取得该点颜色(用户自行更改) */
bak = gui_disp_buf[y][x>>3];
if( (bak&DCB_HEX_TAB[x&0x07])!=0 ) *ret = 1;
else *ret = 0;

return(1);
}


/****************************************************************************
* 名称:GUI_HLine()
* 功能:画水平线。
* 入口参数: x0 水平线起点所在列的位置
* y0 水平线起点所在行的位置
* x1 水平线终点所在列的位置
* color 显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 出口参数:无
* 说明:操作失败原因是指定地址超出缓冲区范围。
****************************************************************************/
void GUI_HLine(uint32 x0, uint32 y0, uint32 x1, uint8 color)
{
uint32 bak;

if(x0>x1) // 对x0、x1大小进行排列,以便画图
{ bak = x1;
x1 = x0;
x0 = bak;
}
if(x0==x1)
{ GUI_Point(x0, y0, color);
return;
}

do
{ GUI_Point(x0, y0, color); // 逐点显示,描出垂直线


x0++;
}while(x1>x0);
GUI_Point(x0, y0, color);
}


/****************************************************************************
* 名称:GUI_RLine()
* 功能:画垂直线。
* 入口参数: x0 垂直线起点所在列的位置
* y0 垂直线起点所在行的位置
* y1 垂直线终点所在行的位置
* color 显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 出口参数:无
* 说明:操作失败原因是指定地址超出缓冲区范围。
****************************************************************************/
void GUI_RLine(uint32 x0, uint32 y0, uint32 y1, uint8 color)
{

uint32 bak;

if(y0>y1) // 对y0、y1大小进行排列,以便画图
{ bak = y1;
y1 = y0;
y0 = bak;
}
if(y0==y1)
{ GUI_Point(x0, y0, color);
return;
}

do
{ GUI_Point(x0, y0, color); // 逐点显示,描出垂直线
y0++;
}while(y1>y0);
GUI_Point(x0, y0, color);
}


void Delay_ms(unsigned int time)
{
unsigned int i,j;
for(i=0;ifor(j=0;j<1000;j++);
}


void LCD_SetAddress(INT8U x,INT8U y)
{
// x = 0x25+x/3;//计算出该点所在的列地址,注意该液晶每3个点共有一个地址
x = x/3;
WriteCommandUC169

8U(0x60|(y&0x0f)); //写行地址低位
WriteCommandUC1698U(0x70|(y>>4)); //写行地址高位
WriteCommandUC1698U(x&0x0f); //写列地址低位
WriteCommandUC1698U(0x10|(x>>4)); //写列地址高位
}

void ClearLcd(INT8U data)
{
INT8U i,j;
//LCD_SetWindowProgram(0,0,200,140);
LCD_SetAddress(0,0) ;
for(i=0; i{ for(j=0; j{

WriteDataUC1698U(data);
//WriteDataUC1698U(data);
//WriteDataUC1698U(data);
// WriteDataUC1698U(data);
}
//WriteDataUC1698U(0x00); //补全每行末尾的数据,使总点数能被三整除
}


}


















相关主题
文本预览
相关文档 最新文档