12860驅(qū)動(dòng)程序
#include "stdio.h"
#include "regdefs.h"
#include "intrins.h"
#include "user.h"
#include "LCM6059B.h"
#define UINT8 unsigned char // 0~255
#define UINT16 unsigned short int // 0~65535
#define INT8 signed int
//////////// LCD Control Command ////////////
#define DISPLAY_ON 0xaf
#define DISPLAY_OFF 0xae
#define DISPLAY_ALL_POINT_ON 0xa4
#define DISPLAY_ALL_POINT_OFF 0xa5
#define DISPLAY_START_LINE_SET 0x40 //line (0~3f)
#define PAGE_ADDRESS_SET 0xb0 //page (0~8)
#define COLUMN_HIGH_SET 0x10 //high 4 bits
#define COLUMN_LOW_SET 0x0f //low 4 bits
#define DISPLAY_RD_WR_MODIFY 0xe0
#define DISPLAY_RD_WR_MODIFY_END 0xee
#define DISPLAY_CONTTAST_LEVEL 0x81 //level (0~3f)
#define ADC_DIR_SELECT 0xa0
#define DISPLAY_NORMAL 0xa6
#define DISPLAY__REVERSE 0xa7
#define LCD_BIAS_SET 0xa2 //1/9,0 1/7,1
#define LCD_RESET 0xe2
#define COM_OUTPUT_SET 0xC0 //mode 0x00, 0x08
#define POWER_CTRL_SET 0x20 //mode 0x08,0x2c,0x2e,0x2f
#define BOOST_RATIO_SET 0xf8 //0x00,0x01,0x02,0x3
#define VO_CTRL_SET 0x20 //Rb/Ra(0~7)
#define OP_NOP 0xe3 //空操作
//////////// MCU IO configuration ////////////
#define LCD_PORT_CFG sfr_GP_CONTROL1 &=(~0x01) //bit0
#define LCD_PORT_OUT sfr_GPIOA_DIRECTION &=(~0xff);
#define LCD_PORT_IN sfr_GPIOA_DIRECTION |=0xff;
#define LCD_PORT sfr_GPIOA_DATA
// LCD_EN GPIOE_6
// LCD_WR GPIOE_5
#define LCD_WR_EN_OUT sfr_GPIOE_DIRECTION &=(~0x60)
#define LCD_EN_SET(x) x?(sfr_GPIOE_DATA|=0x40):(sfr_GPIOE_DATA&=(~0x40))
#define LCD_WR_SET(x) x?(sfr_GPIOE_DATA|=0x20):(sfr_GPIOE_DATA&=(~0x20))
//LCD_A0 GPIOC_4 H->data ,L-> cmd
#define LCD_A0_OUT sfr_GPIOC_DIRECTION &=(~0x10)
#define LCD_A0_SET(x) x?(sfr_GPIOC_DATA|=0x10):(sfr_GPIOC_DATA&=(~0x10))
//LCD_RST GPIOC_3
//LCD_CS GPIOC_2
//sfr_EXT_INT_xF6 bit7
#define LCD_RST_CS_CFG sfr_EXT_INT_xF6 &=(~0x80)
#define LCD_RST_CS_OUT sfr_GPIOC_DIRECTION &=(~0x0c)
#define LCD_RST_SET(x) x?(sfr_GPIOC_DATA|=0x08):(sfr_GPIOC_DATA&=(~0x08))
#define LCD_CS_SET(x) x?(sfr_GPIOC_DATA|=0x04):(sfr_GPIOC_DATA&=(~0x04))
UINT8 ContrastLevel; // for contrast setting level
void DelayMs(UINT16 m)
{ //12MHZ
UINT16 jj;
UINT16 ii;
for (ii=0; ii<m; ii++)
for (jj=0; jj<109; jj++);
}
BOOL CheckBusy(void)
{
LCD_RST_CS_CFG;
LCD_RST_CS_OUT;
LCD_PORT_CFG;
LCD_PORT_OUT;
LCD_A0_OUT;
LCD_WR_EN_OUT;
LCD_A0_SET(0); //命令通道選通
LCD_WR_SET(1); //設(shè)置讀狀態(tài)
LCD_CS_SET(0);
LCD_PORT=0x80;
LCD_EN_SET(1);
LCD_PORT_IN;
_nop_();
if (LCD_PORT&0x80) return(0);
else return(1);
}
void SendCmd(UINT8 Cmd)
{//
Hal_DisableAllInts(); //為了時(shí)序完整性,禁止中斷
LCD_RST_CS_CFG; //根據(jù)MCU的不同,有可能要配置GPIO
LCD_PORT_CFG;
LCD_RST_CS_OUT;
LCD_PORT_OUT;
LCD_A0_OUT;
LCD_WR_EN_OUT;
LCD_A0_SET(0); // 設(shè)置指令通道
LCD_WR_SET(0); // 設(shè)置寫狀態(tài)
LCD_CS_SET(0); // Chip select
LCD_PORT=Cmd; // 發(fā)送命令
LCD_EN_SET(1);
_nop_();
LCD_EN_SET(0);
LCD_CS_SET(1);
Hal_EnableAllInts(); //中斷開
}
void SendData(UINT8 DData)
{
Hal_DisableAllInts();
//CheckBusy()
LCD_RST_CS_CFG;
LCD_RST_CS_OUT;
LCD_PORT_CFG;
LCD_PORT_OUT;
LCD_A0_OUT;
LCD_WR_EN_OUT;
LCD_A0_SET(1); //設(shè)置數(shù)據(jù)通道
LCD_WR_SET(0);
LCD_CS_SET(0);
LCD_PORT=DData; //發(fā)送數(shù)據(jù)
LCD_EN_SET(1);
_nop_();
LCD_EN_SET(0);
LCD_CS_SET(1);
Hal_EnableAllInts();
}
UINT8 ReadData()
{
UINT8 DData;
LCD_RST_CS_CFG;
LCD_RST_CS_OUT;
LCD_PORT_CFG;
LCD_PORT_OUT;
LCD_A0_OUT;
LCD_WR_EN_OUT;
LCD_A0_SET(1); //數(shù)據(jù)通道選通
LCD_WR_SET(1); //設(shè)置讀狀態(tài)
LCD_CS_SET(0);
LCD_PORT=0xff;
LCD_EN_SET(1);
LCD_PORT_IN;
_nop_();
DData=LCD_PORT;
LCD_EN_SET(0);
LCD_CS_SET(1);
return(DData); // 返回?cái)?shù)據(jù)值
}
void DrawDots2(UINT8 x,UINT8 y,UINT8 flg)
{// 坐標(biāo)(x,y),x為列地址,y為行地址
UINT8 p,m;
p=y/8;
SendCmd(p|PAGE_ADDRESS_SET); // 設(shè)置頁地址
SendCmd((x>>4)|COLUMN_HIGH_SET); // 設(shè)置列地址高4位
SendCmd(x&COLUMN_LOW_SET); // 設(shè)置列地址低4位
SendCmd(DISPLAY_RD_WR_MODIFY); // 設(shè)置修改寫模式
y=y%8;
m=0x01;
y=m<<y; /列地址不進(jìn)行加1
m=ReadData(); // 空讀操作
m=ReadData(); // 讀第m列數(shù)據(jù)
SendCmd(OP_NOP); // 空操作
if (flg) //實(shí)點(diǎn)
{
m|=y;
}
else //虛點(diǎn)
{
m&=(~y);
}
SendData(m); // 寫數(shù)據(jù)
SendCmd(DISPLAY_RD_WR_MODIFY_END);
}
void PrintAscii(UINT8 x,UINT8 y,UINT8 *pstr)
{ //(x,y)為坐標(biāo)
UINT8 ii,jj;
UINT16 addr;
if ((y%8)==0)
{
SendCmd(y|PAGE_ADDRESS_SET);
SendCmd((x>>4)|COLUMN_HIGH_SET);
SendCmd(x&COLUMN_LOW_SET);
while (*pstr)
{
addr=*pstr++; // 取字符代碼
addr=(addr-0x20)*8; // 計(jì)算字符字模起始地址
for (jj=0;jj<6;jj++)
{
SendData(ASCIITAB[addr+jj]); // 寫字模數(shù)據(jù)
}
}
}
else //如否, 由于是跨頁操作,則采用描點(diǎn)方式
{
while (*pstr) //非0
{
addr=*pstr++; // 取字符代碼
addr=(addr-0x20)*8; // 計(jì)算字符字模起始地址
for (jj=0;jj<6;jj++) //6*8點(diǎn)陣字符
{
for (ii=0;ii<8;ii++)
{
DrawDots2(x+jj,y+ii,((ASCIITAB[addr+jj]>>ii)&0x01));
}
}
x+=6; // 描完一個(gè)字,地址加6
}
}
}
void PrintChar2(UINT8 x, UINT8 y,UINT8 *pstr)
{// 坐標(biāo)(x,y),x為水平方向像素列;y為垂直方向字符行(8點(diǎn)像素/行)
UINT8 jj,ii;
UINT16 addr;
addr=*pstr++; // 取字符代碼
addr=(addr-0x20)*8; // 計(jì)算字符字模起始地址
for (jj=0;jj<6;jj++) //6*8點(diǎn)陣字符
{
for (ii=0;ii<8;ii++)
{
DrawDots2(x+jj,y+ii,((ASCIITAB[addr+jj]>>ii)&0x01));
}
}
}
void PrintText(UINT8 x, UINT8 y,UINT16 *pstr)
{// 坐標(biāo)(x,y),x為水平方向像素列;y為垂直方向字符行(8點(diǎn)像素/行)
UINT16 addr;
UINT8 jj;
UINT16 Index,ii;
BOOL IsASCII=FALSE;
UINT8 n,ch;
while(*pstr)
{
if (*pstr<0x8000 && *pstr!=0x2300/*#*/) //是否是ASCII碼
{
ch=(UINT8)(*pstr>>8);
PrintChar2(x,y+4,&ch); //地址調(diào)整
x+=6;
ch=(UINT8)(*pstr);
PrintChar2(x,y+4,&ch); //地址調(diào)整
pstr++;
x+=6;
}
else{
ii=0;
while(1) //查找機(jī)內(nèi)碼
{
if (GBK16TAB[ii]==(*pstr>>8) && GBK16TAB[ii+1]==(*pstr&0xff))
{
Index=ii;
break;
}
ii+=34;
if (ii>=500-32) break; //避免溢出
if (*pstr==0x2300/*#*/) break;
}
if (*pstr==0x2300/*#*/) break;
addr=Index+2; // 取得字模存儲(chǔ)首地址
for (n=0;n<2;n++) //
{
for (jj=0; jj<16;jj++) //先左后右,共width點(diǎn)
{
for (ii=0;ii<8;ii++) //先描上后下,共8點(diǎn)
{
DrawDots2(x,y+ii,((GBK16TAB[addr+jj]>>ii)&0x01));
}
x++;
}
y+=8;
x-=16;
addr+=16;
}
x+=16;
y-=16;
pstr++;
}
}
}
void LCD_SetContrast(BOOL bhv)
{
if (bhv)
{
if (ContrastLevel>0x3f) ContrastLevel++;
}
else
{
if (ContrastLevel>0x00) ContrastLevel--;
}
SendCmd(DISPLAY_CONTTAST_LEVEL);
SendCmd(ContrastLevel);
return;
}
void ShowBMP(UINT8 x,UINT8 y,UINT8 width,UINT8 hight,UINT8 bmp[])
{// (x,y)為圖像顯示開始坐標(biāo)
UINT8 ii,jj,page,Index;
Index=0;
page=0;
while(page<hight)
{
for (jj=0; jj<width;jj++) //先左后右,共width點(diǎn)
{
for (ii=0;ii<8;ii++) //先描上后下,共8點(diǎn)
{
DrawDots2(x,y+ii,((bmp[Index]>>ii)&0x01));
}
x++;
Index++;
}
y+=8;
x-=width;
page+=8;
}
}
void DrawLine(UINT8 x1,UINT8 y1,UINT8 x2,UINT8 y2)
{//坐標(biāo)(x1,y1)為線起始地址坐標(biāo);坐標(biāo)(x2,y2)為線終止地址坐標(biāo)
UINT8 temp;
INT8 Xt,Yt,err=0;
if (y1>y2)
{
temp=x1; x1=x2; x2=temp;
temp=y1; y1=y2; y2=temp;
}
DrawDots2(x1,y1,1);
Xt=x2-x1;
Yt=y2-y1;
if (Xt>=0)
{
if (Yt>Xt)//k>1
{
while (y1<y2)
{
if (err<0)
{
x1=x1+1;
y1=y1+1;
err=err+Yt-Xt;
}
else //err>=0
{
y1=y1+1;
err=err-Xt;
}
DrawDots2(x1,y1,1);
}
}
else // 0<=k=<1
{
if (Yt==0) y1=y1-1;
while (x1<x2)
{
if (err<0)
{
x1=x1+1;
err=err+Yt;
}
else
{
y1=y1+1;
x1=x1+1;
err=err+Yt-Xt;
}
DrawDots2(x1,y1,1);
}
}
}
else
{
Xt=x1-x2;
if (Yt>Xt)//k<-1
{
while (y1<y2)
{
if (err<0)
{
x1=x1-1;
y1=y1+1;
err=err+Yt-Xt;
}
else
{
y1=y1+1;
err=err-Xt;
}
DrawDots2(x1,y1,1);
}
}
else //0>k>=-1
{
if (Yt==0) y1=y1-1;
while (x1>x2)
{
if (err<0)
{
x1=x1-1;
err=err+Yt;
}
else
{
x1=x1-1;
y1=y1+1;
err=err+Yt-Xt;
}
DrawDots2(x1,y1,1);
}
}
}
}
void ClearAllRAM()
{
UINT16 i,j;
for (i=0;i<8;i++) //寫8頁
{
SendCmd(i|PAGE_ADDRESS_SET);
SendCmd(0x10);
SendCmd(0x00);
for (j=0;j<132;j++)
{
SendData(0);
}
}
}
void InitLCM6059B(void)
{
LCD_RST_CS_CFG;
LCD_RST_CS_OUT;
LCD_RST_SET(0);
DelayMs(10);
LCD_RST_SET(1);
DelayMs(10);
ContrastLevel=0x21; // 對(duì)比度參數(shù)初始化設(shè)置
SendCmd(DISPLAY_ON); // 開顯示
SendCmd(DISPLAY_START_LINE_SET|0); // 設(shè)置顯示起始行=0
SendCmd(ADC_DIR_SELECT); // RAM列地址與列驅(qū)動(dòng)同順序
SendCmd(DISPLAY_NORMAL); // 正向顯示
SendCmd(DISPLAY_ALL_POINT_ON); // 顯示全亮功能關(guān)閉
SendCmd(LCD_BIAS_SET|0); // LCD偏壓比為1/9
SendCmd(COM_OUTPUT_SET|0x08); // 行驅(qū)動(dòng)方向?yàn)榉聪?br />
SendCmd(POWER_CTRL_SET|0x0f); // 啟用內(nèi)部LCD驅(qū)動(dòng)電源
SendCmd(VO_CTRL_SET|0x05); // 電阻比
SendCmd(BOOST_RATIO_SET);
SendCmd(0x00); // 倍壓設(shè)置為4X
SendCmd(DISPLAY_CONTTAST_LEVEL);
SendCmd(0x21); // 設(shè)置對(duì)比度
ClearAllRAM();
return;
}
|