

    数据传输的四线接法和八线接法差别在于写数据的顺序,下面附上四线接法的程序。
/*--------------------------------------------------------------*/  
 //Name:    LCD1602四线驱动程序   
 //File:    LCD1602_4.H   
 //Date:    11-2-9   
 //TimE:    12:42   
 //Ver: 0.1   
 /*--------------------------------------------------------------*/  
 #include "reg51.h"   
 #include <intrins.h>   
   
 //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<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);  
 }