(整理)LCD12864T6963驱动程序.
12864(T6963)原理与应用(白林峰-单片机技术)
6.2 LCD12864的原理与应用LCD12864为128х64绘图型点阵液晶模块,可以显示汉字、ASCII码字符和任意图形。
根据生产厂家不同,12864控制芯片有KS0108,T6963,ST7920等,其中KS0107(或KS0108)不带字库,ST7920带国标二级字库(8千多个汉字)。
T6963C带有ASC码字符库,并且完善的指令集和较简便的控制方式,所以本节以T6963C控制的12864为列,介绍12864的显示原理和程序设计方法,并通过项目实例介绍12864的一般应用。
6.2.1 12864点阵液晶显示模块的原理一、功能原理T6963C 是日本东芝公司专门为中等规模LCD模块设计的一款控制器,它通过外部MCU方便地实现对LCD驱动器和显示缓存的管理。
其内部有128个常用字符表,可管理外部扩展显示缓存64KB(12864模块为32KB),与单片机连接采用并行接口。
图6-2-1 12864液晶显示器12864液晶显示器除T6963控制器外,内部还包括行驱动器T6A40、列驱动器T6A39、液晶驱动偏压电路、显示存储器以及液晶屏,能够显示字符及图形,也可以显示8×4个16×16点阵的汉字。
12864外形见图6-2-1所示,与外部接口共有20个引脚,分显示器电源、表6-2-1 12864液晶引脚功能背光电源、并行数据接口、控制端口和对比度调节控制端口。
LCD正面时引脚在上,引脚编号从左依次为1~20。
二、12864的指令集T6963C的指令表见表6-2-2所示,分读状态字操作、设置指令、数据的读写操作指、令位操作指令四种。
(1)读状态字操作在T6963C中有一个一字节的状态字,单片机无论是向T6963C读写数据还是写入命令,都必需对状态字进行忙状态判断,以决定是否可以继续对T6963C进行操作;读状态字操作格式为/RD = 0;/WR = 1;/CE = 0;C/D = 1;此时数据端口D0~D7输出状态字,8为状态字从高到低分别为STA7~ STA0,其各位表示的状态描述见表6-2-3所示。
T6963CLCD240128驱动
//参考网页: http://lcm/product/SMG240128A.html
//-------------------------------------------------------------------------------
void putstr(unsigned char code *s); //显示字符串子程序,字符码为0时退出
unsigned char code *getchinesecodeposd char code *getenglishcodepos(unsigned char ac);
//SMG240128A产品引脚说明及演示连线
//PIN1: FG [构造地]-------------------VSS
//PIN2: VSS [电源地]-------------------VSS
//PIN3: VDD [电源正极]-----------------VDD(+5V)
//PIN10:RST [复位端 低有效]------------VDD
//PIN11:D0 [Data I/O]-----------------P1.0
//PIN12:D1 [Data I/O]-----------------P1.1
//PIN13:D2 [Data I/O]-----------------P1.2
//位描述 - LVD_P4.6 ALE_P4.5 NA_P4.4 - - - -
//初始值=x000,xxxx x 0 0 0 x x x x
void point(bit b);
void line(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,bit b);
LCD12864液晶驱动编程指南
二、显示图片
显示图片和显示汉字的原理是一样的, 只不过是大小的问题! 现在我们就以一张 128*64 分辨率的图片进行取模。 取模图片:
现在我们主要看一下显isplay_BMP(uchar a[][64])//显示图形的左边部分 { uchar i,j; for(j=0;j<8;j++) { SelectScreen(1); Set_page(j); Set_column(0); for(i=0;i<64;i++) //显示左屏 { write_LCD_data(a[2*j][i]);//每隔一行取一次数组中的数据 } SelectScreen(2); Set_page(j); Set_column(0); for(i=0;i<64;i++) //显示右屏 { write_LCD_data(a[2*j+1][i]);//每隔一行取一次数组中的数据 } } } 取出图片的数据是二维数组形式!注意,液晶是先显示左半屏,再显示右半屏, 但 是取数组中的元素是逐个往下取出的, 所以是对于一个半屏而言, 每隔一行取数组中的元素, 而隔去的那一行是另一个半屏要取的数据!这一点一定要注意。 还有一点要补充的就是,这个取模软件只能识别 BMP 和 ICO 格式的单色图片,如果我 们选择的图片不是 128*64 大小的话, 可以通过软件将其改成 128*64 大小的, 如果我们直接 用软件取模的话,显示的会是乱码,解决办法是我们可以通过 windows 自带的画图工具, 什么也不做修改,将大小设置好的图片另存为 BMP 单色文件就行了,然后再用取模软件取 模就 OK 了,=^_^ = !算了,给大家截个图
LCD_databusrite_LCD_command(column);//列位置 } void SetOnOff(uchar onoff) //显示开关 函数:0x3E 是关显示,0x3F 是开显示 { onoff=0x3e|onoff; //0011 111x,onoff 只能为 0 或者 1 write_LCD_command(onoff); } void SelectScreen(uchar screen) //选屏 { switch(screen) { case 0: CS1=0;CS2=0;break; //全屏 case 1: CS1=0;CS2=1;break;//左半屏 case 2: CS1=1;CS2=0;break;//右半屏 default:break; } } void ClearScreen(uchar screen) { uchar i,j; SelectScreen(screen); for(i=0;i<8;i++)//控制页数 0-7,共 8 页 { Set_page(i); Set_column(0); for(j=0;j<64;j++) //控制列数 0-63,共 64 列 { write_LCD_data(0x00); //写入 0,地址指针自加 1 } } } void InitLCD() { Read_busy(); SelectScreen(0); SetOnOff(0); //关显示 SelectScreen(0); SetOnOff(1); //开显示 SelectScreen(0); //LCD 的初始化 } void main() { InitLCD(); ClearScreen(0); Set_line(0); Display(1,0,2*16,huan);//欢 Display(1,0,3*16,ying);//迎 Display(2,0,0*16,fang);//访 Display(2,0,1*16,wen);//问 Display(1,2,0*16,da);//大 Display(1,2,1*16,hai);//海 Display(1,2,2*16,xiang);//橡 Display(1,2,3*16,shu);//树 Display(2,2,0*16,bai);//百 Display(2,2,1*16,du);//度 Display(2,2,2*16,kong);//空 Display(2,2,3*16,jian);//间 While(1); } //初始化 //清屏 //显示开始行 } //清屏 据输出 { write_LCD_data(p[i+16]); //汉字的下半部分 上半部分 } Set_page(page+1); //写下半页 Set_column(column); for(i=0;i<16;i++) //控制列 //控制 16 列的数 } void Display(uchar ss,uchar page,uchar column,uchar *p) { uchar i; SelectScreen(ss); Set_page(page); for(i=0;i<16;i++) 的数据输出 { write_LCD_data(p[i]); //汉字的 //写上半页 //控制 16 列 Set_column(column); //控制列 //显示汉字 ClearScreen(0);//清屏 Set_line(0); //开始行:0
LCD12864菜单程序
一起来学LCD12864菜单程序(包含完整程序)一起来学LCD12864菜单程序(包含完整程序)/*-------------------------------------------项目名:家电中央控制系统工程程序名:显示MCU总体程序编写人:杜洋初写时间:2005年9月5日晚20时程序功能:实现液晶、语音部分的人机对话和总线的通信实现方法:用中断实现总线接收CPU说明:89S5212MHZ晶振接口说明:(详见初定义)信息说明:修改日志:NO.1--------------------------------------------*/;----------------------------------------初定义LCDDAT EQU P2RS EQU P3.5RW EQU P3.6E EQU P3.7REDLED EQU P3.4BACKLED EQU P3.1PLAY EQU P1.7STOPIN EQU P3.0LIN EQU P3.2SPDAT EQU P1XX2 EQU P0.0LT_RAM EQU 30HLR_RAM EQU 40HSP_RAM EQU 20HDIS1_RAM EQU 50HDIS2_RAM EQU 70HDIS3_RAM EQU 60HDIS4_RAM EQU 80HRR1 EQU 26HRR3 EQU 21HRR4 EQU 22HT0_RAM EQU 23HQR3_RAM EQU 24HQR2_RAM EQU 25HLCDDISPLAY EQU 26H ;菜单显示移位寄存器MENU_RAM EQU 27H;菜单位置寄存器ONOFFLCD EQU 28H;-------------------------------------程序入口ORG 0000HJMP LCD_STARTORG 0003HJMP LIN_INT0ORG 000BHJMP LED_T0ORG 0030H;--------------------------------------主程序开始LCD_START br>SETB PLAYMOV T0_RAM,#250MOV TMOD,#01HSETB ET0MOV TL0,#0B0H ;50MS 定时初值(T0计时用)MOV TH0,#3CH ;50MS定时初值CLR IT0SETB EX0SETB TR0SETB EAMOV DPTR,#TAB_0CALL START_LCD;-----自检程序CALL DL1SMOV MENU_RAM,#00HMOV DPTR,#TAB_HCALL START_LCDCLR LCDDISPLAY;--------------------------------------主循环体程序LCD_LOOP br>JB ONOFFLCD,DISPLAY_PROLCD_LOOP_1br>JMP LCD_LOOP;---------------------------- 菜单显示处理DISPLAY_PRO br>MOV A,MENU_RAMMOV DPTR,#MENUTAB_HOSTRLC AJMP @A+DPTRMENUNEXT br>CALL START_LCDCLR LCDDISPLAYCLR ONOFFLCDJMP LCD_LOOP;-------------------------MENUTAB_HOST:JMP HOST_H ;主菜单JMP HOST_1 ; 1,控制JMP HOST_2 ; 2,设置JMP HOST_3 ; 3,智能JMP HOST_4 ; 4,帮助<。
LCD12864显示程序
L C D12864显示程序(总3页) -CAL-FENGHAI.-(YICAI)-Company One1-CAL-本页仅作为文档封面,使用请直接删除本例程为通过用AT89C52芯片操作LCD12864显示的程序,使用的晶振为12M。
/**********************************************************程序说明:LCD12864显示主程序程序调试员:莫剑辉调试时间:2010-6-7**********************************************************/#include<reg52.h>#include"12864.c"void main(){Ini_Lcd(); //液晶初始化子程序Disp(1,0,6,"莫剑辉"); //显示数据到LCD12864子程序while(1);}这里我们通过调用下面的头文件就可以了,这样的做法方便我们以后要用到LCD12864的程序的调用。
/**********************************************************程序说明:LCD12864显示头文件程序调试员:莫剑辉调试时间:2010-6-7**********************************************************///#include<reg52.h>#define uchar unsigned char#define uint unsigned int#define DATA P2 //数据输出端0~7sbit RS=P0^0; //LCD12864 RS端sbit RW=P0^1; //LCD12864 RW端sbit E =P0^2; //LCD12864 E 端sbit PSB =P0^3;/*********************************************延时子程序*********************************************/void Delay_1ms(uint x){uint j,i;for(j=0;j<x;j++){for(i=0;i<120;i++); //延时X乘以120}}/*********************************************LCD12864液晶测忙子程序(读状态)*********************************************/void Busy(){uchar busy;do{E = 0; //0为关闭使能端,1为打开使能端RS = 0; //1为指令,0为数据RW = 1; //1为读,0为写Delay_1ms(20); //延时20乘以120时间E = 1; //0为关闭使能端,1为打开使能端busy=P1; //读取P2状态Delay_1ms(20); //延时20乘以120时间E = 0; //0为关闭使能端,1为打开使能端}while(busy&0x80); //判断BUSY位是否工作:1为内部在工作,0为正常状态}/*********************************************LCD12864液晶数据写入子程序*********************************************/void Write_Data(uchar k){Busy(); //测忙E =1; //0为关闭使能端,1为打开使能端RS=1; //1为指令,0为数据RW=0; //1为读,0为写DATA=k; //输入数据K到DATADelay_1ms(20); //延时20乘以120时间E =0; //0为关闭使能端,1为打开使能端Delay_1ms(20); //延时20乘以120时间}/*********************************************LCD12864液晶命令写入子程序*********************************************/void Write_Cmd(uchar cmd){Busy(); //测忙E=1; //0为关闭使能端,1为打开使能端RS=0; //1为指令,0为数据RW=0; //1为读,0为写DATA=cmd; //输入命令cmd到DATADelay_1ms(20); //延时20乘以120时间E=0; //0为关闭使能端,1为打开使能端Delay_1ms(20); //延时20乘以120时间}/*********************************************LCD12864液晶数据显示子程序*********************************************/void Disp(uchar y,uchar x,uchar i,uchar *z){uchar Address;if(y==1){Address=0x80+x;} //Y判断第几行,X判断第几列,0x80为液晶行初始地址if(y==2){Address=0x90+x;}if(y==3){Address=0x88+x;}if(y==4){Address=0x98+x;}Write_Cmd(Address); //写入地址命令到LCD12864while(i) //写入显示数据的大小{Write_Data(*(z++)); //写入显示数据到LCD12864i--;}}/*********************************************LCD12864液晶初始化子程序*********************************************/void Ini_Lcd(void){PSB=1;Delay_1ms(20);Write_Cmd(0x30); //基本指令集Delay_1ms(20);Write_Cmd(0x02); // 地址归位Delay_1ms(20);Write_Cmd(0x0c); //整体显示打开,游标关闭Delay_1ms(20);Write_Cmd(0x06); //游标右移Delay_1ms(20);Write_Cmd(0x80); //设定显示的起始地址Delay_1ms(20);Write_Cmd(0x01); //清除显示}。
基于T6963C驱动的经典程序(240128)
code uchar const uPowArr[]
= {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
// ASCII 字模宽度及高度定义 #define ASC_CHR_WIDTH 8 #define ASC_CHR_HEIGHT 12 // ASCII 字模,显示为 8*16 char code ASC_MSK[96*12] = { // Terminal9; 此字体下对应的点阵为:宽 x 高=8x12 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff, // < 0x20 时,打印此字 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ' ' 0x00,0x0C,0x1E,0x1E,0x1E,0x0C,0x0C,0x00,0x0C,0x0C,0x00,0x00, // '!' 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // '"' 0x00,0x36,0x36,0x7F,0x36,0x36,0x36,0x7F,0x36,0x36,0x00,0x00, // '#'
设置控制词
模式设定
显示模式
光标形式
数据自动 读写 数据读写
屏幕读取 屏幕拷贝 位设置 / 复位
位复位 位设置 位 0(最低位) 位1 位2 位3 位4 位5 位6 位7
2
接口信号
引脚 号 1 2 3 4 5 6 7 8 9 标记号 FG Vss Vdd Vo Wr Rd CE C/D Reset 说明 显示屏框夹外壳地 电源地 电源+5V LCD 工作电源(对比度调节负电压输入) 数据写入当 WR = L 时,将数据写入 T6963C 数据读出 WR = L C/D = H :写命令 C/D = L :读命令 RD = L C/D = H: 读状态 C/D = L : 读数据 复位信号,H:正常(T6963C 有内部上拉电阻) L: 初始化 T6963C. Text 文本和图形的地址,文本和图 形区域设定被保持。 数据位 0 数据位 1 数据位 2 数据位 3 数据位 4 数据位 5 数据位 6 数据位 7 字体选择:FS = H, 6*8 点的字体,FS = L, 8*8 点的字体 DC-DC 负电源输出(液晶屏工作电压,作对比度调节) 背光电源正端 背光电源负端 备注 接地
液晶显示屏LCD12864驱动解析
液晶显示器LCD12864驱动程序#include<msp430g2553.h>#include "lcd12864.h"#include "typedef.h"#define cyCS BIT0 //P2.0,片选信号#define cySID BIT1 //P2.1,串行数据#define cyCLK BIT2 //P2.2,同步时钟#define cyPORT P2OUT#define cyDDR P2DIRvoid Write_8bits(u8 W_bits){u8 i;cyDDR |= cyCLK + cySID; //设置输出方向for(i = 0; i < 8; i++){if(( W_bits << i )&0x80){cyPORT |= cySID;}else{cyPORT &= ~cySID;}delay_ms(1);cyPORT |= cyCLK;delay_ms(1);delay_ms(1);cyPORT &= ~cyCLK;}}void w_1byte(u8 RS, u8 w_data){u8 H_Data,L_Data;u8 tmp_Data = 0xf8;cyDDR |= cyCS; //设置CS口为输出if(RS == 0) tmp_Data &= ~0x02;else tmp_Data |= 0x02;H_Data = w_data; //高位数据H_Data &= 0xf0;L_Data = w_data; //低位数据L_Data &= 0x0f;L_Data <<= 4;cyPORT |= cyCS;Write_8bits(tmp_Data);Write_8bits(H_Data);Write_8bits(L_Data);cyPORT &= ~cyCS;}void init_Lcd(void){cyDDR |= cyCLK + cySID + cyCS; //相应的位端口设置为输出delay_ms(10); //延时等待液晶完成复位w_1byte(0,0x30);delay_ms(1);w_1byte(0,0x02);delay_ms(5);w_1byte(0,0x0c);delay_ms(1);w_1byte(0,0x01);delay_ms(5);w_1byte(0,0x06);delay_ms(1);}//清屏void clear_lcd(void){delay_ms(1);w_1byte(0,0x01);delay_ms(5);}void lcd_pos(u8 x,u8 y)//定位{u8 pos;switch(x){case 1:pos=0x80;break;case 2:pos=0x90;break;case 3:pos=0x88;break;case 4:pos=0x98;break;default:pos=0x80;}pos += y;w_1byte(0,pos);}//显示汉字void Disp_HZ(const u8 * pt,u8 num){u8 i;for(i = 0;i < num*2;i++){w_1byte(1,*(pt++));}}//显示字符void Disp_Ch(const u8 ch){w_1byte(1, ch);}//汉字和字符混合显示void disp_lcd_str(u8 x, u8 y, const u8 *str, u8 len) {u8 i;lcd_pos(x, y);for(i = 0;i < len && *str; ){if(*(str) >= 0x80){w_1byte(1,*(str++));w_1byte(1,*(str++));i++;i++;}else{w_1byte(1,*(str++));i++;}}}。
液晶控制器T6963的C语言驱动程序
StartAddr=lin*LineChar*16 +column; //定位起始行
for(i=0;i<35;i++)
{
OutPortCom3( (unsigned char)(StartAddr), (unsigned char)(StartAddr>>8), 0x24); //定位当前操作位置
//显示一个汉字(16*16点阵)
//lin:行(0-7), column: 列(0-7)
//hzcode: 汉字代码(自定义的)
void ShowHZD(unsigned char lin,unsigned char column,unsigned int hzcode)
{
unsigned char i,j;
/*------输入/出函数,与T6963通讯------------------------------------------------*/
/*------------------------------------------------------------------------*/
#include "menu.h" //汉字点阵库(自做)
//set following data by user according to LCD
#define ComPort 0xB101
#define DataPort 0xB000
#define GraphAddr 0x0000 //head of graph
unsigned char InPortData() { RWCheck(); return(XBYTE[DataPort]); }
12864LCD驱动程序
//----------------------------------------------------------------- // 名称: LGM12864LCD显示驱动程序(不带字库) //----------------------------------------------------------------- #include <pic.h>#include "LGM12864.h"//是否反相显示(白底黑字/黑底白字)INT8U Reverse_Display = 0;//----------------------------------------------------------------- // 等待液晶就绪//----------------------------------------------------------------- void Wait_LCD_Ready(){}//----------------------------------------------------------------- // 向LCD发送命令//----------------------------------------------------------------- void LCD_Write_Command(INT8U cmd){}//----------------------------------------------------------------- // 向LCD发送数据//----------------------------------------------------------------- void LCD_Write_Data(INT8U dat){}//----------------------------------------------------------------- // LCD初始化函数//----------------------------------------------------------------- void LCD_Initialize()RST = 0; __delay_ms(1); //复位LCDRST = 1; //恢复LCD正常工作LCD_Write_Command(0x30); __delay_ms(15); //基本指令操作LCD_Write_Command(0x01); __delay_ms(15); //清除显示LCD_Write_Command(0x06); __delay_ms(15); //光标移动方向LCD_Write_Command(0x0c); __delay_ms(15); //开显示,关光标,不闪烁}//-----------------------------------------------------------------//// 通用显示函数//// 从第P页第L列开始显示W个字节数据,数据在r所指向的缓冲// 每字节8位是垂直显示的,高位在下,低位在上// 每个8*128的矩形区域为一页// 整个LCD又由64x64的左半屏和64x64的右半屏构成//-----------------------------------------------------------------void Common_Show(INT8U P,INT8U L,INT8U W,INT8U *r){INT8U i;//显示在左半屏或左右半屏if( L < 64 ){}//全部显示在右半屏else{}}//-----------------------------------------------------------------// 显示一个8×16点阵字符//-----------------------------------------------------------------void Display_A_Char_8X16(INT8U P,INT8U L,INT8U *M)}//-----------------------------------------------------------------// 显示一个16×16点阵汉字//-----------------------------------------------------------------void Display_A_WORD(INT8U P,INT8U L,INT8U *M){}//-----------------------------------------------------------------// 显示一串16×16点阵汉字//-----------------------------------------------------------------void Display_A_WORD_String(INT8U P,INT8U L,INT8U C,INT8U *M) {}。
LCD19264的驱动程序
LCD19264的驱动程序#include "Public.h"#define Fisrt 01#define Second 02#define Third 03/*定义LCD控制端口*/sbit LCD_RS = P0^7;sbit LCD_RW = P0^6;sbit LCD_CE = P0^5;sbit LCD_CSA = P0^4;sbit LCD_REST = P0^3;sbit LCD_CSB = P0^2;sbit LCD_CSC = P0^1;#define DATA_BUS P2/************************************************************** *****函数功能说明:判断LCD忙函数1、2、3、*************************************************************** ****/void Read_busy(unsigned char Area){unsigned char temp = 0;do{LCD_CE = 0;LCD_RS = 0; switch(Area){case Fisrt:LCD_CSA = 0; break;case Second: LCD_CSB = 0; break;case Third:LCD_CSC = 0; break;default:break;}_nop_();LCD_CE = 1;_nop_();temp = DATA_BUS; LCD_CE = 0;LCD_RW = 0; switch(Area){case Fisrt:LCD_CSA = 1; break;case Second: LCD_CSB = 1; break;case Third:break;default:break;}LCD_CE = 1;}while(temp&0x80);}/************************************************************** *****函数功能说明:设置坐标1、液晶分为三个区 A、B、C2、设置每个区的坐标3、送坐标到总线上*************************************************************** ****/void Set_Locatexy(unsigned char x_add,unsigned char y_add) {switch(x_add&0xc0){case 0x00:Write_command(Fisrt,x_add&0x3f)break;case 0x40:break;case 0x80:break;default:break;}/************************************************************** *****函数功能说明:写数据1、液晶分为三个区 A、B、C2、设置每个区的片选信号3、送数据到总线上*************************************************************** ****/void Write_data(unsigned char Area_Num,unsigned char Lcd_data){Read_busy(Area_Num);LCD_CE = 0; /*写入到LCM*/LCD_RW = 0;LCD_RS = 1; //数据switch(Area_Num){case Fisrt:LCD_CSA = 0;break;case Second:LCD_CSB = 0;break;case Third:LCD_CSC = 0;break;default:break;_nop_();LCD_CE = 1;_nop_();DATA_BUS = Lcd_data;_nop_();_nop_();LCD_CE = 0;LCD_RW = 1;switch(Area_Num){case Fisrt:LCD_CSA = 1;break;case Second:LCD_CSB = 1;break;case Third:LCD_CSC = 1;break;default:break;}LCD_CE = 1;}/************************************************************** *****函数功能说明:写命令1、液晶分为三个区 A、B、C2、设置每个区的片选信号3、送命令到总线上*******************************************************************/void Write_command(unsigned char Area_Num,unsigned char Lcd_Command){Read_busy(Area_Num);LCD_CE = 0; /*写入到LCM*/LCD_RW = 0;LCD_RS = 0; //指令switch(Area_Num){case Fisrt:LCD_CSA = 0;break;case Second:LCD_CSB = 0;break;case Third:LCD_CSC = 0;break;default:break;}_nop_();LCD_CE = 1;_nop_();DATA_BUS = Lcd_Command;_nop_();_nop_();LCD_CE = 0;LCD_RW = 1;switch(Area_Num){case Fisrt:LCD_CSA = 1;break;case Second:LCD_CSB = 1;break;case Third:LCD_CSC = 1;break;default:break;}LCD_CE = 1;}void Lcminit( void ){LCD_REST = 0;_nop_();LCD_REST = 1;Write_command(Fisrt,0x40); Write_command(Second,0x40); Write_command(Third,0x40);Write_command(Fisrt,0xb8); Write_command(Second,0xb8); Write_command(Third,0xb8);Write_command(Fisrt,0xc0);Write_command(Second,0xc0); Write_command(Third,0xc0);Write_command(Fisrt,0x3f); Write_command(Second,0x3f); Write_command(Third,0x3f); }。
t6963驱动芯片调试程序
* 入口参数:
*
* 出口参数:状态值
* LCD的操作时序:CD置位到CS变高之间的时间>100ns,且在CS变高后要保持10ns
* WR为上升沿有效,并保持40ns;
* RD在变低150ns后,数据有效;
lcd_parameter[1] = 0x00;
write_command_lcd(0x42,2,lcd_parameter);
lcd_parameter[0] = 40; //图形字节数/行
lcd_parameter[1] = 0x00;
#define LCDCE 0x00010000 //O P0.16口 LCD的片选信号:低有效
#define LCDCD 0x00020000 //O P0.17口 LCD的数据/命令:1=命令,0=数据
{ uint8 xi;
if(xlen > 2) xlen = 2;
for(xi = 0; xi < xlen; xi++)
{ Write_Byte_T6963(xp[xi],0);
}
Write_Byte_T6963(xd,1);
//P0.18~P0.25为LCD的8位数据接口 //O
#define LCD_GRAPHICS_ADDR 0x0000 // LCD图形显示区的地址
#define LCD_XMAX 30; //LCD的一行最多显示的字符数(8*16字符)
void lcd_initi(void) // ;初始化lcd
{ uint16 xt;
lcd_parameter[0] = 0x00; //文本区首址0000H
12864液晶屏驱动程序
BMPwith=*PicData;
PicData++;
BMPheight=(*PicData)/8;
PicData++;
//BMPLen=BMPheight/8*BMPwith
for(BMPheightLen=0;BMPheightLen<BMPheight;BMPheightLen++)
Series = Series << 1;
}
}
/***********************************
** 函数名称: Write_Data
** 功能描述: 传送数据
** 输 入: dat
** 输 出 : 无
** 全局变量:无
** 调用模块: Busy,
******************************************/
//图像反色显示 0 否 1是
bit LCD_DisplayReserve_Driver;
//定义LCD显示的全局变量
#define CS_Port P3_0
#define A0_Port P3_1
#define SI_Port P3_2
{
switch (PIN)
{
case CS :
CS_Port=1;
break;
case A0 :
A0_Port=1;
break;
case SI :
SI_Port=1;
break;
case SCL :
SCL_Port=1;
LCD12864液晶驱动编程指南
LCD12864液晶驱动编程指南
1.连接硬件:
2.初始化液晶:
在开始使用液晶之前,需要进行初始化。
初始化过程包括设置液晶的
工作模式、显示模式和其他参数。
通过向液晶发送一系列的指令,可以完
成初始化过程。
3.编写驱动程序:
液晶驱动程序的主要目的是将需要显示的内容以及液晶的控制指令发
送给液晶屏。
根据液晶屏的通信方式,可以采用单片机的IO口直接控制
液晶屏,也可以通过SPI或I2C等接口芯片间接控制。
4.显示图形:
5.显示文本:
除了图形外,液晶还可以显示文本。
可以通过设置显示位置和发送需
要显示的文本来实现。
6.更新显示:
当需要更新液晶上的内容时,可以通过重新设置显示的内容和刷新液
晶来实现。
可以定时刷新液晶,或者通过检测外部事件来触发刷新。
7.扩展功能:
除了基本功能外,还可以实现一些扩展功能,如显示动画、滚动显示、倒计时等。
只需要根据需求编写相应的代码即可实现。
总结:
注意事项:
在编写驱动程序时,需要注意及时更新液晶上的内容,避免频繁刷新导致的卡顿现象。
同时,为了保证程序的可移植性,可以将液晶驱动程序与其他功能模块进行分离,便于代码的维护和移植。
12864 LCD驱动程序
/*LCD.C128×64 LCD驱动程序*/#include <INTRINS.H>#include <ABSACC.H>#include "LCD.H"//定义屏幕光标(取值0~63,光标本身不可见)unsigned char LcdCursor;/*函数:LcdLightOn()功能:点亮背光灯*/void LcdLightOn(){LCD_BL = 1;}/*函数:LcdLightOff()功能:熄灭背光灯*/void LcdLightOff(){LCD_BL = 0;}/*函数:LcdGetBF()功能:读出状态位BF返回:BF=1,表示忙,不可进行任何操作BF=0,表示不忙,可以进行正常操作*/bit LcdGetBF(){unsigned char dat;dat = XBYTE[0xD002]; //XBYTE的定义见<ABSACC.H>return (bit)(dat & 0x80);}/*函数:LcdWriteCmd()功能:向LCD发送命令参数:cmd:命令字,详见器件的数据手册*/void LcdWriteCmd(unsigned char cmd){while ( LcdGetBF() );XBYTE[0xD000] = cmd;}/*函数:LcdWriteDat()功能:向LCD写入数据参数:dat,要写入的数据说明:目标地址由地址计数器AC隐含指定,写完后AC自动加1*/void LcdWriteDat(unsigned char dat){while ( LcdGetBF() );XBYTE[0xD001] = dat;}/*函数:LcdReadDat()功能:从LCD读出数据返回:读出的数据*//*unsigned char LcdReadDat(){volatile unsigned char dat;while ( LcdGetBF() );dat = XBYTE[0xD003];dat = XBYTE[0xD003]; //需要连续执行两次才能够读出真正的数据return dat;}*//*函数:LcdSetAC()功能:设置DDRAM(显示数据RAM)的AC(地址计数器)值参数:ac:地址计数器值,范围0~63*/void LcdSetAC(unsigned char ac){ac &= 0x3F;ac |= 0x80;LcdWriteCmd(ac);}/*函数:LcdClear()功能:LCD清屏,并使光标回到0*/void LcdClear(){LcdWriteCmd(0x01); //清屏命令LcdCursor = 0;}/*函数:LcdDelay()功能:延时(t*100)个机器周期*/void LcdDelay(unsigned char t){unsigned char n;do{n = 49;while ( --n != 0 );} while ( --t != 0 );}/*函数:LcdInit()功能:LCD初始化*/void LcdInit(){LcdWriteCmd(0x30); //设置基本指令集LcdDelay(3);LcdWriteCmd(0x30); //设置基本指令集(需要再执行一次)LcdDelay(1);LcdWriteCmd(0x0C); //开启显示LcdDelay(3);LcdClear(); //清屏LcdDelay(250);LcdWriteCmd(0x06); //设置进入点LcdDelay(10);}/*函数:LcdCheckAC()功能:根据光标位置调整AC*/void LcdCheckAC(){switch ( LcdCursor ){case 16:LcdSetAC(16);break;case 32:LcdSetAC(8);break;case 48:LcdSetAC(24);break;case 64:LcdCursor = 0;LcdSetAC(0);break;default:break;}/*函数:LcdPutChar()功能:显示ASCII码参数:c为可显示的ASCII码(0x20~0x7F)*/void LcdPutChar(unsigned char c){LcdWriteDat(c);LcdCursor++;LcdCheckAC();}/*函数:LcdPutHZ()功能:显示汉字参数:ch,cl:汉字编码*/void LcdPutHZ(unsigned char ch, unsigned char cl){if ( LcdCursor & 0x01 ){//显示汉字时,必须偶地址对准,即光标位置不能是奇数LcdPutChar(' '); //额外输出一个空格}LcdWriteDat(ch);LcdWriteDat(cl);LcdCursor += 2;LcdCheckAC();}/*函数:LcdPuts()功能:显示字符串参数:*s:要显示的字符串(可同时包含ASCII码和汉字)*/void LcdPuts(unsigned char *s){unsigned char ch, cl;for (;;){ch = *s++;if ( ch == '\0' ) break;if ( ch < 0x80 ){LcdPutChar(ch);}else{cl = *s++;LcdPutHZ(ch,cl);}}}。
LCD12864T6963驱动程序
液晶显示模块的应用一、结构特点内藏T6963C 的液晶显示模块上已经实现了T6963C 与行、列驱动器及显示缓冲区RAM 的接口,同时也已用硬件设置了液晶屏的结构(单双屏、数据传输方式、显示窗口长度、宽度等等。
我们常用的液晶显示模块一般都是单屏结构,因此我们这里只讨论单屏结构的液晶显示模块。
内藏T6963C 的单屏结构点阵图形液晶显示模块的方框图如下:二、T6963C 的特点(1) T6963C 是点阵式液晶图形显示控制器它能直接与8 位微处理器接口;(2) T6963C 的字符字体可由硬件或软件设置,其字体有4 种5X8 、6X8 、7X8、8X8;(3) T6963C 的占空比可从1/16 到1/128;(4) T6963C 可以图形方式、文本方式及图形和文本合成方式进行显示,以及文本方式下的特征显示,还可以实现图形拷贝操作等等;(5) T6963C 具有内部字符发生器CGROM,共有128 个字符。
T6963C 可管理64K显示缓冲区及字符发生器CGRAM,并允许MPU 随时访问显示缓冲区,甚至可以进行位操作。
三、该类液晶模块的管脚定义见下表:说明:对于单电源模块,标志为V0/POFF。
当该管脚为高或悬空时,内部DC/DC 功能开启;为低时,内部DC/DC 功能关闭。
该功能可用作屏幕保护和休眠方式。
如果用其直接替代双电源模块,该管脚直接悬空即可。
四、液晶显示模块的供电说明1. 如果您所选用的液晶模块是双电源(VDD/V0)供电的就需要提供一个负电压(液晶驱动电压V0/VEE),用以调节对比度,接在液晶模块的V0 引脚上。
因为液晶材料的物理特性,液晶的对比度会随着温度的变化而相应变化,所以,您加的负电压值应该随温度作相应的调整,大致是温度变化10°C 电压变化1伏左右。
为满足这一要求您要选择较大值的负电源,然后做一个温度补偿电路,或者安排一个电位器调整负电压值。
例如对于QH12864T-HT-LED04,当室温(VDD=5V)时,V0=-10.5V,如果要用到-20°C,液晶驱动电压将要变到V0=-14.5V,再考虑到负载消耗所以您提供的负电源应该为-16V 左右。
LCD12864(T6963)驱动程序
液晶显示模块的应用一、结构特点内藏T6963C 的液晶显示模块上已经实现了T6963C 与行、列驱动器及显示缓冲区RAM 的接口,同时也已用硬件设置了液晶屏的结构(单双屏、数据传输方式、显示窗口长度、宽度等等。
我们常用的液晶显示模块一般都是单屏结构,因此我们这里只讨论单屏结构的液晶显示模块。
内藏T6963C 的单屏结构点阵图形液晶显示模块的方框图如下:二、T6963C 的特点(1) T6963C 是点阵式液晶图形显示控制器它能直接与8 位微处理器接口;(2) T6963C 的字符字体可由硬件或软件设置,其字体有4 种5X8 、6X8 、7X8、8X8;(3) T6963C 的占空比可从1/16 到1/128;(4) T6963C 可以图形方式、文本方式及图形和文本合成方式进行显示,以及文本方式下的特征显示,还可以实现图形拷贝操作等等;(5) T6963C 具有内部字符发生器CGROM,共有128 个字符。
T6963C 可管理64K显示缓冲区及字符发生器CGRAM,并允许MPU 随时访问显示缓冲区,甚至可以进行位操作。
三、该类液晶模块的管脚定义见下表:说明:对于单电源模块,标志为V0/POFF。
当该管脚为高或悬空时,内部DC/DC 功能开启;为低时,内部DC/DC 功能关闭。
该功能可用作屏幕保护和休眠方式。
如果用其直接替代双电源模块,该管脚直接悬空即可。
四、液晶显示模块的供电说明1. 如果您所选用的液晶模块是双电源(VDD/V0)供电的就需要提供一个负电压(液晶驱动电压V0/VEE),用以调节对比度,接在液晶模块的V0 引脚上。
因为液晶材料的物理特性,液晶的对比度会随着温度的变化而相应变化,所以,您加的负电压值应该随温度作相应的调整,大致是温度变化10°C 电压变化1伏左右。
为满足这一要求您要选择较大值的负电源,然后做一个温度补偿电路,或者安排一个电位器调整负电压值。
例如对于QH12864T-HT-LED04,当室温(VDD=5V)时,V0=-10.5V,如果要用到-20°C,液晶驱动电压将要变到V0=-14.5V,再考虑到负载消耗所以您提供的负电源应该为-16V 左右。
T6963驱动程序
//***************************************************************************** *****T6963驱动程序,已调试通过// LCM(OCM-240128)显示程序//***************************************************************************** *****//#include "stc12c5a56s2.h"#include "includes.h"#include "intrins.h"#include "math.h"#include "ZIMO.H"// T6963C 端口定义//#define LCMDW XBYTE[0x0000] //数据口0x8000//#define LCMDW XBYTE[0x0100] //命令口0x8100#define LCMDW P0#define LCMCW P0sbit LCMCD = P4^6; //命令数据通道选择sbit LCMWR = P4^2; //写sbit LCMRD = P1^0; //读sbit LCMRST = P1^4;sbit LCMCE = P1^1;sbit LCMFS = P1^5;#define End 0xff //结束项// T6963C 命令定义#define CUR_POS 0x21 // 光标位置设置#define CGR_POS 0x22 // CGRAM偏置地址设置#define ADD_POS 0x24 // +地址指针位置#define TXT_STP 0x40 // +文本区首址#define TXT_WID 0x41 // +文本区宽度#define GRH_STP 0x42 // +图形区首址#define GRH_WID 0x43 // +图形区宽度#define MOD_OR 0x80 // +显示方式:逻辑“或”#define MOD_XOR 0x81 // 显示方式:逻辑“异或”#define MOD_AND 0x82 // 显示方式:逻辑“与”#define MOD_TCH 0x83 // 显示方式:文本特征#define DIS_SW 0x90 // +显示开关:D0=1/0:光标闪烁启用/禁用;// D1=1/0:光标显示启用/禁用;// D2=1/0:文本显示启用/禁用;// D3=1/0:图形显示启用/禁用;#define CUR_SHP 0xA0 // +光标形状选择:0xA0-0xA7表示光标占的行数#define AUT_WR 0xB0 // +自动写设置#define AUT_RD 0xB1 // 自动读设置#define AUT_OVR 0xB2 // +自动读/写结束#define INC_WR 0xC0 // 数据一次写,地址加1#define INC_RD 0xC1 // 数据一次读,地址加1#define DEC_WR 0xC2 // 数据一次写,地址减1#define DEC_RD 0xC3 // 数据一次读,地址减1#define NOC_WR 0xC4 // 数据一次写,地址不变#define NOC_RD 0xC5 // 数据一次读,地址不变#define SCN_RD 0xE0 // 屏读#define SCN_CP 0xE8 // 屏拷贝#define BIT_OP 0xF0 // 位操作:D0-D2:定义D0-D7位;D3:1置位;0:清除/*******************************************************// 状态位STA1,STA0判断(读写指令和读写数据)********************************************************/unsigned char fnST1(void){unsigned char i;LCMCW = 0xff;LCMCD = 1; //打开指令通道LCMRD = 0; //允许读LCMWR = 1; //禁止写for( i = 10; i > 0; i-- ){if((LCMCW & 0x03) == 0x03)break;}LCMRD = 1;return i; //若返回零,说明错误}/*******************************************************// 状态位ST3判断(数据自动写状态)********************************************************/unsigned char fnST3(void){unsigned char i;LCMCW = 0xff;LCMCD = 1; //打开指令通道LCMRD = 0; //允许读LCMWR = 1; //禁止写for( i = 10; i > 0; i--){if((LCMCW & 0x08) == 0x08)break;}LCMRD = 1;return i; // 若返回零,说明错误}/*-------------------------------------------------------写数据,需要将LCMCD 置零---------------------------------------------------------*/void fnWrDat(unsigned char uDat){LCMCD = 0; //数据通道打开LCMRD = 1; //读数据无效LCMDW = uDat; //返回数据LCMWR = 0; //写数据有效_nop_();_nop_();LCMWR = 1; //写数据禁止,产生一个上升沿}/*-------------------------------------------------------写命令,需要将LCMCD 置1---------------------------------------------------------*/void fnWrCmd(unsigned char uDat){LCMCD = 1; //命令通道打开LCMRD = 1; //读数据无效LCMDW = uDat; //返回数据LCMWR = 0; //写数据有效_nop_();_nop_();LCMWR = 1; //写数据有效}/******************************************************// 写双参数的指令*******************************************************/void fnPR1(unsigned char uCmd,unsigned char uPar1,unsigned char uPar2) {if( fnST1() != 0 ) fnWrDat(uPar1);if( fnST1() != 0 ) fnWrDat(uPar2);if( fnST1() != 0 ) fnWrCmd(uCmd);//LCMCW = uCmd;}/*****************************************************// 写无参数的指令******************************************************/ void fnPR12(unsigned char uCmd){if( fnST1() != 0 ) fnWrCmd(uCmd);}/****************************************************// 写数据****************************************************/ void fnPR13(unsigned char uData){if( fnST3() != 0 ) fnWrDat(uData);}/************************************************** //30列*16,8行X:行Y:列***************************************************/ void fnSetPos(unsigned char X, unsigned char Y){unsigned int Z;Z = Y * 30 + X;fnPR1(ADD_POS,Z ,Z >> 8);//+以点阵为单位}/*************************************************// 清屏**************************************************/ void fnClrScreen(void){unsigned int i;EA = 0;fnPR1(ADD_POS,0x00,0x00); // 置地址指针fnPR12(AUT_WR); // 自动写for( i = 0; i <256*64; i++){fnPR13(0x00); // 0x00写数据}fnPR12(AUT_OVR); // 自动写结束fnPR1(ADD_POS,0x00,0x00); // 重置地址指针EA = 0;}//*************************************// LCM 初始化void INI240128(void){EA = 0;LCMFS = 0;LCMRST = 0;LCMCE = 0;LCMWR = 1;LCMRD = 1;LCMRST = 1;fnPR1( TXT_STP, 0x00, 0x10 ); // 1000H文本显示区首地址1000-11ffh fnPR1( TXT_WID, 0x1E, 0x00 ); // 文本显示区宽度:30fnPR1( GRH_STP, 0x00, 0x00 ); // 图形显示区首地址0000-0fffhfnPR1( GRH_WID, 0x1E, 0x00 ); // 图形显示区宽度:30 左上角的第一个8点列像素fnPR12( CUR_SHP | 0x01 ); // 光标形状,2行fnPR12( MOD_OR ); // 显示方式设置:文本与图形以"或"合成fnPR12( DIS_SW | 0x0f ); // 显示开关设置:启用图形显示EA = 1;}/*****************************************************显示ASCII字符输入参数:X:行Y:列N:显示的ASCII()Z:是否反显,1/0:反显/正常显示输出:无******************************************************/void DisAsc(unsigned char x,y,x1,y1,n,bit z){unsigned char i;if(z){y = y+y1;for(i=0;i<12;i++){fnSetPos(x+x1,y+i);fnPR12(AUT_WR); //自动写设置fnPR13(~ASC1212[n].OUT[i]);fnPR12(AUT_OVR); //自动写结束}}else{y = y+y1;for(i=0;i<12;i++){fnSetPos(x+x1,y+i);fnPR12(AUT_WR); //自动写设置fnPR13(ASC1212[n].OUT[i]);fnPR12(AUT_OVR); //自动写结束}}}/*****************************************************显示汉字字符输入参数:X:行Y:列N:显示的ASCII()Z:是否反显,1/0:反显/正常显示输出:无******************************************************/void DisHz(unsigned char x,unsigned char y ,unsigned char x1,unsigned char y1 ,unsigned char n,bit z){unsigned char i;if(z){y+=y1;for(i=0;i<12;i++){fnSetPos(x+x1,y+i);fnPR12(AUT_WR); //自动写设置fnPR13(~HZ1212[n].OUT[2*i]);fnPR13(~HZ1212[n].OUT[2*i+1]);fnPR12(AUT_OVR); //自动写结束}}else{y+=y1;for(i=0;i<12;i++){fnSetPos(x+x1,y+i);fnPR12(AUT_WR); //自动写设置fnPR13(HZ1212[n].OUT[2*i]);fnPR13(HZ1212[n].OUT[2*i+1]);fnPR12(AUT_OVR); //自动写结束}}}/*****************************************************显示ASCII字符、汉字字符输入参数:X:行Y:列x1: 行偏移几个点y1: 列偏移几个点Z:是否反显,1/0:反显/正常显示ptr:显示的字符串输出:无******************************************************/void Dis(unsigned char x,unsigned char y,unsigned char x1,unsigned char y1 ,bit z,unsigned char *ptr){unsigned char n;EA = 0;y *= 15;fnPR1(ADD_POS,y,x); /* 置地址指针*/while(*ptr!=0){if(*ptr<0xa0) //显示ASC字码{if( x > 30 ){y += 12;x = 0;}n=0;while(ASC1212[n].In != End && ASC1212[n].In != *ptr){ n++; }DisAsc(x,y,x1,y1,n,z); //DisAsc(0,0,0,3,1,0); DisAsc(0,0,0,3,1,0);//DisAsc(1,0,0,3,2,0);//DisAsc(2,0,0,3,3,0);x += 1;ptr += 1;}else //显示汉字{if(x/2>30){y += 12;x = 0;}n=0;while(HZ1212[n].In[0]!=End&&(HZ1212[n].In[0]!=*ptr||HZ1212[n].In[1]!=*(ptr+1))) { n++; }DisHz(x,y,x1,y1,n,z);x += 2;ptr += 2;}}EA = 1;}void DisAsc24(unsigned char x,y,x1,y1,n,bit z){unsigned char i;if(z){y = y+y1;for(i=0;i<16;i++){fnSetPos(x+x1,y+i);fnPR12(AUT_WR); //自动写设置fnPR13(~ASC[n].OUT[i]);fnPR12(AUT_OVR); //自动写结束}}else{y = y+y1;for(i=0;i<16;i++){fnSetPos(x+x1,y+i);fnPR12(AUT_WR); //自动写设置fnPR13(ASC[n].OUT[i]);fnPR12(AUT_OVR); //自动写结束}}}/*****************************************************显示ASCII字符、汉字字符输入参数:X:行Y:列Z:是否反显,1/0:反显/正常显示ptr:显示的字符串输出:无******************************************************/void DisASC1616(unsigned char x,unsigned char y,unsigned char x1,unsigned char y1 ,bit z,unsigned char *ptr){unsigned char n;EA = 0;y *= 19;fnPR1(ADD_POS,y,x); /* 置地址指针*/while(*ptr!=0){if(*ptr<0xa0) //显示ASC字码{if( x > 30 ){y += 16;x = 0;}n=0;while(ASC[n].In != End && ASC[n].In != *ptr){ n++; }DisAsc24(x,y,x1,y1,n,z); //DisAsc(0,0,0,3,1,0); DisAsc(0,0,0,3,1,0);//DisAsc(1,0,0,3,2,0);//DisAsc(2,0,0,3,3,0);x += 1;ptr += 1;}}EA = 1;}void delay1(int i){int j = 2000;while(i--){while(j--);}}/*x,y为坐标,l为长度,Bp为第几个点,Lm为横竖线*/void DrawLine(unsigned char x,y,l,char Bp,bit Lm){unsigned char i,j;EA = 0;if(Lm) //画横线{for( i = 0; i < l;i ++){fnSetPos(x+i, y);for(j = 0;j< 8;j++){if((Bp>>j)&0x01){fnPR12(0xf8 + j);}}/* fnPR12(0xf8 + ((Bp>>0)&0x01));fnPR12(0xf8 + ((Bp>>1)&0x01));fnPR12(0xf8 + ((Bp>>2)&0x01));fnPR12(0xf8 + ((Bp>>3)&0x01));fnPR12(0xf8 + ((Bp>>4)&0x01));fnPR12(0xf8 + ((Bp>>5)&0x01));fnPR12(0xf8 + ((Bp>>6)&0x01));fnPR12(0xf8 + ((Bp>>7)&0x01)); */}}else //画竖线{for( i = 0; i < l;i ++){fnSetPos(x, y+i);fnPR12(0xf8|(7-Bp%8));}}EA = 1;}/**/void DrawPont(unsigned char x,y,Bp) {unsigned char j;EA = 0;fnSetPos(x, y);for(j = 0;j< 8;j++){if((Bp>>j)&0x01){fnPR12(0xf8 + j);}}EA = 1;}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
液晶显示模块的应用一、结构特点内藏T6963C 的液晶显示模块上已经实现了T6963C 与行、列驱动器及显示缓冲区RAM 的接口,同时也已用硬件设置了液晶屏的结构(单双屏、数据传输方式、显示窗口长度、宽度等等。
我们常用的液晶显示模块一般都是单屏结构,因此我们这里只讨论单屏结构的液晶显示模块。
内藏T6963C 的单屏结构点阵图形液晶显示模块的方框图如下:二、T6963C 的特点(1) T6963C 是点阵式液晶图形显示控制器它能直接与8 位微处理器接口;(2) T6963C 的字符字体可由硬件或软件设置,其字体有4 种5X8 、6X8 、7X8、8X8;(3) T6963C 的占空比可从1/16 到1/128;(4) T6963C 可以图形方式、文本方式及图形和文本合成方式进行显示,以及文本方式下的特征显示,还可以实现图形拷贝操作等等;(5) T6963C 具有内部字符发生器CGROM,共有128 个字符。
T6963C 可管理64K显示缓冲区及字符发生器CGRAM,并允许MPU 随时访问显示缓冲区,甚至可以进行位操作。
三、该类液晶模块的管脚定义见下表:说明:对于单电源模块,标志为V0/POFF。
当该管脚为高或悬空时,内部DC/DC 功能开启;为低时,内部DC/DC 功能关闭。
该功能可用作屏幕保护和休眠方式。
如果用其直接替代双电源模块,该管脚直接悬空即可。
四、液晶显示模块的供电说明1. 如果您所选用的液晶模块是双电源(VDD/V0)供电的就需要提供一个负电压(液晶驱动电压V0/VEE),用以调节对比度,接在液晶模块的V0 引脚上。
因为液晶材料的物理特性,液晶的对比度会随着温度的变化而相应变化,所以,您加的负电压值应该随温度作相应的调整,大致是温度变化10°C 电压变化1伏左右。
为满足这一要求您要选择较大值的负电源,然后做一个温度补偿电路,或者安排一个电位器调整负电压值。
例如对于QH12864T-HT-LED04,当室温(VDD=5V)时,V0=-10.5V,如果要用到-20°C,液晶驱动电压将要变到V0=-14.5V,再考虑到负载消耗所以您提供的负电源应该为-16V 左右。
但如果超过此值太多或说超过了液晶驱动电源的极限值的话应该考虑保护电路。
2. 常用负电源产生办法1) 采用79 系列三端集成稳压器可产生-18v(7918) -24v(7924)等电源2) 采用DC-DC 模块市场上常见的5D**系列型号可选择使用3) 采用DC-DC 集成电路制作负电源如MAX749、 MAX680、 MC34063 等。
3. 液晶模块可选用带背光的型号大部分为LED 背光方式,供电为3.8~4.3V 直流电源,严格限制5V 电源直接供电,否则不仅会增加您的功耗,更会增加损坏背光灯的可能性和缩短液晶模块的使用寿命。
推荐电压如下:当背光方式为LED04 即底背光时VLED<4.0V;当背光方式为LED03 即边背光时VLED 4.1V。
五、T6963C 与MPU 的接口时序:T6963C 与MPU 接口时序如图:六、液晶显示模块指令系统该类液晶模块的系统指令集其实就是T6963C 控制器的指令集。
模块的初始化设置一般都由管脚设置完成,因此其指令系统将集中于显示功能的设置上。
T6963C的指令可带一个或两个参数,或无参数。
每条指令的执行都是先送入参数(如果有的话),再送入指令代码。
每次操作之前,最好先进行状态字检测。
T6963C 的状态字如下所示:由于状态位作用不一样,因此执行不同指令必须检测不同状态位。
在MPU每一次读写指令和数据时,STA0 和STA1 要同时有效――处于"准备好"状态。
当MPU 读写数组时,判断STA2 或STA3 状态。
屏读、屏拷贝指令使用STA6。
STA5 和STA7 反映T6963C 内部运行状态。
T6963C指令系统的说明:1、指针设置指令,格式如下:D1,D2为第一和第二个参数,后一个字节为指令代码,根据N0,N1,N2的取值,该指令有三种含义(N0,N1,N2不能有两个同时为1)(1)光标指针设置:D1表示光标在实际液晶屏上离左上角的横向距离(字符数),D2表示纵向距离(字符行)(2) CGRAM偏置地填寄存器设置:设置了CGRAM在显示64KRAM内的高5位地址,CGRAM的实际地址为:(3)地址指针设置:设置将要进行操作的显示缓冲区(RAM)的一个单元地址,D1、D2为该单元地址的低位和高位地址。
2、显示区域设置,指令格式为:根据N1,N0的不同取值,该指令有四种指令功能形式:文本区和图形区首地址为对应显示屏上左上角字符位或字节位,修改该地址可以产生卷动效果。
D1,D2分别为该地址的低位和高位字节。
文本区宽度(字节数/行)设置和图形区宽度(字节数/行)设置用于调整一行显示所占显示RAM的字节数,从而确定显示屏与显示RAM单元的对应关系。
T6963C硬件设置的显示窗口宽度是指T6963C扫描驱动的有效列数。
需说明的是当硬件设置6×8字体时,图形显示区单元的低6位有效,对应显示屏上6×1显示位。
3、显示方式设置,指令格式为:N3:字符发生器选择位。
N3=1为外部字行发生器有效,此时内部字符发生器被屏蔽,字符代码全部提供给外部字符发生器使用,字符代码为00H-FFH。
N3=0为CGROM即内部字符发生器有效,由于CGROM字符代码为00H~7FH。
因此选用80H~FFH字符代码时,将自动选择CGRAM。
N2~N0:合成显示方式控制位,其组合功能如下表:当设置文本方式和图形方式无能打开时,上述合成显示方式设置才有效。
其中的文本特征方式是指将图形区改为文本特征区。
该区大小与文本区相同,每个字节作为对应文本区的每个字符显示的特征,包括字符显示与不显示、字符闪烁及字符的“负向”显示。
通过这种方式,T6963C可以控制每个字符的文本特征。
文本特征区内,字符的文本特征码由一个字节的低四位组成,即:d3:字符闪烁控制位,d3=1为闪烁,d3=0为不闪烁;d2~d0的组合如下:启用文本特征方式时可在原有图形区和文本区外用图形区域设置指令另开一区作为文本特征区,以保持原图形区的数据。
显示缓冲区可划分如下:4、显示开关,指令格式如下:N0:1/0,光标闪烁启用/禁止N1:1/0,光标显示启用/禁止N2:1/0,文本显示启用/禁止N3:1/0,图形显示启用/禁止5、光标形状选择,指令格式如下:光标形状为8点(列) N行,N的值为0-7H6、数据自动读、写方式设置:该指令执行后,MPU可以连续地读、写显示缓冲区RAM的数据,每读、写一次,地址指针自动增1。
自动读、写结束时,必须写入自动结束命令以使T6963C退出自动读、写状态,开始接受其它指令。
N1,N0组合功能如下:7、数据一次读、写方式,指令格式如下:D1为需要写的数据,读时无此数据。
8、屏读,指令格式为:该指令将屏上地址指针处文本与图形合成后显示的一字节内容数据送到T6963C的数据栈内,等待MPU读出。
地址指针应在图形区内设置。
9、屏拷贝,指令格式为:该指令将屏上当前地址指针(图形区内)处开始的一行合成显示内容拷贝到相对应的图形显示区的一组单元内,该指令不能用于文本特征方式下或双屏结构液晶显示器的应用上。
10、位操作:该指令可将显示缓冲区某单元的某一位清零或置1,该单元地址当前地址指针提供。
N3=1置1,N3=0清零。
N2~N0:操作位,对应该单元的D0~D7位。
至此,T6963C的指令系统全部讲述完毕。
七、液晶显示模块与MCU的接口方法一、直接访问方式MPU可利用数据总线与控制信号直接采用I/O设备访问形式控制T6963C类液晶显示模块。
接口电路以精电蓬远公司提供的演示板为例,如下图所示:8031数据口P0口直接与液晶显示模块的数据口连接,由于T6963C接口适用于8080系列和Z80系列MPU,所以可以直接用8031的/RD、/WR作为液晶显示模块的读、写控制信号,液晶显示模块/RESET,/HALT挂在+5V上。
/CE信号可由地址线译码产生。
C/D信号由8031地址线A8提供,A8=1为指令口地址;A8=0为数据口地址。
指令通道地址C_ADD:8100H数据通道地址D_ADD:8000H二、间接控制方式间接控制方式是MPU通过并行接口间接实现对液晶显示模块控制。
根据液晶模块的需要,并行接口需要一个8位的并行接口和一个3位的并行口,由上图所示。
8031的P1口作为数据总线。
P3口中3位作为读、写及寄存器选择信号。
由于并行接口只用于液晶显示模块,所以/CE信号接地就行了。
MPU通过并行接口操纵液晶显示模块,要对其时序关系有一个清楚的了解,并在程序中应明确地反映出来。
八、LCD驱动程序的设计以直接访问方式为例,说明LCD驱动程序的编制方法。
#include <absacc.h>#include <reg52.h>#include <string.h>#include <stdio.h>#include <math.h>#define ulong unsigned long#define uint unsigned int#define uchar unsigned char#define TRUE 1#define FALSE 0#define HIGH 1#define LOW 0// T6963C 端口定义#define LCMDW XBYTE[0x08100H] // 数据口#define LCMCW XBYTE[0x08000H] // 命令口// T6963C 命令定义#define LCM_CUR_POS 0x21 // 光标位置设置#define LCM_CGR_POS 0x22 // CGRAM偏置地址设置#define LCM_ADD_POS 0x24 // 地址指针位置#define LCM_TXT_STP 0x40 // 文本区首址#define LCM_TXT_WID 0x41 // 文本区宽度#define LCM_GRH_STP 0x42 // 图形区首址#define LCM_GRH_WID 0x43 // 图形区宽度#define LCM_MOD_OR 0x80 // 显示方式:逻辑"或"#define LCM_MOD_XOR 0x81 // 显示方式:逻辑"异或"#define LCM_MOD_AND 0x83 // 显示方式:逻辑"与"#define LCM_MOD_TCH 0x84 // 显示方式:文本特征#define LCM_DIS_SW 0x90 // 显示开关:D0=1/0:光标闪烁启用/禁用;// D1=1/0:光标显示启用/禁用;// D2=1/0:文本显示启用/禁用;// D3=1/0:图形显示启用/禁用;#define LCM_CUR_SHP 0xA0 //光标形状选择:0xA0-0xA7表示光标占的行数#define LCM_AUT_WR 0xB0 // 自动写设置#define LCM_AUT_RD 0xB1 // 自动读设置#define LCM_AUT_OVR 0xB2 // 自动读/写结束#define LCM_INC_WR 0xC0 // 数据一次写,地址加1#define LCM_INC_RD 0xC1 // 数据一次读,地址加1#define LCM_DEC_WR 0xC2 // 数据一次写,地址减1#define LCM_DEC_RD 0xC3 // 数据一次读,地址减1#define LCM_NOC_WR 0xC4 // 数据一次写,地址不变#define LCM_NOC_RD 0xC5 // 数据一次读,地址不变#define LCM_SCN_RD 0xE0 // 屏读#define LCM_SCN_CP 0xE8 // 屏拷贝#define LCM_BIT_OP 0xF0 /* 位操作:D0-D2:定义D0-D7位;D3:1置位;0:清除*//* ----- 定义液晶屏内部RAM ------ */#define LCM_T_BASE 0x00 // 文本区内存首地址#define LCM_G_BASE 0x00 // 图形区内存首地址#define LCM_BYTES_PER_ROW 16 // 定义屏幕文本宽度为16字节// 绘图坐标限制#define LCM_XMAX 128#define LCM_XMIN 0#define LCM_YMAX 64#define LCM_YMIN 0//判准备好子程序uchar fnST01(void) // 状态位STA1,STA0判断(读写指令和读写数据){uchar i;for(i=10;i>0;i--){if((LCMCW & 0x03) == 0x03)break;}return i; // 若返回零,说明错误}uchar fnST2(void) // 状态位ST2判断(数据自动读状态){uchar i;for(i=10;i>0;i--){if((LCMCW & 0x04) == 0x04)break;}return i; // 若返回零,说明错误}uchar fnST3(void) // 状态位ST3判断(数据自动写状态){uchar i;for(i=10;i>0;i--){if((LCMCW & 0x08) == 0x08)break;}return i; // 若返回零,说明错误}uchar fnST6(void) // 状态位ST6判断(屏读/屏拷贝状态){uchar i;for(i=10;i>0;i--){if((LCMCW & 0x40) == 0x40)break;}return i; // 若返回零,说明错误}uchar fnPR10(uchar uCmd,uchar uPar1,uchar uPar2) // 写双参数的指令{if(fnST01() == 0)return 1;LCMDW = uPar1;if(fnST01() == 0)return 2;LCMDW = uPar2;if(fnST01() == 0)return 3;LCMCW = uCmd;return 0; // 返回0成功}uchar fnPR11(uchar uCmd,uchar uPar1) // 写单参数的指令{if(fnST01() == 0)return 1;LCMDW = uPar1;if(fnST01() == 0)return 2;LCMCW = uCmd;return 0; // 返回0成功}uchar fnPR12(uchar uCmd) // 写无参数的指令{if(fnST01() == 0)return 1;LCMCW = uCmd;return 0; // 返回0成功}uchar fnPR13(uchar uData) // 一次写数据{if(fnST01() == 0)return 1;LCMDW = uData;return 0; // 返回0成功uchar fnPR14(uchar uData) // 自动写数据{if(fnST3() == 0)return 1;LCMDW = uData;return 0; // 返回0成功}uchar fnPR2(void) // 一次读数据{if(fnST01() == 0)return 1;return LCMDW;}//设置地址void LCM_set_address(unit addr){ fnPR1(LCM_ADD_POS, addr & 0xFF, addr / 256); //0x24为设定地址命令}//文本方式设置显示坐标void LCM_xy(uchar x, uchar y){uint addr;addr = LCM_T_BASE + (y * LCM_BYTES_PER_ROW) + x;LCM_set_address(addr); // 设置显示地址}//文本清屏void LCM_clear_text(void){uint i;fnPR1(LCM_ADD_POS, LCM_T_BASE,0x00); // 置地址指针fnPR12(LCM_AUT_WR); // 自动写for(i=0;i<16*8*;i++){fnST3();fnPR14(0x00); // 写数据}fnPR12(LCM_AUT_OVR); // 自动写结束fnPR1(LCM_ADD_POS, LCM_T_BASE,0x00); // 重置地址指针}}// 图形清屏void LCM_clear_graph(void){uint i;fnPR1(LCM_ADD_POS, LCM_G_BASE,0x00); // 置地址指针fnPR12(LCM_AUT_WR); // 自动写for(i=0;i<16*8*8;i++){fnST3();fnPR14(0x00); // 写数据}fnPR12(LCM_AUT_OVR); // 自动写结束fnPR1(LCM_ADD_POS, LCM_G_BASE,0x00); // 重置地址指针}//清全部32KB内存void LCM_clear_ram(void){uint i;fnPR1(LCM_ADD_POS, 0x00,0x00); // 置地址指针fnPR12(LCM_AUT_WR); // 自动写for(i=0;i<8000;i++){fnST3();fnPR14(0x00); // 写数据}fnPR12(LCM_AUT_OVR); // 自动写结束fnPR1(LCM_ADD_POS, 0x00,0x00); // 重置地址指针}// 初始化显存和显示模式void LCM_init (void){if(fnPR1(LCM_TXT_STP, LCM_T_BASE,0x00) != 0) // 文本显示区首地址return -1;fnPR1(LCM_TXT_WID, LCM_BYTES_PER_ROW,0x00); // 文本显示区宽度fnPR1(LCM_GRH_STP, LCM_G_BASE,0x00); // 图形显示区首地址fnPR1(LCM_GRH_WID, LCM_BYTES_PER_ROW,0x00); // 图形显示区宽度fnPR12(LCM_CUR_SHP | 0x07); // 光标形状fnPR1(LCM_ADD_POS, 0x00,0x00); // 光标位置设置fnPR12(LCM_MOD_OR); // 显示方式设置fnPR12(LCM_DIS_SW | 0x0C); //显示设置为:图形开、文本开// 注意:如果设置显示光标,需要设定光标的位置return 0;}// 显示字符串RAMvoid LCM_print_ram(uchar x,uchar y, uchar *string){uchar i,c;LCM_xy(x,y);fnPR12(LCM_AUT_WR); // 自动写for (i=0;string[i]!=0;i++){c = string[i] - 0x20; // 转换ASCII码为屏幕内码fnPR14(c); // 写数据}fnPR12(LCM_AUT_OVR); // 自动写结束}//声明函数uchar fnST01(void) // 状态位STA1,STA0判断(读写指令和读写数据)uchar fnST2(void) // 状态位ST2判断(数据自动读状态)uchar fnST3(void) // 状态位ST3判断(数据自动写状态)uchar fnST6(void) // 状态位ST6判断(屏读/屏拷贝状态)uchar fnPR10(uchar uCmd,uchar uPar1,uchar uPar2) // 写双参数的指令uchar fnPR11(uchar uCmd,uchar uPar1) // 写单参数的指令uchar fnPR12(uchar uCmd) // 写无参数的指令uchar fnPR13(uchar uData) // 一次写数据uchar fnPR14(uchar uData) // 自动写数据uchar fnPR2(void) // 一次读数据void LCM_init(void); // 初始化显存和显示方式void LCM_xy(uchar x, uchar y); // 设置显示坐标(文本模式)void LCM_clear_text(void); // 文本清屏void LCM_print_ram(uchar x,uchar y,char *string); // 显示字符串RAMvoid LCM_set_address(unit addr); //设置地址void LCM_clear_graph(void); // 图形清屏void LCM_pixel(uchar column, uchar row, char show); //画、清点void LCM_show(uchar * s,int start_line,int how_many_line); //指定数据组图void LCM_line(int x1, int y1, int x2, int y2, uchar show); //画直线void LCM_circle(int x, int y, int radius, uchar show); //画圆void LCM_circle_half(int x, int y, int radius, uchar show);//画半圆void LCM_box(int x1, int y1, int x2, int y2, uchar show); //画矩形//画线段void LCM_degree_line(int x, int y, int degree, int inner_radius, int outer_radius, uchar show);//画线段包围线void LCM_degree_line_bold(int x, int y, int degree, int inner_radius, int outer_radius, uchar show);void LCM_fill(int x1, int y1, int x2, int y2, uchar persent,char first); //画进度条void DelayMs(unit ms);//画、清点函数//column为水平点数,row为垂直点数//show=1画点,show=0清点void LCM_pixel(uchar column, uchar row, char show){int addr; // memory address of byte containing pixel to writeif( (column>=LCM_XMAX) || (row>=LCM_YMAX) )return;addr = LCM_G_BASE + (row*LCM_BYTES_PER_ROW) + (column/8);LCM_set_address(addr); // set LCD addr. Pointerif(show)fnPR13(0xf8 | (7-column%8)); // 0xf8为画点命令elsefnPR13(0xf0 | (7-column%8)); // 0xf0为清点命令}//以指定的数据进行画点void LCM_show(uchar * s,int start_line,int how_many_line){int addr,i;addr = LCM_G_BASE +start_line*16;LCM_set_address(addr);fnPR12(LCM_AUT_WR); //自动写模式for(i=0;i<how_many_line*16;i++){fnPR14(s[i]);}fnPR12(LCM_AUT_OVR); // 自动写结束}/*********************************************************************** 画一条x1,y1到x2,y2的直线(show=1画点,show=0清点)***********************************************************************/ void LCM_line(int x1, int y1, int x2, int y2, uchar show){int dy ;int dx ;int stepx, stepy, fraction;dy = y2 - y1;dx = x2 - x1;if (dy < 0){dy = -dy;stepy = -1;}else{stepy = 1;}if (dx < 0)dx = -dx;stepx = -1;}else{stepx = 1;}dy <<= 1;dx <<= 1;LCM_pixel(x1,y1,show); if (dx > dy){fraction = dy - (dx >> 1); while (x1 != x2){if (fraction >= 0){y1 += stepy;fraction -= dx;}x1 += stepx;fraction += dy;LCM_pixel(x1,y1,show);}else{fraction = dx - (dy >> 1);while (y1 != y2){if (fraction >= 0){x1 += stepx;fraction -= dy;}y1 += stepy;fraction += dx;LCM_pixel(x1,y1,show);}}}/*********************************************************************** 以x,y为圆心,以radius为半径画贺(show=1画点,show=0清点)***********************************************************************/ void LCM_circle(int x, int y, int radius, uchar show){int yc ;int p ;yc=radius;p = 3 - (radius<<1);while (xc <= yc){LCM_pixel(x + xc, y + yc, show);LCM_pixel(x + xc, y - yc, show);LCM_pixel(x - xc, y + yc, show);LCM_pixel(x - xc, y - yc, show);LCM_pixel(x + yc, y + xc, show);LCM_pixel(x + yc, y - xc, show);LCM_pixel(x - yc, y + xc, show);LCM_pixel(x - yc, y - xc, show);if (p < 0)p += (xc++ << 2) + 6;elsep += ((xc++ - yc--)<<2) + 10;}}//画半圆void LCM_circle_half(int x, int y, int radius, uchar show) {int yc ;int p ;yc=radius;p = 3 - (radius<<1);while (xc <= yc){// LCM_pixel(x + xc, y + yc, show);LCM_pixel(x + xc, y - yc, show);// LCM_pixel(x - xc, y + yc, show);LCM_pixel(x - xc, y - yc, show);// LCM_pixel(x + yc, y + xc, show);LCM_pixel(x + yc, y - xc, show);// LCM_pixel(x - yc, y + xc, show);LCM_pixel(x - yc, y - xc, show);if (p < 0)p += (xc++ << 2) + 6;elsep += ((xc++ - yc--)<<2) + 10;}}//画矩形void LCM_box(int x1, int y1, int x2, int y2, uchar show) {LCM_line(x1,y1,x2,y1,show); // upLCM_line(x1,y2,x2,y2,show); // downLCM_line(x2,y1,x2,y2,show); // rightLCM_line(x1,y1,x1,y2,show); // left}//***********************************************************************//以x,y点为原点,以degree为角度,画一条从内径到外径之间的线段//(show=1画点,show=0清点)//***********************************************************************/*void LCM_degree_line(int x, int y, int degree, int inner_radius, int outer_radius, uchar show){int fx,fy,tx,ty;fx = x + (inner_radius * sin(degree * 3.14 / 180));fy = y - (inner_radius * cos(degree * 3.14 / 180));tx = x + (outer_radius * sin(degree * 3.14 / 180));ty = y - (outer_radius * cos(degree * 3.14 / 180));LCM_line(fx,fy,tx,ty,show);}//画上函数线段的包括线void LCM_degree_line_bold(int x, int y, int degree, int inner_radius, int outer_radius, uchar show){int fx,fy,tx,ty;fx = x + (inner_radius * sin(degree * 3.14 / 180));fy = y - (inner_radius * cos(degree * 3.14 / 180));tx = x + (outer_radius * sin(degree * 3.14 / 180));ty = y - (outer_radius * cos(degree * 3.14 / 180));LCM_line(fx,fy,tx,ty,show);LCM_line(fx+1,fy+1,tx+1,ty+1,show);LCM_line(fx-1,fy-1,tx-1,ty-1,show);}*///画进度条函数/*void LCM_fill(int x1, int y1, int x2, int y2, uchar persent,char first) {char M,horizon_line,horizon_line2,i,str1[10];if(persent>100)return;if(!first){LCM_line(x1,y2,x2,y2,1); // downLCM_line(x2,y1,x2,y2,1); // rightLCM_line(x1,y1,x1,y2,1); // leftfirst=1;}M=100/abs(y2-y1);horizon_line=persent/M;for(i=0;i<horizon_line;i++)LCM_line(x1+2,y2-2-i,x2-2,y2-2-i,1);horizon_line2=100/M;for(i=horizon_line;i<horizon_line2;i++)LCM_line(x1+2,y2-2-i,x2-2,y2-2-i,0);sprintf(str1,"%02d%% ",persent);LCM_print_ram( (x2+x1)/16-1 , (y2+y1)/16,str1);}*//************************************************************************** 延时ms:延时的毫秒数***************************************************************************/void DelayMs(unit ms){unit iq0, iq1;for (iq0 = ms; iq0 > 0; iq0--)for (iq1 = 1000; iq1 > 0; iq1--);}void main(void) // 测试用{LCM_init();LCM_clear_ram();LCM_circle(120,64,20,1);LCM_circle_half(60,64,20,1);LCM_box(150,20,180,60,1);}。