外省生孩子能报销吗:基于ST7565控制器的LCM驱动方法

来源:百度文库 编辑:中财网 时间:2024/04/29 21:13:50

项目中需要用到LCD,初步选择为ST7565控制器的COGLCM。在网上找到一圈,发现现成的程序都是基于I/O的操作方式的(这款LCM可以由客户来选择是并行驱动还是串行驱动,并行驱动还可以选择是80的时序或者是68的时序的,可以说是功能强大,使用灵活)。I/O操作方式就是I/O操作方式吧,写了个程序,发现用不了,而且看起来费劲。从网上当了个英文的PDF资料,一点点的全部看完,发现是可以用总线的操作方式的,不然为什么让选80还是68时序呀。折腾了一阵,终于把程序调出来了,公布出来和大家分享:

#include
#include

#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}

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编辑器中对位的操作特别烦琐,所以本程序兴许能解决你的问题。