5.自制单片机之五(2)……LCD1602的驱动_边学边秀单片机_百度空间

具体电路的制作是很简单的,就接了两个电阻,一个是10欧姆的背光限流电阻,另一个是2K的LCD极板电压调节电阻。这两个电阻的阻值怎么定呢?背光比较简单,它就相当于在后面接了几个发光二极管,任何时候你只要在15、16脚串上个100欧的电位器接上电源,调节电位器,觉得亮度合适。此时的阻值便可。LCD液晶极板驱动电压调节电阻的确定就稍微麻烦一点。在各数据线,控制线接好关通上电源的前提下在第3脚(VEE)和地之间接一个10K的电位器。调节电位器。当3脚电压高时为全亮,电压为0时为全暗(液晶全显示为黑块)。你用电位器把屏幕从全暗刚好调到变亮。这时便可调试程序。待屏幕能正确显示后再细调电位器,使对比度合适。这时的阻值便可确定,然后换成等值的固定电阻焊上便可。

我们接着上次的系统板制做:

我们从CGROM表上可以看到,在表的最左边是一列可以允许用户自定义的CGRAM,从上往下看着是16个,实际只有8个字节可用。它的字符码是00000000-00000111这8个地址,表的下面还有8个字节,但因为这个CGRAM的字符码规定0-2位为地址,3位无效,4-7全为零。因此CGRAM的字符码只有{zh1}三位能用也就是8个字节了。等效为0000X111,X为无效位,{zh1}三位为000-111共8个。
如果我们要想显示这8个用户自定义的字符,操作方法和显示CGROM的一样,先设置DDRAM位置,再向DDRAM写入字符码,例如“A”就是41H。现在我们要显示CGRAM的{dy}个自定义字符,就向DDRAM写入00000000B(00H),如果要显示第8个就写入00000111(08H),简单吧!
好!现在我们来看怎么向这八个自定义字符写入字模。有个设置CGRAM地址的指令大家还记得吗?赶快再找出来看看。

从这个指令可以看出指令数据的高2位已固定是01,只有后面的6位是地址数据,而这6位中的高3位就表示这八个自定义字符,{zh1}的3位就是字模数据的八个地址了。例如{dy}个自定义字符的字模地址为01000000-01000111八个地址。我们向这8个字节写入字模数据,让它能显示出“℃”
地址:01000000  数据:00010000       图示:○○○■○○○○
   01000001     00000110               ○○○○○■■○
   01000010     00001001               ○○○○■○○■
   01000011     00001000               ○○○○■○○○
   01000100     00001000               ○○○○■○○○
   01000101     00001001               ○○○○■○○■
   01000110     00000110               ○○○○○■■○
   01000111     00000000               ○○○○○○○○
下面我们写一段程序让这8个自定义字符显示出一个心的图案:
# include <reg51.h>
unsigned char table1[]={0x03,0x07,0x0f,0x1f,0x1f,0x1f,0x1f,0x1f,
                           0x18,0x1E,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
                           0x07,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
                           0x10,0x18,0x1c,0x1E,0x1E,0x1E,0x1E,0x1E,
                           0x0f,0x07,0x03,0x01,0x00,0x00,0x00,0x00,
                           0x1f,0x1f,0x1f,0x1f,0x1f,0x0f,0x07,0x01,
                           0x1f,0x1f,0x1f,0x1f,0x1f,0x1c,0x18,0x00,
                           0x1c,0x18,0x10,0x00,0x00,0x00,0x00,0x00};//心图案
unsigned char table[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};//字符℃
/**************定义函数************************/
void LCD_write_command(unsigned char command);//写入指令函数
void LCD_write_dat(unsigned char dat);//写入数据函数
void LCD_set_xy( unsigned char x, unsigned char y );//设置显示位置函数
void LCD_dsp_char( unsigned x,unsigned char y,unsigned char dat);//显示一个字符函数
void LCD_dsp_string(unsigned char X,unsigned char Y,unsigned char *s);//显示字符串函数
void LCD_init(void);//初始化函数
void delay_nms(unsigned int n);//延时函数
/********************************************/
/************初始化函数****************/
void LCD_init(void)
{
CLEARSCREEN;//clear screen
LCD_write_command(0x38);//set 8 bit data transmission mode
LCD_write_command(0x0c);//open display (enable lcd display)
LCD_write_command(0x80);//set lcd first display address
CLEARSCREEN;//clear screen
}
/****************************************************/
/**************写指令函数********************************/  
void LCD_write_command(unsigned char command)
{
      LCDIO=command;
      LCD1602_RS=0;   
      LCD1602_RW=0;
      LCD1602_EN=0;
      LCD1602_EN=1;
      delay_nms(10);
}
/***************************************************/
/****************写数据函数************************/
void LCD_write_dat(unsigned char dat)
{
LCDIO=dat;
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_EN=0;
delay_nms(1);
LCD1602_EN=1;
}
/****************************************************/
/***************设置显示位置**************************/
void LCD_set_xy( unsigned char x, unsigned char y )
{
unsigned char address;
if (y == 1)
     address = 0x80 + x;
else
        address =0xc0+ x;
LCD_write_command(address);
}
/***************************************************/
/***************显示字符串函数***************/
void LCD_dsp_string(unsigned char X,unsigned char Y,unsigned char *s)
{
       LCD_set_xy( X, Y );
       while (*s)  
       {
         LCD_write_dat(*s);   
         s ++;
       }
}
/***********************************************/
/********** 延时**********************/
void delay_nms(unsigned int n)      
{
       unsigned int i=0,j=0;
       for (i=n;i>0;i--)
       for (j=0;j<10;j++);  
}
/**************************************/
/***********主函数**************/
void main(void)
{
unsigned char i,j,k,tmp;
LCD_init();
delay_nms(100);
tmp=0x40;//设置CGRAM地址的格式字
k=0;
for(j=0;j<8;j++)
     {
        for(i=0;i<8;i++)
         {
           LCD_write_command(tmp+i); // 设置自定义字符的 CGRAM 地址  
           delay_nms(2);
           LCD_write_dat(table1[k]); // 向CGRAM写入自定义字符表的数据
           k++;
           delay_nms(2);
         }
        tmp=tmp+8;
      }
     LCD_dsp_string(1,1,"LCD TEST        ");//在{dy}行{dy}列显示“LCD TEST”
     LCD_dsp_string(1,2,"SUCCESSFUL      ");//在第二行{dy}列显示“SUCCESSFUL”
     for (i=0;i<4;i++)
       {
         LCD_dsp_char( 12+i,1,i);//在{dy}行第12列位置显示心图案的上半部
         delay_nms(1);
       }
     for (i=4;i<8;i++)
       {
         LCD_dsp_char( 12+i-4,2,i);在第二行第12列位置显示心图案的下半部
         delay_nms(1);
       }
     while (1);
}
/********************************************************************/

18 2009-04-09 13:20 |
/**************写指令函数********************************/  
void LCD_write_command(unsigned char command)
{
      LCDIO=command;
      LCD1602_RS=0;   
      LCD1602_RW=0;
      LCD1602_EN=0;
      LCD1602_EN=1;
      delay_nms(10);
}
這里的delay_nms(10){zh0}改為20,不然將會出現第二行的情況。

郑重声明:资讯 【5.自制单片机之五(2)……LCD1602的驱动_边学边秀单片机_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——