项目中需要用到LCD,初步选择为ST7565控制器的COG
LCM。在网上找到一圈,发现现成的程序都是基于I/O的操作方式的(这款LCM可以由客户来选择是并行驱动还是串行驱动,并行驱动还可以选择是80的时
序或者是68的时序的,可以说是功能强大,使用灵活)。I/O操作方式就是I/O操作方式吧,写了个程序,发现用不了,而且看起来费劲。从网上当了个英文
的PDF资料,一点点的全部看完,发现是可以用总线的操作方式的,不然为什么让选80还是68时序呀。折腾了一阵,终于把程序调出来了,公布出来和大家分
享:
#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); /*初始化系统*/ void delayms(unint temp);
void write_LcdData(unchar data1); /*向LCD写一个数据*/ 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; /*使用统一最长等待时间*/ 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写一个数据*/ { 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); /*非反转的正常显示*/ write_LcdComm(0xa6); /*非反白显示*/ write_LcdComm(0xa4); /*非全屏显示*/ write_LcdComm(0xa2); /*1/9 bias*/ write_LcdComm(0xc8); /*com0-com63-com1*/ write_LcdComm(0x2f); /*电源全开*/ write_LcdComm(0x24); /*对比度调节*/ write_LcdComm(0x81); /*进入亮度调节寄存器*/ 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数字 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数字和字母 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显示,生成的字模为纵向取模,字节倒序。由于AVR单片机的C编辑器中对位的操作特别烦琐,所以本程序兴许能解决你的问题。
|