1602相关知识及四线驱动程序

来源:互联网 发布:关键词排名优化公司 编辑:程序博客网 时间:2024/06/03 12:31

        今天在调1602显示的时候又费了点小周折,由于平常我们一般是对液晶进行写操作,所以在有的开发板上这个引脚直接是接地的,今天自己用杜邦线连了个1602忽略了这个问题,后来接地就好了。


        数据传输的四线接法和八线接法差别在于写数据的顺序,下面附上四线接法的程序。

/*--------------------------------------------------------------*/ //Name:LCD1602四线驱动程序 //File:LCD1602_4.H //Date:11-2-9 //TimE:12:42 //Ver:0.1 /*--------------------------------------------------------------*/ #include "reg51.h" #include <intrins.h>  //LCD1602接口定义           #defineLCD_DATAP1//P1口(P14~P17)与LCD高四位(D4~D7)对应相接 sbitLCD1602_RS=P1^2;//数据指令 sbitLCD1602_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<n;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<n;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); }   //----------------------在某个地址处,写一个字符---------------------------- 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)!='\0') {  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); }