|
項目中需要用到LCD,初步選擇為ST7565控制器的COG
LCM。在網(wǎng)上找到一圈,發(fā)現(xiàn)現(xiàn)成的程序都是基于I/O的操作方式的(這款LCM可以由客戶來選擇是并行驅(qū)動還是串行驅(qū)動,并行驅(qū)動還可以選擇是80的時
序或者是68的時序的,可以說是功能強大,使用靈活)。I/O操作方式就是I/O操作方式吧,寫了個程序,發(fā)現(xiàn)用不了,而且看起來費勁。從網(wǎng)上當了個英文
的PDF資料,一點點的全部看完,發(fā)現(xiàn)是可以用總線的操作方式的,不然為什么讓選80還是68時序呀。折騰了一陣,終于把程序調(diào)出來了,公布出來和大家分
享:
#include<mega128.h> #include<microdefine.h>
#define unchar unsigned char #define unint unsigned int
#define Lcd_Command (*(volatile unsigned char *)0xddff) #define Lcd_Data (*(volatile unsigned char *)0xdfff)
void init_System(void); /*初始化系統(tǒng)*/ void delayms(unint temp);
void write_LcdData(unchar data1); /*向LCD寫一個數(shù)據(jù)*/ void write_LcdComm(unchar comm); /*向LCD寫一個命令*/ void busycheck(void); void initLCD(void); void clearLCD(void); void display_168(unchar Page,unchar Column,unchar temp); void PutChar(unchar Page,unchar Column,const unchar *temp); void PutPicture(unchar Page,unchar Column,const unchar *temp);
void main(void) /*主程序*/ { unchar seg; unchar page; init_System(); initLCD();
PutPicture(0xb0,24,array10); PutChar(0xb2,0,array1); display_168(0xb3,8,1); display_168(0xb3,16,0); display_168(0xb3,24,0); display_168(0xb3,32,0); display_168(0xb3,48,1); display_168(0xb3,56,0); display_168(0xb3,64,0); PutChar(0xb4,72,array6); display_168(0xb3,78,0); display_168(0xb3,90,2); display_168(0xb3,98,0); display_168(0xb3,106,0); PutChar(0xb4,114,array6); display_168(0xb3,120,0); PutChar(0xb5,0,array4); PutChar(0xb5,22,array2); PutChar(0xb5,44,array7); PutChar(0xb5,64,array2); PutChar(0xb5,90,array8); PutChar(0xb5,106,array3); write_LcdComm(0xb0); write_LcdComm(0x16); write_LcdComm(0x0e); for(seg=0;seg<16;seg++) { write_LcdData(array9[seg]); } while(1); }
void init_System(void) { MCUCR |= 0xc0; /*使能外部SRAM*/ XMCRA = 0x02; /*使用統(tǒng)一最長等待時間*/ XMCRB = 0x00; // DDRD = 0x0c; }
/******************************************************************************* 軟件延時,temp即為temp個ms *******************************************************************************/ void delayms(unint temp) { unchar j; for(j=0;j<temp;j++); }
void busycheck(void) { unchar Status; do { Status = Lcd_Command; Status = Status & 0x80; }while(Status == 0x80); }
void write_LcdData(unchar data1) /*向LCD寫一個數(shù)據(jù)*/ { busycheck(); Lcd_Data = data1; }
void write_LcdComm(unchar comm) /*向LCD寫一個命令*/ { busycheck(); Lcd_Command=comm; }
void initLCD(void) { write_LcdComm(0xaf); /*顯示開*/ write_LcdComm(0x40); /*開始行地址*/ write_LcdComm(0xa0); /*非反轉(zhuǎn)的正常顯示*/ write_LcdComm(0xa6); /*非反白顯示*/ write_LcdComm(0xa4); /*非全屏顯示*/ write_LcdComm(0xa2); /*1/9 bias*/ write_LcdComm(0xc8); /*com0-com63-com1*/ write_LcdComm(0x2f); /*電源全開*/ write_LcdComm(0x24); /*對比度調(diào)節(jié)*/ write_LcdComm(0x81); /*進入亮度調(diào)節(jié)寄存器*/ write_LcdComm(0x24); /*亮度值*/ clearLCD(); }
void clearLCD(void) { unchar page; unchar seg; for(page=0xb0;page<0xb9;page++) { write_LcdComm(page); write_LcdComm(0x10); /*列地址高位,D4位為1表示高位地址*/ write_LcdComm(0x00); /*列地址低位,D4位為0表示低位地址*/ for(seg=0;seg<128;seg++) { write_LcdData(0x00); } } }
/******************************************************************************* 顯示8*16數(shù)字 Page必須在0xb0~0xb7之間 *******************************************************************************/ void display_168(unchar Page,unchar Column,unchar temp) { unchar ColLow; unchar ColHigh; unchar i; unchar asc; i = Column; ColHigh = i & 0xf0; ColHigh = ColHigh/16; ColHigh = ColHigh | 0x10; ColLow = i & 0x0f; write_LcdComm(Page); write_LcdComm(ColHigh); write_LcdComm(ColLow); asc = temp*16; for(i=0;i<8;i++) { write_LcdData(zk_ShuZi[asc]); asc++; } write_LcdComm(Page+1); write_LcdComm(ColHigh); write_LcdComm(ColLow); for(i=0;i<8;i++) { write_LcdData(zk_ShuZi[asc]); asc++; } } /******************************************************************************* 顯示6*8數(shù)字和字母 Page必須在0xb0~0xb7之間 *******************************************************************************/ void PutChar(unchar Page,unchar Column,const unchar *temp) { unchar i; unchar j; unint asc; unchar len;
write_LcdComm(Page); i = Column; j = i & 0xf0; j = j/16; write_LcdComm(0x10|j); /*列地址高位,D4位為1表示高位地址*/ write_LcdComm(0x0f&i); do { asc = (*temp-32)*6; for(i=0;i<6;i++) { write_LcdData(zk_Asc[asc]); asc++; } temp++; }while((*temp) != '?'); }
void PutPicture(unchar Page,unchar Column,const unchar *temp) { unchar ColLow; unchar ColHigh; unchar i; unchar asc; i = Column; ColHigh = i & 0xf0; ColHigh = ColHigh/16; ColHigh = ColHigh | 0x10; ColLow = i & 0x0f; write_LcdComm(Page); write_LcdComm(ColHigh); write_LcdComm(ColLow); for(i=0;i<67;i++) { write_LcdData(*temp); temp++; } write_LcdComm(Page+1); write_LcdComm(ColHigh); write_LcdComm(ColLow); for(i=0;i<67;i++) { write_LcdData(*temp); temp++; } }
使用的時候必須注意不能跨PAGE顯示,生成的字模為縱向取模,字節(jié)倒序。由于AVR單片機的C編輯器中對位的操作特別煩瑣,所以本程序興許能解決你的問題。
|