lvzhenqiang 发表于 2025-12-2 12:35:23

8051单片机,用6线驱动1602共用6个IO口,并行驱动显示


51通常的例程,大部分是用并行8线来驱动的,我们尝试用4线,分两次发送。写命令和数据。这样的话数据口就只用4条线。





R/W线,因为我们主要用的是写数据,或者是写命令,很少用到读,只有需要读忙状态才用到,我们可以用1毫秒的延时来替代,这样的话直接R/W接地。



上接线图,R22是用来限流,可以直接接VCC也就是直接连到2脚上,16脚直接连到1脚上。
3脚VL,接1K电阻到1脚,这样能正常显示,只是不能调节对比度,管它呢,只要能显示就行。
这样一来 ,需要8条线,两条电源线,6条数据线。

硬件连线上图




没有找到碳膜电阻用个0603焊上了。{:ciya:}{:ciya:}

硬件接完了,接下来就是函数了。
我们不做太多显示,只显示一个字符,证明能显示就是。

分下面几部
1,定义管脚
2,写一个字节数据函数
3,写一个字节命令函数
4,屏幕初始化
5,写一个需要显示位置的函数
这样就可以显示字符了

写函数之前强调一下,通常的1602规格书没有介绍,4线和8线如何配置,其实初始化写命令时把,0X38改成0X28就改好了。


写一个字节数据

//写一个字节数据
void LCD1602_Write_Data(unsigned char dat) //写数据
{
          
               DelayXms(1); //毫秒延时跳过忙检测

             RS = 1; //发数据写 1
       
             //写高4位
             //Data_IO_Port = dat & 0xF0;//写高4位             

             LCD_Data8 = dat & 0x80;// 1000 0000
             LCD_Data7 = dat & 0x40;// 0100 0000
             LCD_Data6 = dat & 0x20;// 0010 0000
             LCD_Data5 = dat & 0x10;// 0001 0000
       

               EN = 1; //打开使能
               Delay10us();//10微秒延时
             EN = 0; //关闭使能
       

             //写低4位
             //Data_IO_Port = dat<< 4;//写低4位
             LCD_Data8 = dat & 0x08; //0000 1000
             LCD_Data7 = dat & 0x04; //0000 0100
             LCD_Data6 = dat & 0x02; //0000 0010
             LCD_Data5 = dat & 0x01; //0000 0001
       
             EN = 1; //打开使能
               Delay10us();//10微秒延时
             EN = 0; //关闭使能
       
}写一个字节命令

//写一个字节命令
void LCD1602_Write_Cmd(unsigned char Cmd) //写命令
{
       
             DelayXms(1); //毫秒延时跳过忙检测
             RS = 0; //发命令写 0

       
             //写高4位
             //Data_IO_Port = dat;//高4位
       
             LCD_Data8 = Cmd & 0x80;// 1000 0000
             LCD_Data7 = Cmd & 0x40;// 0100 0000
             LCD_Data6 = Cmd & 0x20;// 0010 0000
             LCD_Data5 = Cmd & 0x10;// 0001 0000
                     
             EN = 1; //打开使能
               Delay10us();//10微秒延时
             EN = 0; //关闭使能

       
             //写低4位
             //Data_IO_Port = dat <<4;//低4位
       
             LCD_Data8 = Cmd & 0x08; //0000 1000
             LCD_Data7 = Cmd & 0x04; //0000 0100
             LCD_Data6 = Cmd & 0x02; //0000 0010
             LCD_Data5 = Cmd & 0x01; //0000 0001
       

             EN = 1; //打开使能
               Delay10us();//10微秒延时
             EN = 0; //关闭使能
       

}



屏幕初始化

//屏幕初始化
void LCD1602_LCDInit() //屏幕初始化
{

           LCD1602_Write_Cmd(0x28);   //4位接口,2行显示 5*8点阵
           DelayXms(10); //毫秒延时
           LCD1602_Write_Cmd(0x28);   //4位接口,2行显示 5*8点阵

           LCD1602_Write_Cmd(0x01);   //清屏指令
           LCD1602_Write_Cmd(0x06);   //指针自增
           LCD1602_Write_Cmd(0x0C);   //显示开,光标关
       
}

显示位置
void LCD1602_Position_ShowString(bit x, unsigned char y)//显示字符串 //参数1:显示行位置(0和1)。参数2:显示列位置。
{
       unsigned char position; //位置
   if(x == 0)
               {
          position = 0x80 + y;//显示上行的位置
   }
               else
               {
          position = 0xC0 + y;//显示下行的位置
   }
   LCD1602_Write_Cmd(position); //写入位置
}

Delay 里面如下
#include "delay.h"
#include <intrins.h>//包含空语句




void Delay10us(void)//10微秒延时        //@11.0592MHz
{
        unsigned char data i;

        i = 2;
        while (--i);
}



void Delay1ms() //1毫秒延时                //@11.0592MHz
{

        unsigned char data i, j;

        _nop_();
        i = 2;
        j = 199;
        do
        {
                while (--j);
        } while (--i);
               
}




void DelayXms(unsigned int xms) //1毫秒延时
{
          unsigned chari;       
      for(i=xms;i>0;i--)
       {
         Delay1ms();                //@11.0592MHz

       }
          
}


这样就写好了接下来调用就行


主函数
#include <reg52.h>
#include "lcd1602.h"
#include "delay.h"
/*
          测试单片机型号STC89C51RC
                  晶振:外部晶振11.0592
*/



void main()
{
               
       
          LCD1602_LCDInit(); //屏幕初始化

          LCD1602_Position_ShowString(0,3);//参数1:显示行位置(0和1)。参数2:显示列位置
      LCD1602_Write_Data('h');    //显示字符



    while(1)
        {
       


    }


}


上附件








DebugLab 发表于 2025-12-2 13:03:15

六年前写的4位并口1602程序供参考

#include <STC89C5xRC.H>
#define                LCD1602_RS                P22
#define                LCD1602_EN                P23
#define                LCD1602_D4                P24
#define                LCD1602_D5                P25
#define                LCD1602_D6                P26
#define                LCD1602_D7                P27
#define                Command                                                                0
#define                Data                                                                1
#define                Clear_Display                                                0x01        //Clear_Display
#define                Return_Home                                                        0x02        //Return_Home
#define                Entry_Mode_Cursor_Left                                0x04        //Entry_Mode_Set
#define                Entry_Mode_Entire_Right                                0x05        //Entry_Mode_Set
#define                Entry_Mode_Cursor_Right                                0x06        //Entry_Mode_Set
#define                Entry_Mode_Entire_Left                                0x07        //Entry_Mode_Set
#define                Display_Off                                                        0x08        //Display_ON/OFF
#define                Display_On                                                        0x0c        //Display_ON/OFF
#define                Display_On_Cursor_Off_Blink_On                0x0d        //Display_ON/OFF
#define                Display_On_Cursor_On_Blink_Off                0x0e        //Display_ON/OFF
#define                Display_On_Cursor_On_Blink_On                0x0f        //Display_ON/OFF
#define                Cursor_Move_Left                                        0x10        //Cursor_or_Display_Shift
#define                Cursor_Move_Right                                        0x14        //Cursor_or_Display_Shift
#define                Display_Move_Left                                        0x18        //Cursor_or_Display_Shift
#define                Display_Move_Right                                        0x1c        //Cursor_or_Display_Shift
#define                Setting_Basic_Instruction_Set                0x28        //Function_Set
#define                Setting_Extended_Instruction_Set        0x29        //Function_Set
#define                Function_Set                                                0x38        //Function_Set
#define                Contrast_Set                                                0x78        //Contrast_Set
#define                Internal_OSC                                                0x14        //Internal_OSC
#define                Power_ICON_Contrast                                        0x5e        //Power_ICON_Contrast
#define                Follower_Control                                        0x6a        //Follower_Control
#define                Power_ICON_Contrast                                        0x5e        //Power_ICON_Contrast
unsigned char code Display_Hex={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};
unsigned char code Display_Data1=
{
        "LCD_1602_Program"        //0x80
        "Conter:000000000"        //0xc0
};

/*----------------------------延时10us@STC-Y1@11.0592MHz----------------------------*/
void Delay_10us(void)
{
        unsigned char i;
        i=2;
        while(--i);
}

/*----------------------------延时x10us----------------------------*/
void Delay_x10us(unsigned char x)
{
        while(x--)
                Delay_10us();
}

/*----------------------------延时10ms@STC-Y1@11.0592MHz----------------------------*/
void Delay_10ms(void)
{
        unsigned char i,j;
        i=18;
        j=235;
        do
        {
                while(--j);
        }while(--i);
}

/*----------------------------延时x10ms----------------------------*/
void Delay_x10ms(unsigned char x)
{
        while(x--)
                Delay_10ms();
}

/*----------------------------LCD1602_Enable----------------------------*/
void LCD1602_Enable(void)
{
        LCD1602_EN=1;
        Delay_10us();
        LCD1602_EN=0;
}

/*----------------------------写命令或数据,x=0传送命令,x=1传送数据----------------------------*/
void LCD1602_Write(unsigned char temp,bit x)
{
        LCD1602_RS=x;        //x=0传送命令,x=1传送数据
        LCD1602_D4=temp&0x10;
        LCD1602_D5=temp&0x20;
        LCD1602_D6=temp&0x40;
        LCD1602_D7=temp&0x80;
        LCD1602_Enable();
        LCD1602_D4=temp&0x01;
        LCD1602_D5=temp&0x02;
        LCD1602_D6=temp&0x04;
        LCD1602_D7=temp&0x08;
        LCD1602_Enable();
}

/*----------------------------整页显示字符----------------------------*/
void Display_Text(unsigned char code *addr)
{
        unsigned char i;
        LCD1602_Write(0x80,Command);        //设置DDRAM地址
        Delay_10us();
        for(i=0;i<16;i++)
        {
                LCD1602_Write(*addr,Data);
                addr++;
        }
        LCD1602_Write(0xc0,Command);        //设置DDRAM地址
        Delay_10us();
        for(i=0;i<16;i++)
        {
                LCD1602_Write(*addr,Data);
                addr++;
        }
}

/*----------------------------指定位置显示字符----------------------------*/
void Display_Data(unsigned char x,unsigned char y,unsigned char temp)
{
        switch(y)
        {
                case 0:
                        LCD1602_Write(0x80+x,Command);        //设置DDRAM地址
                        Delay_10us();
                        LCD1602_Write(temp,Data);
                        break;
                case 1:
                        LCD1602_Write(0xc0+x,Command);        //设置DDRAM地址
                        Delay_10us();
                        LCD1602_Write(temp,Data);
                        break;
        }
}

/*----------------------------初始化LCD1602----------------------------*/
void LCD12864_Init(void)
{
        Delay_10ms();
        Delay_10ms();
        Delay_10ms();
        Delay_10ms();                //延时40ms
//        LCD1602_Write(Function_Set,Command);                                                //Function_Set
//        Delay_x10us(200);        //延时2ms
//        LCD1602_Write(Function_Set,Command);                                                //Function_Set
//        Delay_x10us(3);                //延时3us
        LCD1602_Write(Function_Set,Command);                                                //Function_Set
        Delay_x10us(3);                //延时3us
        LCD1602_Write(Setting_Basic_Instruction_Set,Command);                //Setting_Basic_Instruction_Set
        Delay_x10us(3);                //延时3us
        LCD1602_Enable();
        LCD1602_Write(Setting_Extended_Instruction_Set,Command);        //Setting_Extended_Instruction_Set
        Delay_x10us(3);                //延时3us
//        LCD1602_Write(Cursor_Move_Right,Command);                                        //Cursor_Move_Right
//        Delay_x10us(3);                //延时3us
//        LCD1602_Write(Contrast_Set,Command);                                                //Contrast_Set
//        Delay_x10us(3);                //延时3us
//        LCD1602_Write(Internal_OSC,Command);                                                //Internal_OSC
//        Delay_x10us(3);                //延时3us
//        LCD1602_Write(Power_ICON_Contrast,Command);                                        //Power_ICON_Contrast
//        Delay_x10us(3);                //延时3us
//        LCD1602_Write(Follower_Control,Command);                                        //Follower_Control
//        Delay_x10ms(20);        //延时200ms
        LCD1602_Write(Display_On,Command);                                                        //Display_On
        Delay_x10us(3);                //延时3us
        LCD1602_Write(Clear_Display,Command);                                                //Clear_Display
        Delay_x10us(200);        //延时2ms
//        LCD1602_Write(Entry_Mode_Cursor_Right,Command);                                //Entry_Mode_Cursor_Right
//        Delay_x10us(3);                //延时3us
}

void main(void)
{
        unsigned int a=0,b=0;
        LCD12864_Init();
        while(1)
        {
                Display_Text(Display_Data1);
                while(1)
                {
                        Display_Data(7,1,Display_Hex);
                        Display_Data(8,1,Display_Hex);
                        Display_Data(9,1,Display_Hex);
                        Display_Data(10,1,Display_Hex);
                        Display_Data(11,1,Display_Hex);
                        Display_Data(12,1,Display_Hex);
                        Display_Data(13,1,Display_Hex);
                        Display_Data(14,1,Display_Hex);
                        Display_Data(15,1,Display_Hex);
                        Delay_x10ms(2);
                        b++;
                        if(b>=10000)
                        {
                                b=0;
                                a++;
                        }
                }
        }
}

神农鼎 发表于 2025-12-2 14:10:04

SPI-DMA 刷 LCD12864 程序,整屏523us,AI8051U 驱动1.44寸黑白点阵屏,超高帧频 - LCD12864,LCD1602,DMA-M6800并口自动刷屏,CPU不等待,DMA-SPI刷屏 国芯人工智能技术交流网站 - AI32位8051交流社区

dahxiixz 发表于 2025-12-21 01:02:39

{:baoquan:}

ZIJIN_CHJ 发表于 2026-3-4 11:01:42

学习了.
页: [1]
查看完整版本: 8051单片机,用6线驱动1602共用6个IO口,并行驱动显示