1602 c语言驱动程序,51单片机驱动LCD1602程序设计(C语言)很详细的教程

1602 c语言驱动程序,51单片机驱动LCD1602程序设计(C语言)很详细的教程//********写指令函数************voidLCD_write_command(uchardat){LCD_DB=dat;LCD_RS=0;//指令LCD_RW=0;//写入LCD_E=1;//允许LCD_E=0;delay_n40us(1);//实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。}//****************************…

大家好,又见面了,我是你们的朋友全栈君。

//********写指令函数************

void LCD_write_command(uchar dat)

{

LCD_DB=dat;

LCD_RS=0;//指令

LCD_RW=0;//写入

LCD_E=1;//允许

LCD_E=0;

delay_n40us(1);//实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。

}

//*******************************

//********写数据函数*************

void LCD_write_data(uchar dat)

{

LCD_DB=dat;

LCD_RS=1;//数据

LCD_RW=0;//写入

LCD_E=1;//允许

LCD_E=0;

delay_n40us(1);

}

//********************************

//*******显示一个字符函数*********

void LCD_disp_char(uchar x,uchar y,uchar dat)

{

uchar address;

if(y==1)

address=0x80+x;

else

address=0xc0+x;

LCD_write_command(address);

LCD_write_data(dat);

}

//********************************

/*******检查忙函数*************

void LCD_check_busy()      //实践证明,在我的LCD1602上,检查忙指令通过率极低,以

{                                          //至于不能正常使用LCD。因此我没有再用检查忙函数。而使

do                                       //用了延时的方法,延时还是非常好用的。我试了一下,用

{ LCD_E=0;                   //for循环作延时,普通指令只要1次循就可完成。清屏指令

LCD_RS=0;                 //要用200次循环便能完成。

LCD_RW=1;

LCD_DB=0xff;

LCD_E=1;

}while(LCD_DB^7==1);

******************************/

//********延时函数***************

void delay_n40us(uint n)

{ uint i;

uchar j;

for(i=n;i>0;i–)

for(j=0;j<2;j++);          //在这个延时循环函数中我只做了2次循环,

}                                         //实践证明我的LCD1602上普通的指令只需1次循环就能可靠完成。

//*******************************

//*********主函数*****************

void main(void)

{

LCD_init();

LCD_disp_char(0,1,’A’);

while(1);

}

//*******************************

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

580e96b99b263a586b5f96c406d55e31.png

597392e7d6bd7cf86eb20353181b4e7c.png

组装后:

642a079dcee28db91b921436075e61ce.png

具体电路图:

efddd36222a7c319b5a089659d70749c.png

接口说明:

e97b47abb75156f55c80e0bcb05aa58c.png

我们从CGROM表上可以看到,在表的最左边是一列可以允许用户自定义的CGRAM,从上往下看着是16个,实际只有8个字节可用。它的字符码是00000000-00000111这8个地址,表的下面还有8个字节,但因为这个CGRAM的字符码规定0-2位为地址,3位无效,4-7全为零。因此CGRAM的字符码只有最后三位能用也就是8个字节了。等效为0000X111,X为无效位,最后三位为000-111共8个。

如果我们要想显示这8个用户自定义的字符,操作方法和显示CGROM的一样,先设置DDRAM位置,再向DDRAM写入字符码,例如“A”就是41H。现在我们要显示CGRAM的第一个自定义字符,就向DDRAM写入00000000B(00H),如果要显示第8个就写入00000111(08H),简单吧!

现在我们来看怎么向这八个自定义字符写入字模。有个设置CGRAM地址的指令大家还记得吗?赶快再找出来看看。

21c9207d011b53a26aaf026b4ffb9f03.png

从这个指令可以看出指令数据的高2位已固定是01,只有后面的6位是地址数据,而这6位中的高3位就表示这八个自定义字符,最后的3位就是字模数据的八个地址了。例如第一个自定义字符的字模地址为01000000-01000111八个地址。我们向这8个字节写入字模数据,让它能显示出“℃”

地址:01000000  数据:00010000       图示:○○○■○○○○

01000001     00000110               ○○○○○■■○

01000010     00001001               ○○○○■○○■

01000011     00001000               ○○○○■○○○

01000100     00001000               ○○○○■○○○

01000101     00001001               ○○○○■○○■

01000110     00000110               ○○○○○■■○

01000111     00000000               ○○○○○○○○

可以通过手动提取的方法。如下图所示,对应一个字符显示区域。每8个字节,组成一个点阵数组。

d18c2a90aea54eaffc45873760da7f20.png

“日”的点阵数组即为 {0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00}

6b6706144ffd25eed008b922b322018f.png

“车”字取模数组为:{0x00,0x0f,0x02,0x04,0x07,0x00,0x0f,0x00,

0x10,0x1e,0x00,0x10,0x1c,0x10,0x1e,0x10}

340cb5082a4351ff7c958e28d57176b5.png

将生成的点阵数组保存到CGRAM存储器中,生成自定义字符。1602内部CGRAM用于自定义的字符点阵的存储,总共64字节。由上一步点阵提取可知,每一个字符由8个字节数据组成。所以64字节CGRAM存储器,能够存储8组自定义字符的点阵数组。按照CGRAM地址划分为0-7为第一组,8-15为第二组,依次类推56-63为第8组数据。把自定义字符的数组按8个字节一组存储到CGRAM中,程序代码参考如下。

//功能:将自定义字符的编码数组 写入到CGRAM中.

//输入:自定义字符的编码数组

void Write_CGRAM(unsigned char *p)

{

unsigned char i,j,kk;

unsigned char tmp=0x40;  //操作CGRAM的命令码

kk=0;

for(j=0;j<8;j++)        //64 字节存储空间,可以生成 8 个自定义字符点阵

{

for(i=0;i<8;i++)    // 8 个字节生成 1 个字符点阵

{

Write_com(tmp+i);    //操作CGRAM的命令码+写入CGRAM地址.

Write_dat(p[kk]);    //写入数据

kk++;

}

tmp += 8;

}

}

上一步中,自定义字符存储到CGRAM的任意一组以后,每一个组(8个字节)也有一个显示编码。按顺序依次为00H-07H 。显示时,只要调用每一组的编码,即可以显示相应的字符。

注:内部常用字符显示时,显示编码是从0x20开始的。0x00-0x0f是专门留给自定义字符显示的。0x00-0x07和0x08-0x0f内容是一样的。例如:调用0x01 位置和0x09位置,显示的内容是一样的。

直接按照单个字符的显示方式调用显示函数,就可以显示自定义字符了。代码参考如下:

//在第1行,第7个位置显示自定义汉字 “年”

DisplayOneChar(6,0,0);    //显示 “年”  //CGRAM 码 00

说明:此时“年”的8个字节点阵数组 ,存储空间为CGRAM的 00-07地址

也就是CGRAM的第1组数据存储区域,编码为0。 如果存储在CGRAM的08-15地址,那么编码就应该是 1了。

很多资料中,都没有详细介绍过CGRAM和CGROM的区别和用法,在1602调试过程中经常会被搞混。这里总结一点小技巧,希望能给需要的人一点帮助。

以下是显示效果:

单个和两个点阵的汉字显示:

172416aa40119bd97053e07d7949bbb5.png

图形显示效果:

0460ff8eb24517df9864e9b518a77869.png

下面一段程序让这8个自定义字符显示出一个心的图案:

#include 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};//字符℃

#define     CLEARSCREEN     LCD_write_command(0x01)

/**************定义接口************************/

#define     LCDIO      P2

sbit LCD1602_RS=P3^0;

sbit LCD1602_RW=P3^1;

sbit LCD1602_EN=P3^2;

/**************定义函数************************/

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_char( unsigned x,unsigned char y,unsigned char dat)

{

LCD_set_xy( x, y );

LCD_write_dat(dat);

}

/**********************************************/

/***************显示字符串函数***************/

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;

c2c9ed493cd281aa86d8a6f5178c4c01.gif [1] [2] [3] 610626052e95c7fbe3d254abc769d9ad.gif

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/160142.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号