项目中需要用到LCD,初步选择为ST7565控制器的COGLCM。在网上找到一圈,发现现成的程序都是基于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编辑器中对位的操作特别烦琐,所以本程序兴许能解决你的问题。
联系客服