1602相关知识及四线驱动程序
扫描二维码
随时随地手机看文章
今天在调1602显示的时候又费了点小周折,由于平常我们一般是对液晶进行写操作,所以在有的开发板上这个引脚直接是接地的,今天自己用杜邦线连了个1602忽略了这个问题,后来接地就好了。
数据传输的四线接法和八线接法差别在于写数据的顺序,下面附上四线接法的程序。
[cpp] view plaincopy/*--------------------------------------------------------------*/
//Name: LCD1602四线驱动程序
//File: LCD1602_4.H
//Date: 11-2-9
//TimE: 12:42
//Ver: 0.1
/*--------------------------------------------------------------*/
#include "reg51.h"
#include
//LCD1602接口定义
#define LCD_DATA P1 //P1口(P14~P17)与LCD高四位(D4~D7)对应相接
sbit LCD1602_RS=P1^2; //数据指令
sbit LCD1602_EN=P1^3; //使能
//延时函数,12mhz 6t延迟时间10*255us
void LCD_init(void);
void LCD_en_write(void);
void LCD_write_command(unsigned char command) ;
void LCD_write_data(unsigned char Recdata);
void LCD_set_xy (unsigned char x, unsigned char y);
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s);
void LCD_write_char(unsigned char X,unsigned char Y,unsigned char Recdata);
void delay_nus(unsigned int n);
void delay_nms(unsigned int n);
//以下函数用于输出字符串和数字
int LCD_PutNum(unsigned long num,int XS,int pos);
int LCD_PutStr(unsigned char *DData,int pos);
//-------------------------1us延时函数---------------------------------
void delay_1us(void)
{
_nop_();
}
//------------------------N us延时函数---------------------------------
void delay_nus(unsigned int n)
{
unsigned int i=0;
for (i=0;i
delay_1us();
}
//-----------------------1ms延时函数----------------------------------
void delay_1ms(void)
{
unsigned int i;
for (i=0;i<1140;i++);
}
//-----------------------N ms延时函数---------------------------------
void delay_nms(unsigned int n)
{
unsigned int i=0;
for (i=0;i
delay_1ms();
}
//------------------------液晶初始化-----------------------------------
void LCD_init(void)
{
LCD_write_command(0x28);
delay_nus(40);
LCD_write_command(0x28);
delay_nus(40);
LCD_write_command(0x28);
delay_nus(40);
LCD_en_write();
delay_nus(40);
LCD_write_command(0x28); //4位显示
LCD_write_command(0x0c); //显示开
LCD_write_command(0x01); //清屏
delay_nms(2);
}
//----------------------液晶使能函数-------------------------------------
void LCD_en_write(void)
{ //EN由高电平跳变到低电平时液晶使能
LCD1602_EN=1;
delay_nus(1);
LCD1602_EN=0;
}
//------------------------写指令函数--------------------------------------
void LCD_write_command(unsigned char command)
{
delay_nus(16);
LCD1602_RS=0; //RS=0
LCD_DATA &=0X0f; //清高四位
LCD_DATA|=command&0xf0; //写高四位
LCD_en_write();
command=command<<4; //低四位移到高四位
LCD_DATA&=0x0f; //清高四位
LCD_DATA|=command&0xf0; //写低四位
LCD_en_write();
}
//------------------------写数据函数--------------------------------------
void LCD_write_data(unsigned char Recdata)
{
delay_nus(16);
LCD1602_RS=1; //RS=1
LCD_DATA&=0X0f; //清高四位
LCD_DATA|=Recdata&0xf0; //写高四位
LCD_en_write();
Recdata=Recdata<<4; //低四位移到高四位
LCD_DATA&=0X0f; //清高四位
LCD_DATA|=Recdata&0xf0; //写低四位
LCD_en_write();
}
//-----------------------地址定位函数-------------------------------------
void LCD_set_xy( unsigned char x, unsigned char y )
{
unsigned char address;
if (y == 0) address = 0x80 + x;
else address = 0xc0 + x;
LCD_write_command(address);
}
//----------------------在某个地址处,写一个字符----------------------------[!--empirenews.page--]
void LCD_write_char(unsigned char X,unsigned char Y,unsigned char Recdata) //列x=0~15,行y=0,1
{
LCD_set_xy(X, Y); //写地址
LCD_write_data(Recdata);
}
//----------------------------输出字符串-------------------------------------
int LCD_PutStr(unsigned char *DData,int pos) //pos表示字符显示位置,0~31
{
unsigned char i;
if(pos==-1)
{
LCD_write_command(0x01); //清屏
delay_nms(2);
pos=0;
}
while((*DData)!=' ')
{
switch(*DData)
{
case 'n': //如果是n,则换行
{
if(pos<17)
{
for(i=pos;i<16;i++) LCD_write_char(i%16, i/16,' ');
pos=16;
}
else
{
for(i=pos;i<32;i++) LCD_write_char(i%16, i/16,' ');
pos=0;
}
break;
}
case 'b': //如果是b,则退格
{
if(pos>0) pos--;
LCD_write_char(pos%16, pos/16, ' ');
break;
}
default:
{
if((*DData)<0x20) //小于0x20的显示不了?
{
*DData=' ';
}
LCD_write_char(pos%16, pos/16,*DData);
pos++;
break;
}
}
DData++;
}
return(pos);
}
//----------------------------输出数字---------------------------------
//这段程序写法我的理解大致是这样:num为去掉小数点之后的数字,XS为小数点
//从左数第几位,pos为显示的位置
//---------------------------------------------------------------------
int LCD_PutNum(unsigned long num,int XS,int pos)
{
unsigned long tmp=0;
unsigned char numbits=0; //总数字位数
if(pos==-1)
{
LCD_write_command(0x01);
delay_nms(2);
pos=0;
}
if(num==0)
{
LCD_write_char(pos%16, pos/16, '0');
pos++;
}
else
{
if(num<0)
{
LCD_write_char(pos%16, pos/16, '-');
num*=(-1);
pos++;
}
while(num) //例如数字1234,经过这个运算变成了4321
{
tmp=tmp*10+(num%10);
num=num/10;
numbits++;
}
while(tmp)
{
LCD_write_char(pos%16, pos/16, (tmp%10)+48);
tmp=tmp/10;
pos++;
numbits--;
if(numbits==XS) pos=LCD_PutStr(".",pos); //插入小数点
}
while(numbits--)
{
LCD_write_char(pos%16, pos/16, '0');
pos++;
}
}
return(pos);
}