T6963C的51單片機驅動程序:http://www.zg4o1577.cn/mcu/3135.html
#include<stdio.h>
#include<intrins.h>
#include <reg52.h>
#include <math.h>
#include <absacc.h>
#include <string.h>
#include "Test.h"
/* 地址定義 */
#define d_c_add XBYTE[0x00] //數據口 命令口
/* 常數定義 */
#define uchar unsigned char
#define uint unsigned int
/* T6963C 命令定義 */
#define LCD_CUR_POS 0x21 /* 光標位置設置(只有設置到有效顯示地址并打開顯示時才看到) */
#define LCD_CGR_POS 0x22 /* CGRAM偏置地址設置(可以增加自已的符號) */
#define LCD_ADR_POS 0x24 /* 地址指針位置(設置讀寫操作指針) */
#define LCD_TXT_STP 0x40 /* 文本區首址(從此地址開始向屏幕左上角顯示字符) */
#define LCD_TXT_WID 0x41 /* 文本區寬度(設置顯示寬度,N/6或N/8,其中N為x軸的點數) */
#define LCD_GRH_STP 0x42 /* 圖形區首址(從此地址開始向屏幕左上角顯示點) */
#define LCD_GRH_WID 0x43 /* 圖形區寬度(設置顯示寬度,N/6或N/8,其中N為x軸的點數) */
#define LCD_MOD_OR 0x80 /* 顯示方式:邏輯或 */
#define LCD_MOD_XOR 0x81 /* 顯示方式:邏輯異或 */
#define LCD_MOD_AND 0x82 /* 顯示方式:邏輯與 */
#define LCD_MOD_TCH 0x83 /* 顯示方式:文本特征 */
#define LCD_DIS_SW 0x90 /* 顯示開關:D0=1/0,光標閃爍啟用/禁用 */
/ * D1=1/0,光標顯示啟用/禁用 */
/* D2=1/0,文本顯示啟用/禁用(打開后再使用) */
/* D3=1/0,圖形顯示啟用/禁用(打開后再使用) */
#define LCD_CUR_SHP 0xA0 /* 光標形狀選擇:0xA0-0xA7表示光標占的行數 */
#define LCD_AUT_WR 0xB0 /* 自動寫設置 */
#define LCD_AUT_RD 0xB1 /* 自動讀設置 */
#define LCD_AUT_OVR 0xB2 /* 自動讀/寫結束 */
#define LCD_INC_WR 0xC0 /* 數據一次寫,地址加1 */
#define LCD_INC_RD 0xC1 /* 數據一次讀,地址加1 */
#define LCD_DEC_WR 0xC2 /* 數據一次寫,地址減1 */
#define LCD_DEC_RD 0xC3 /* 數據一次讀,地址減1 */
#define LCD_NOC_WR 0xC4 /* 數據一次寫,地址不變 */
#define LCD_NOC_RD 0xC5 /* 數據一次讀,地址不變 */
#define LCD_SCN_RD 0xE0 /* 屏讀 */
#define LCD_SCN_CP 0xE8 /* 屏拷貝 */
#define LCD_BIT_OP 0xF0 /* 位操作:D0-D2--定義D0-D7位,D3--1為置位,0為清除 */
/* 定義標志位 */
sbit CD = P1^0;
sbit CE = P1^1;
sbit light = P1^2;
extern uchar code HZTable[ ][32];
extern uchar code ASCII_DOT_LIB[][16];
/********************************************************************************************************/
/***********************************************************************
* 名稱:LCD_TestStaBit01()
* 功能:判斷讀寫指令和讀寫數據是否允許。
* 入口參數:無
* 出口參數:返回0表示禁止,否則表示允許
***********************************************************************/
uchar LCD_TestStaBit01(void)
{ uchar i;
CD=1;
for(i=100; i>0; i--)
{ if( (d_c_add&0x03)==0x03 ) break;
}
return(i);
}
/***********************************************************************
* 名稱:LCD_TestStaBit02()
* 功能:查詢是否可數據自動讀狀態
* 入口參數:無
* 出口參數:返回0表示禁止,否則表示允許
***********************************************************************/
uchar LCD_TestStaBit02(void)
{ uchar i;
CD=1;
for(i=100; i>0; i--)
{ if( (d_c_add&0x04)==0x04 ) break;
}
return(i);
}
/***********************************************************************
* 名稱:LCD_TestStaBit03()
* 功能:數據自動寫狀態是否允許。
* 入口參數:無
* 出口參數:返回0表示禁止,否則表示允許
***********************************************************************/
uchar LCD_TestStaBit03(void)
{ uchar i;
CD=1;
for(i=100; i>0; i--)
{ if( (d_c_add&0x08)==0x08 ) break;
}
return(i);
}
/********************************************************************************************************/
/***********************************************************************
* 名稱:LCD_ReadState()
* 功能:讀取狀態字子程序。
* 入口參數:無
* 出口參數:返回值即為讀出的狀態字
* 說明:函數會設置LCM數據總線為輸入方式
***********************************************************************/
LCD_WriteCommand(uchar command)
{
CD=1;
d_c_add=command;
}
/********************************************************************************************************/
/***********************************************************************
* 名稱:LCD_WriteData()
* 功能:寫數據子程序。(發送數據前,不檢查液晶模塊的狀態)
* 入口參數:dat 要寫入LCM的數據
* 出口參數:無
* 說明:函數會設置LCM數據總線為輸出方式
***********************************************************************/
LCD_WriteData(uchar dat)
{
CD=0;
d_c_add=dat;
}
/********************************************************************************************************/
/***********************************************************************
* 名稱:LCD_ReadData()
* 功能:讀取數據子程序。
* 入口參數:無
* 出口參數:返回值即為讀出的數據
* 說明:函數會設置LCM數據總線為輸入方式
***********************************************************************/
uchar LCD_ReadData(void)
{
uchar dat;
CD=0;
dat=d_c_add;
return dat;
}
/**************************************LCD_WriteTCommand1******************************************************************/
/***********************************************************************
* 名稱:LCD_WriteTCommand1()
* 功能:寫無參數命令子程序。會先判斷LCM狀態字。
* 入口參數:command 要寫入LCM的命令字
* 出口參數:操作出錯返回0,否則返回1
***********************************************************************/
uchar LCD_WriteTCommand1(uchar command)
{ if( LCD_TestStaBit01()==0 )return(0);
LCD_WriteCommand(command); // 發送命令字
return(1);
}
/********************************LCD_WriteTCommand2************************************************************************/
/***********************************************************************
* 名稱:LCD_WriteTCommand2()
* 功能:寫單參數命令子程序。會先判斷LCM狀態字。
* 入口參數:command 要寫入LCM的命令字
* dat1 參數1
* 出口參數:操作出錯返回0,否則返回1
* 說明:先發送參數據數據,再發送命令字
***********************************************************************/
uchar LCD_WriteTCommand2(uchar command, uchar dat1)
{ if( LCD_TestStaBit01()==0 ) return(0);
LCD_WriteData(dat1); // 發送數據1
if( LCD_TestStaBit01()==0 ) return(0);
LCD_WriteCommand(command); // 發送命令字
return(1);
}
/********************************LCD_WriteTCommand3************************************************************************/
/***********************************************************************
* 名稱:LCD_WriteTCommand3()
* 功能:寫雙參數命令子程序。會先判斷LCM狀態字。
* 入口參數:command 要寫入LCM的命令字
* dat1 參數1
* dat2 參數2
* 出口參數:操作出錯返回0,否則返回1
* 說明:先發送兩字節參數據數據,再發送命令字
***********************************************************************/
uchar LCD_WriteTCommand3(uchar command, uchar dat1, uchar dat2)
{ if( LCD_TestStaBit01()==0 ) return(0);
LCD_WriteData(dat1); // 發送數據1
if( LCD_TestStaBit01()==0 ) return(0);
LCD_WriteData(dat2); // 發送數據2
if( LCD_TestStaBit01()==0 ) return(0);
LCD_WriteCommand(command); // 發送命令字
return(1);
}
/******************************LCD_WriteTData1**************************************************************************/
/***********************************************************************
* 名稱:LCD_WriteTData1()
* 功能:寫1字節數據子程序。會先判斷狀態字。
* 入口參數:dat 要寫入LCM的數據
* 出口參數:操作出錯返回0,否則返回1
***********************************************************************/
uchar LCD_WriteTData1(uchar dat)
{ if( LCD_TestStaBit03()==0 ) {return(0);}
LCD_WriteData(dat); // 發送命令字
return(1);
}
/*******************************LCD_Initialize*************************************************************************/
void LCD_Initialize(void)
{ LCD_WriteTCommand3(LCD_TXT_STP, 0x00, 0x00); // 設置文本方式RAM起始地址
LCD_WriteTCommand3(LCD_TXT_WID, 30, 0x00); // 設置文本模式的寬度,寬度為N/6或N/8,N為寬度點數,如240
LCD_WriteTCommand3(LCD_GRH_STP, 0x00, 0x00); // 設置圖形方式RAM起始地址
LCD_WriteTCommand3(LCD_GRH_WID, 30, 0x00); // 設置圖形模式的寬度,寬度為N/6或N/8,N為寬度點數,如240
LCD_WriteTCommand1(LCD_MOD_OR); // 設置顯示方式為"或"
LCD_WriteTCommand1(LCD_DIS_SW|0x08); // 設置純圖形顯示模式
LCD_WriteTCommand1(LCD_CUR_SHP|0x07); // 光標形狀
}
/*********************************LCD_FillAll**********************************************************************/
void LCD_FillAll(uchar dat)
{ uint i;
LCD_WriteTCommand3(LCD_ADR_POS, 0x00, 0x00); // 置地址指針
LCD_WriteTCommand1(LCD_AUT_WR); // 自動寫
for(i=0;i<128*30;i++)
{ LCD_WriteTData1(dat); // 寫數據
}
LCD_WriteTCommand1(LCD_AUT_OVR); // 自動寫結束
LCD_WriteTCommand3(LCD_ADR_POS,0x00,0x00); // 重置地址指針
}
/********************************************************************************************************/
void Write_Hz(uchar x,uchar y,uchar datah)
{
uchar i;
uint StartAddr;
StartAddr=x*480+y;
for(i=0;i<16;i++)
{ LCD_WriteTCommand3(LCD_ADR_POS,StartAddr,((StartAddr)/256));
LCD_WriteTCommand2(LCD_INC_WR,HZTable[datah][i*2] );
LCD_WriteTCommand2(LCD_NOC_WR,HZTable[datah][i*2+1]);
StartAddr=StartAddr + 30;
}
}
/********************************************************************************************************/
//顯示數字
void Write_No(uchar x,uchar y,uchar ch)
{
uchar i, dat;
uint StartAddr;
StartAddr=x*480+y;
for(i=0;i<16;i++)
{
dat=ASCII_DOT_LIB[ch][i];
LCD_WriteTCommand3(LCD_ADR_POS,StartAddr,StartAddr>>8);
LCD_WriteTCommand2(LCD_NOC_WR,dat);
StartAddr=StartAddr + 30;
}
}
/********************************************************************************************************/
//顯示字母,縱向寫字,取模方式:縱向取模,字節正序
void Write_Char(uchar x,uchar y,uchar ch)
{
uchar i, dat;
uint StartAddr,StartAddr1;
StartAddr=x*240+y;
StartAddr1=x*240+y+1;
for(i=0;i<8;i++)
{
dat=ASCII_DOT_LIB[ch][i];
LCD_WriteTCommand3(LCD_ADR_POS,StartAddr,StartAddr>>8);
LCD_WriteTCommand2(LCD_NOC_WR,dat);
StartAddr=StartAddr+30;
}
for(i=0;i<8;i++)
{
dat=ASCII_DOT_LIB[ch][i+8];
LCD_WriteTCommand3(LCD_ADR_POS,StartAddr1,StartAddr1>>8);
LCD_WriteTCommand2(LCD_NOC_WR,dat);
StartAddr1=StartAddr1+30;
}
}
/********************************************************************************************************/
void Charline(uchar x,uchar y ,uchar n,uchar m)
{
uchar i;
for(i=0;i<m;i++)
Write_Char(x,y+i,n+i);
}
/********************************************************************************************************/
void ReverseShowChar(uchar x,uchar y,uchar ch)//CGTAB
{
uchar i, dat;
uint StartAddr,StartAddr1;
StartAddr=x*240+y;
StartAddr1=x*240+y+1;
for(i=0;i<8;i++)
{
LCD_WriteTCommand3(LCD_ADR_POS,StartAddr,StartAddr>>8);
//LCD_WriteTCommand1(0xc5); //數據一次讀,地址不變
//dat=LCD_ReadData(); //讀入數據
dat=ASCII_DOT_LIB[ch][i];
dat=(0xff-dat); //取反
//LCD_WriteTCommand2( dat, 0xc4); //送回
LCD_WriteTCommand2(LCD_NOC_WR,dat);
StartAddr=StartAddr+30;
}
for(i=0;i<8;i++)
{
LCD_WriteTCommand3(LCD_ADR_POS,StartAddr1,StartAddr1>>8);
//LCD_WriteTCommand1(0xc5); //數據一次讀,地址不變
// dat=LCD_ReadData(); //讀入數據
dat=ASCII_DOT_LIB[ch][i+8];
dat=(0xff-dat); //取反
// LCD_WriteTCommand2(dat, 0xc4); //送回
LCD_WriteTCommand2(LCD_NOC_WR,dat);
StartAddr1=StartAddr1+30;
}
}
/**********************************
//= 函數原型: Pixel(unsigned char PointX,unsigned char PointY, bit Mode)
//= 功 能: 在指定坐標位置顯示一個點
//= 參 數: 坐標,顯示點或清除點
//= 返 回 值:
//= 函數性質:私有函數
//= 如果顯示屏超過了256*256,請修改這個函數 PointX,PointY的類型
//= Mode 1:顯示 0:清除該點
**********************************/
Pixel(unsigned char PointX,unsigned char PointY, bit Mode)
{
unsigned int StartAddr;
uchar StartAddrL,StartAddrH;
unsigned char dat;
StartAddr=(uint)((uint)PointX*30 + PointY/8 );//grhome
StartAddrL=StartAddr&0xFF;
StartAddrH=StartAddr>>8;
dat=LCD_BIT_OP+7-PointY%8; //生產位操作命令畫點的數據
if(Mode) dat=dat|0x08;
LCD_WriteTCommand3(LCD_ADR_POS,StartAddrL,StartAddrH);//設置該點所在單元地址
LCD_WriteTCommand1(dat); // 利用位操作命令畫點
}
/**********************************
//= 函數原型: void line( unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, bit Mode)
//= 功 能: 劃線函數
//= 參 數: 坐標1,坐標2,顯示點或清除點
//= 返 回 值:
//= 函數性質:私有函數
//= 其它:顯示點陣不超過255*255
/**********************************/
void line( unsigned char y1,unsigned char x1, unsigned char y2,unsigned char x2, bit Mode)
{
unsigned char x,y;
float k,b;
if( abs(y1-y2) <= abs(x1-x2) ) // |k|<=1
{
k=((float)y2-y1) / ((float)x2-x1) ;
b=y1-k*x1;
if( x1 <= x2 )
{
for(x=x1;x<=x2;x++)
{
y=(uchar)(k*x+b);
Pixel(x, y, Mode);
}
}
else
{
for(x=x2;x<=x1;x++)
{
y=(uchar)(k*x+b);
Pixel(x, y, Mode);
}
}
}
else // abs(y1-y2) > abs(x1-x2) |K|>1
{
k=((float)x2-x1) / ((float)y2-y1) ;
b=x1-k*y1;
if( y1 <= y2 )
{
for(y=y1;y<=y2;y++)
{
x=(uchar)(k*y+b);
Pixel( x , y,Mode );
}
}
else
{
for(y=y2;y<=y1;y++)
{
x=(uchar)(k*y+b);
Pixel( x , y,Mode );
}
}
}
}
/********************************************************************************************************/
uchar code HZTable[ ][32]={
{0x40,0x02,0x27,0xC2,0x24,0x42,0x84,0x52,0x45,0x52,0x55,0x52,0x15,0x52,0x25,0x52,
0x25,0x52,0x25,0x52,0xC5,0x52,0x41,0x02,0x42,0x82,0x42,0x42,0x44,0x4A,0x48,0x04},/*"測",0*/
{0x00,0x20,0x40,0x28,0x20,0x24,0x30,0x24,0x27,0xFE,0x00,0x20,0xE0,0x20,0x27,0xE0,
0x21,0x20,0x21,0x10,0x21,0x10,0x21,0x0A,0x29,0xCA,0x36,0x06,0x20,0x02,0x00,0x00},/*"試",1*/
{0x0D,0xF8,0x71,0x08,0x11,0x08,0x11,0x08,0xFD,0x08,0x11,0xF8,0x30,0x00,0x3B,0xFC,
0x54,0x40,0x50,0x40,0x93,0xFC,0x10,0x40,0x10,0x40,0x10,0x40,0x17,0xFE,0x10,0x00},/*"程",2*/
{0x01,0x00,0x00,0x80,0x3F,0xFE,0x20,0x00,0x27,0xF8,0x21,0x10,0x20,0xA0,0x20,0x40,
0x2F,0xFE,0x20,0x44,0x20,0x40,0x20,0x40,0x20,0x40,0x40,0x40,0x41,0x40,0x80,0x80},/*"序",0*/
{0x06,0x40,0x38,0x50,0x08,0x48,0x08,0x48,0x08,0x40,0xFF,0xFE,0x08,0x40,0x08,0x48,
0x0E,0x28,0x38,0x30,0xC8,0x20,0x08,0x50,0x09,0x92,0x08,0x0A,0x28,0x06,0x10,0x02},/*"我",1*/
};
unsigned char code ASCII_DOT_LIB[][16]=
{
//正確的,縱向取模,字節正序
0x00,0x10,0x18,0x14,0x03,0x11,0x1F,0x10,0x00,0x04,0x1C,0x64,0x80,0x04,0xFC,0x04,
0x00,0x08,0x10,0x17,0x11,0x11,0x1F,0x10,0x00,0x18,0x04,0xC4,0x04,0x04,0xFC,0x04,
0x00,0x10,0x1C,0x13,0x00,0x13,0x1C,0x10,0x00,0x00,0x00,0x04,0xFC,0x04,0x00,0x00,
0x00,0x07,0x08,0x10,0x10,0x08,0x07,0x00,0x00,0xF0,0x08,0x04,0x04,0x08,0xF0,0x00, // -0-
0x00,0x00,0x00,0x00,0x1F,0x08,0x08,0x00,0x00,0x00,0x04,0x04,0xFC,0x04,0x04,0x00, // -1-
0x00,0x0E,0x11,0x10,0x10,0x10,0x0E,0x00,0x00,0x0C,0x84,0x44,0x24,0x14,0x0C,0x00, // -2-
0x00,0x0C,0x12,0x11,0x11,0x10,0x0C,0x00,0x00,0x70,0x88,0x04,0x04,0x04,0x18,0x00, // -3-
0x00,0x00,0x1F,0x08,0x04,0x03,0x00,0x00,0x00,0x24,0xFC,0x24,0x24,0x20,0xE0,0x00, // -4-
0x00,0x10,0x10,0x11,0x11,0x10,0x1F,0x00,0x00,0x70,0x88,0x04,0x04,0x84,0x98,0x00, // -5-
0x00,0x00,0x18,0x11,0x11,0x08,0x07,0x00,0x00,0x70,0x88,0x04,0x04,0x88,0xF0,0x00, // -6-
}; |