整理下前陣子的心得,ST7529和ST7586S的驅動體會。驅動IC的PDF文檔網上都能搜索到。
單片機都是AVR 的MEGA64A
點上土匪頭像,98*98像素。吟濕一首,好濕啊好濕
//PIN7-PIN14 ---> DB0-DB7--->PF0-PF7
//PIN16 LED-K ---> PA7
//PIN15 /RST ---> PD4
//PIN6 /RD ---> PA3
//PIN5 /WD ---> PA4
//PIN4 RS ---> PA5
//PIN3 /CS ---> PA6
#define DATA_IO_INIT() {DDRF=0xFF;PORTF=0x00;}
#define LCD_RST_ON() {DDRD|=BIT(4);PORTD&=~BIT(4);}
#define LCD_RST_OFF() {DDRD|=BIT(4);PORTD|=BIT(4);}
#define LCD_RS_LOW_COMMAND() {DDRA|=BIT(5);PORTA&=~BIT(5);}
#define LCD_RS_HIGH_DATA() {DDRA|=BIT(5);PORTA|=BIT(5);}
#define LCD_RD_LOW() {DDRA|=BIT(3);PORTA&=~BIT(3);}
#define LCD_RD_HIGH() {DDRA|=BIT(3);PORTA|=BIT(3);}
#define LCD_WR_LOW() {DDRA|=BIT(4);PORTA&=~BIT(4);}
#define LCD_WR_HIGH() {DDRA|=BIT(4);PORTA|=BIT(4);}
#define LCD_CS_LOW_ON() {DDRA|=BIT(6);PORTA&=~BIT(6);}
#define LCD_CS_HIGH_OFF() {DDRA|=BIT(6);PORTA|=BIT(6);}
#define LCD_LED_ON() {DDRA|=BIT(7);PORTA|=BIT(7);}
#define LCD_LED_OFF() {DDRA|=BIT(7);PORTA&=~BIT(7);}
/**************************************************************
EXPLAIN: DEFINE FOR ST7529 DRIVER
***************************************************************/
#define EXT_IN 0x30 //(P=0 )Ext=0 Set
#define EXT_OUT 0x31 //(P=0 )Ext=1 Set
#define DISON 0xaf //(P=0 )Display On
#define DISOFF 0xae //(P=0 )Display Off
#define DISNOR 0xa6 //(P=0 )Normal Display
#define DISINV 0xa7 //(P=0 )Inverse Display
#define COMSCN 0xbb //(P=1 )COM Scan Direction
#define DISCTRL 0xca //(P=3 )Display Control
#define SLPIN 0x95 //(P=0 )Sleep In
#define SLPOUT 0x94 //(P=0 )Sleep Out
#define LASET 0x75 //(P=2 )Line Address Set
#define CASET 0x15 //(P=2 )Column Address Set
#define DATSDR 0xbc //(P=3 )Data Scan Direction
#define RAMWR 0x5c //(P=N )Writing to Memory
#define RAMRD 0x5d //(P=N )Reading from Memory
#define PTLIN 0xa8 //(P=2 )Partial display in
#define PTLOUT 0xa9 //(P=0 )Partial display out
#define RMWIN 0xe0 //(P=0 )Read and Modify Write
#define RMWOUT 0xee //(P=0 )RMW end
#define ASCSET 0xaa //(P=4 )Area Scroll Set
#define SCSTART 0xab //(P=1 )Scroll Start Set
#define OSCON 0xd1 //(P=0 )Internal OSC on
#define OSCOFF 0xd2 //(P=0 )Internal OSC off
#define PWRCTRL 0x20 //(P=1 )Power Control
#define VOLCTRL 0x81 //(P=2 )EC control
#define VOLUP 0xd6 //(P=0 )EC increase 1
#define VOLDOWN 0xd7 //(P=0 )EC decrease 1
#define RESERVED 0x82 //(P=0 )Not Use
#define EPSRRD1 0x7c //(P=0 )READ Register1
#define EPSRRD2 0x7d //(P=0 )READ Register2
//#define NOP 0x25 //(P=0 )NOP Instruction
//#define STREAD //(P=0 )Status Read
#define EPINT 0x07 //(P=1 )Initial code(1)
//Ext =1
#define GRAY1SET 0x20 //(P=16)FRAME 1 Gray PWM Set
#define GRAY2SET 0x21 //(P=16)FRAME 2 Gray PWM Set
#define ANASET 0x32 //(P=3 )Analog Circuit Set
#define SWINT 0x34 //(P=0 )Software Initial
#define EPCTIN 0xcd //(P=1 )Control EEPROM
#define EPCOUT 0xcc //(P=0 )Cancel EEPROM
#define EPMWR 0xfc //(P=0 )Write to EEPROM
#define EPMRD 0xfd //(P=0 )Read from EEPROM
//*****************************************
//*****************************
#define LCM_SEG_MAX 255
#define LCM_COM_MAX 160
#define LCM_PAG_MAX 9
#define LCM_SEG_USE 240
#define LCM_COM_USE 160
#define LCM_PAG_USE 8
#define LCM_RATIO 1
#define LCM_VOP 2
#define LCM_STR_COM 0
#define LCM_STR_SEG 4
#define LCM_STR_PAG 0
#define LCM_COM_DIR 1 //0表示反向掃描,1表示正向掃描
#define LCM_SEG_DIR 1 //0表示反向掃描,1表示正向掃描
/*****************************要顯示的數據取模方式****************************/
/*從第一行開始向右,取8個點作為一個字節,然后從第二行開始向右
取8個點作為第二個字節...依此類推。如果最后不足8個點就補滿8位。
取模順序是從高到低,即第一個點作為最高位。如*-------取為10000000*/
//行列式,順位,高位在前
//就舉一個,用取模軟件自己比對吧
//就舉一個,用取模軟件自己比對吧
const uchar Image24_ceng[]=
{0x00,0x00,0x01,0x00,0x00,0x08,0x0F,0x0A,0x09,0x08,0x08,0x08,0x0F,0x00,0x02,0x03,0x02,0x02,0x03,0x02,0x02,0x03,0x02,0x00,
0x00,0x00,0x01,0xC1,0xC2,0x04,0xFB,0x18,0x99,0x99,0x9A,0x1C,0xE3,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,
0x00,0x00,0x80,0x00,0x00,0x18,0xF0,0x90,0x90,0x10,0x10,0x10,0xF0,0x00,0xC0,0x40,0x40,0x40,0xC0,0x40,0x40,0xC0,0x40,0x00};/*"曾",0*/ /*******************************LCD寫命令**********************************/
void LCD_Cmd_Write(unsigned char cmd)
{
LCD_RS_LOW_COMMAND();
LCD_RD_HIGH();
/*LCD_ChkBusy();*/ //Call LCD_ChkBusy to Check Busy Bit
LCD_WR_LOW();
NOP();
NOP();
DDRF = 0xFF;
PORTF = cmd;
LCD_CS_LOW_ON();
NOP();
NOP();
LCD_WR_HIGH();
Some_NOP(3);
LCD_CS_HIGH_OFF();
}
/*****************************LCD寫數據**********************************/
void LCD_Data_Write(unsigned char data)
{
/*LCD_ChkBusy(); */ //Call LCD_ChkBusy to Check Busy Bit
DDRF = 0xFF;
LCD_RS_HIGH_DATA();
LCD_RD_HIGH();
PORTF = data;
LCD_WR_LOW();
NOP();
NOP();
LCD_CS_LOW_ON();
NOP()
NOP();
LCD_WR_HIGH();
Some_NOP(3);
LCD_CS_HIGH_OFF();
} /***********************LCD讀數據*******************************/
unsigned char LCD_Data_Read(void)
{
unsigned char data_m=0;
DDRF = 0x00; //讀出
LCD_RS_HIGH_DATA();
LCD_RD_HIGH();
LCD_WR_LOW();
NOP();
NOP();
LCD_CS_LOW_ON();
NOP();
NOP();
LCD_WR_HIGH();
NOP();
NOP();
LCD_RD_LOW();
NOP();
NOP();
data_m = PINF;
LCD_RD_HIGH();
NOP();
NOP();
return data_m;
}
/**********************************設置XY坐標*********************************/
/******************X<159,Y<84*****************************/
void Set_Address(uchar ucXpos1,uchar ucXpos2,uchar ucYpos1,uchar ucYpos2)
{
LCD_Cmd_Write(EXT_IN); //EXT=0
LCD_Cmd_Write(LASET); //THIRD COMMAND SET LINE ADDRESS
LCD_Data_Write(ucYpos1); //START LINE
LCD_Data_Write(ucYpos2); //END LINE
LCD_Cmd_Write(CASET); //THIRD COMMAND SET COLUMN ADDRESS
LCD_Data_Write(ucXpos1); //START COLUMN
LCD_Data_Write(ucXpos2); //END COLUMN
}/**************************LCD的點測試程序***********************************/
/*******************y_line[0,159],x_column[0,83]**************************/
void LCD_Clear_RAM(uchar start_x,uchar end_x,uchar start_y,uchar end_y)
{
unsigned int i,j;
Set_Address(start_x,end_x,start_y,end_y);
LCD_Cmd_Write(RAMWR); //DATA WRITE
j = (end_x-start_x+1)*(end_y-start_y+1);
for(i=0;i<=j;i++)
{
LCD_Data_Write(0);
LCD_Data_Write(0);
LCD_Data_Write(0);
}
} /****在坐標XY處開始寫入1個點的數據,并且保持處于這列中的其它兩個值不變*********/
void Write_XY(uchar ucXpos,uchar ucYpos,uchar ucData)
{
unsigned char i=0,l=0,j=0;
unsigned char ucMem=0;
unsigned char ucData1,ucData2,ucData3,ucCol=0,ucSet=0;
unsigned int uiCount=0;
ucCol = ucYpos/3;//得到Y軸上的列,一些寫一個列,一個列里包含3個數據
ucSet = ucYpos%3;//得到塊上3個點中的一個
Set_Address(ucCol,80,ucXpos,159); //因為選擇了行不變,而列由3個豎條小列組成,所以一次要寫3個點
LCD_Cmd_Write(RAMRD); //從RAM內讀坐標的值
LCD_Data_Read(); //空讀一個頭數據
ucData1 = LCD_Data_Read(); //讀取原來的3個點的值
ucData2 = LCD_Data_Read();
ucData3 = LCD_Data_Read();
Set_Address(ucXpos,159,ucCol,83); //在指定坐標的RAM內寫入顯示值
LCD_Cmd_Write(RAMWR);
switch(ucSet)
{
case 0:
ucData1 = ucData;
//ucData2=0x00;
//ucData3=0x00;
break;
case 1:
//ucData1=0x00;
ucData2 = ucData;
//ucData3=0x00;
break;
case 2:
//ucData1=0x00;
//ucData2=0x00;
ucData3 = ucData;
break;
}
LCD_Data_Write(ucData1); //寫入新點的值,并且保持原來兩個點的值不變
LCD_Data_Write(ucData2);
LCD_Data_Write(ucData3);
}
/*******************24*24圖片顯示***************************/
void Image24_Disp(uchar x,uchar y,const uchar *img)
{
uint p;
uchar i,j,k,data;
LCD_Cmd_Write(0x30);
LCD_Cmd_Write(CASET);
LCD_Data_Write(x);
LCD_Data_Write(x+7);
LCD_Cmd_Write(LASET);
LCD_Data_Write(y);
LCD_Data_Write(y+24);
LCD_Cmd_Write(RAMWR);
for(i=0;i<24;i++)
{
k = img[i];
for(j=0;j<8;j++)//第一個8列字節數據
{
if(k&0x80)
{
data = 0xFF;
}
else
{
data = 0;
}
LCD_Data_Write(data);
k = k<<1;
}
k = img[i+24];//第2個8列字節數據
for(j=0;j<8;j++)
{
if(k&0x80)
{
data = 0xFF;
}
else
{
data = 0;
}
LCD_Data_Write(data);
k = k<<1;
}
k = img[i+48];//第3個8列字節數據
for(j=0;j<8;j++)
{
if(k&0x80)
{
data = 0xFF;
}
else
{
data = 0;
}
LCD_Data_Write(data);
k = k<<1;
}
}
}
/*******************16*16圖片顯示***************************/
void Image_Disp(uchar x,uchar y,const uchar *img,uchar column,uchar line)
{
uint p;
uchar i,j,k,data;
LCD_Cmd_Write(0x30);
LCD_Cmd_Write(CASET);
LCD_Data_Write(x);
LCD_Data_Write(x+5);
LCD_Cmd_Write(LASET);
LCD_Data_Write(y);
LCD_Data_Write(y+16);
LCD_Cmd_Write(RAMWR);
for(i=0;i<16;i++)
{
k = img[i];
for(j=0;j<8;j++)//第一個8列字節數據
{
if(k&0x80)
{
data = 0xFF;
}
else
{
data = 0;
}
LCD_Data_Write(data);
k = k<<1;
}
k = img[i+16];//第2個8列字節數據
for(j=0;j<8;j++)
{
if(k&0x80)
{
data = 0xFF;
}
else
{
data = 0;
}
LCD_Data_Write(data);
k = k<<1;
}
LCD_Data_Write(0);//余下的兩列
LCD_Data_Write(0);
}
}
void Read_LCD_EEPROM(void)
{
LCD_Cmd_Write(EXT_IN); // Ext = 0
LCD_Cmd_Write(EPINT); // Initial code (1)
LCD_Data_Write(0x19);
LCD_Cmd_Write(EXT_OUT); // Ext = 1
LCD_Cmd_Write(EPCTIN); // EEPROM ON
LCD_Data_Write(0x00); // Entry "Read Mode"
Delay_ms(95); // Waite for EEPROM Operation ( 100ms )
LCD_Cmd_Write(EPMRD); // Start EEPROM Reading Operation
Delay_ms(95); // Waite for EEPROM Operation ( 100ms )
LCD_Cmd_Write(EPCOUT); // Exist EEPORM Mode
LCD_Cmd_Write(EXT_IN); // Ext = 0
}
//********************************
//Funtion:
//Parameter:
//********************************
void Write_LCD_EEPROM(void)
{
LCD_Cmd_Write(EXT_IN); // Ext = 0
LCD_Cmd_Write(DISOFF); // Display OFF
LCD_Cmd_Write(EPINT); // Initial code(1)
LCD_Data_Write(0x19);
LCD_Cmd_Write(EXT_OUT); // Ext = 1
LCD_Cmd_Write(EPCTIN); // EEPROM ON
LCD_Data_Write(0x20); // Entry "Write Mode"
Delay_ms(95); // Waite for EEPROM Operation ( 100ms )
LCD_Cmd_Write(EPMWR); // Start EEPROM Writing Operation
Delay_ms(95); // Waite for EEPROM Operation ( 100ms )
LCD_Cmd_Write(EPCOUT); // Exist EEPROM Mode
LCD_Cmd_Write(EXT_IN); // Ext = 0
LCD_Cmd_Write(DISON); // Display ON
}
/**********************LCD復位程序********************/
void LCD_Reset(void )
{
LCD_RST_OFF();
Delay_ms(1);
LCD_RST_ON();
Delay_us(10);
LCD_RST_OFF();
Delay_ms(1);
}
/*************************LCD初始化***********************/
void LCD_Init(void)
{
LCD_Reset();
LCD_Cmd_Write(EXT_IN); // EXT=0,0X30
LCD_Cmd_Write(SLPOUT); // SLPOUT=0x94,SLEEP OUT
LCD_Cmd_Write(OSCON); // OSCON=0xD1,INTERNAL OSCILLATION ON
Delay_ms(1);
LCD_Cmd_Write(PWRCTRL); // PWRCTRL=0x20,POWER CONTROL SET
LCD_Data_Write(0x08); // TURN ON BOOSTER AND REFERENCE VOLTAGE GENERATION CIRCUIT ;0bh
Delay_ms(2);
LCD_Cmd_Write(PWRCTRL); // PWRCTRL=0x20,POWER CONTROL SET
LCD_Data_Write(0x0B); // TURN ON BOOSTER AND REFERENCE VOLTAGE GENERATION CIRCUIT ;0bh
LCD_Cmd_Write(DISCTRL); // DISCTRL=0xCA,DISPLAY CONTROL
LCD_Data_Write(0X04); // CL DIVIDING RATIO ,F1 AND F2 DRIVE PATTERN
LCD_Data_Write(0X27); // DIVER DUTY,160
LCD_Data_Write(0X00); // FR INVERSE-SET VALUE
LCD_Cmd_Write(COMSCN); // COMSCN=0xBB,C0M0-->COM79,C0M159-->COM80
LCD_Data_Write(0X01);
LCD_Cmd_Write(VOLCTRL); // VOLCTRL=0x81,Electronic Control,THREE COMMAND SET REFERENCE VOLTAGE SELECT MODE
LCD_Data_Write(0X0E); // REFERENCE VOLTAGE PARAMETER ;14.4V
LCD_Data_Write(0X04); // SET REFERENCE VOLTAGE PARAMETER ;04 3.6+(100001110)*0.04
Delay_us(20);
LCD_Cmd_Write(DISINV); // DISINV=0xA7,INVERSE DISPLAY
LCD_Cmd_Write(EXT_OUT); // EXT=1
LCD_Cmd_Write(ANASET); // ANASET=0x32,ANALOG CIRCUIT SET
LCD_Data_Write(0X03); // OSC FREQUENCEY ADJUSTMENT DEFAULT=12.7K 03=21.9K
LCD_Data_Write(0X02); // BOOSTER EFFICIENCY SET 6K DEFAULT
LCD_Data_Write(0X02); // BIAS SETTING DEFAULT 1/12;1/13,1/14時太淡
Delay_ms(1);
//====================================================
LCD_Cmd_Write(GRAY1SET); // SET GRAY VALUE 0X1F時背景全部為深色
LCD_Data_Write(0X00); // START PARA 00
LCD_Data_Write(0X00); // START PARA 03
LCD_Data_Write(0X00); // START PARA 06
LCD_Data_Write(0X00); // START PARA 09
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
//******************************************
LCD_Cmd_Write(GRAY2SET); // SET GRAY VALUE
LCD_Data_Write(0X00); // START PARA 00
LCD_Data_Write(0X00); // START PARA 03
LCD_Data_Write(0X00); // START PARA 06
LCD_Data_Write(0X00); // START PARA 09
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Data_Write(0X00); // START PARA
LCD_Cmd_Write(SWINT); //Software Initial
Delay_ms(1);
//******************************************
Read_LCD_EEPROM(); //Read EEPROM Flow
LCD_Cmd_Write(EXT_IN); // EXT=0
LCD_Cmd_Write(DISON); //Display On
LCD_Cmd_Write(DATSDR); // FORTH COMMAND SET DATA SCAN DRECTION
LCD_Data_Write(0X01); // NORMAL/REVERSE DISPLAY OF ADDRESS AND ADDRESS SCAN DRICTION
LCD_Data_Write(0X00); // RGB ARRANGEMENT
LCD_Data_Write(0X02); // 32 GRAY-SCALE 65K,3B3P MODE
LCD_Cmd_Write(LASET); // THIRD COMMAND SET LINE ADDRESS
LCD_Data_Write(0X00); // START LINE
LCD_Data_Write(0X9f); // END LINE
Delay_ms(1);
LCD_Cmd_Write(CASET); // THIRD COMMAND SET COLUMN ADDRESS
LCD_Data_Write(0X00); // START COLUMN
LCD_Data_Write(0X4F); // END COLUMN
Delay_ms(1);
}