找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1488|回复: 26
打印 上一主题 下一主题
收起左侧

关于两块51单片机共同控制lcd1602

 关闭 [复制链接]
跳转到指定楼层
楼主
ID:891089 发表于 2022-7-16 23:19 来自手机 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
最近做了一个小项目,用两块单片机共同控制一块lcd1602。思路是这样的,a单片机的p0.0-0.4控制lcd1602 dat的低四位,b单片机的p0.0-0.4控制lcd1602 dat的高四位。1602的rs rw e口都在a单片机的 p27 26 25,数据和指令靠uart传输。试了一个礼拜了,数据是传过去了,但是屏幕一直显示一行白色方块,,实在不知道为啥了,有兴趣的朋友可以试下。mcu是stc12c60s2,程序如下。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:891089 发表于 2022-7-16 23:24 | 只看该作者
主机
/*************** 用户定义参数 *****************************/

#define MAIN_Fosc                22118400L        //define main clock

#define Baudrate1                9600                //define the baudrate, 如果使用BRT做波特率发生器,则波特率跟串口2一样
                                                                        //12T mode: 600~115200 for 22.1184MHZ, 300~57600 for 11.0592MHZ

#define Baudrate2                9600                //define the baudrate2,
                                                                        //12T mode: 600~115200 for 22.1184MHZ, 300~57600 for 11.0592MHZ

#define                BUF_LENTH        128                //定义串口接收缓冲长度

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

#include<reg51.h>       
#include<intrins.h>  //包含_nop_()函数定义的头文件
#include<fun.h>

sfr AUXR1 = 0xA2;
sfr        AUXR = 0x8E;
sfr S2CON = 0x9A;        //12C5A60S2双串口系列
sfr S2BUF = 0x9B;        //12C5A60S2双串口系列
sfr IE2   = 0xAF;        //STC12C5A60S2系列
sfr BRT   = 0x9C;

unsigned char         uart1_wr;                //写指针
unsigned char         uart1_rd;                //读指针
unsigned char         xdata RX1_Buffer[BUF_LENTH];
bit                B_TI;

unsigned char         uart2_wr;                //写指针
unsigned char         uart2_rd;                //读指针
unsigned char         xdata RX2_Buffer[BUF_LENTH];
bit                B_TI2;


/****************** 编译器自动生成,用户请勿修改 ************************************/

#define T1_TimerReload        (256 - MAIN_Fosc / 192 / Baudrate1)                        //Calculate the timer1 reload value        at 12T mode
#define BRT_Reload                (256 - MAIN_Fosc / 12 / 16 / Baudrate2)                //Calculate BRT reload value

#define        TimeOut1                (28800 / (unsigned long)Baudrate1 + 2)
#define        TimeOut2                (28800 / (unsigned long)Baudrate2 + 2)

#define        TI2                                (S2CON & 0x02) != 0
#define        RI2                                (S2CON & 0x01) != 0
#define        CLR_TI2()                S2CON &= ~0x02
#define        CLR_RI2()                S2CON &= ~0x01

/******LCD1602***********/
sbit p00=P0^0;
sbit p01=P0^1;
sbit p02=P0^2;
sbit p03=P0^3;
sbit p04=P0^4;
sbit p05=P0^5;
sbit p06=P0^6;

sbit RS=P2^6;    //寄存器选择位,将RS位定义为P2.6引脚
sbit RW=P2^5;    //读写选择位,将RW位定义为P2.5引脚
sbit E=P2^7;     //使能信号位,将E位定义为P2.7引脚
sbit BF=P0^7;    //忙碌标志位,,将BF位定义为P0.7引脚

sbit tx=P2^0;    //从机状态线
sbit rx=P2^1;    //从机状态线

unsigned char flag1,flag2,flag3,flag4;//发送指令位的值

/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void delay1ms()
{
   unsigned char i,j;       
         for(i=0;i<10;i++)
          for(j=0;j<33;j++)
           ;                 
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delay(unsigned char n)
{
   unsigned char i;
        for(i=0;i<n;i++)
           delay1ms();
}
/*****************************************************
函数功能:判断液晶模块的忙碌状态
返回值:result。result=1,忙碌;result=0,不忙
***************************************************/
unsigned char BusyTest(void)
  {
    bit result;
        RS=0;       //根据规定,RS为低电平,RW为高电平时,可以读状态
    RW=1;
    E=1;        //E=1,才允许读写
    _nop_();   //空操作
    _nop_();
    _nop_();
    _nop_();   //空操作四个机器周期,给硬件反应时间       
    result=BF;  //将忙碌标志电平赋给result
        E=0;
    return result;
  }
/*****************************************************
函数功能:将模式设置指令或显示地址写入液晶模块
入口参数:dictate
***************************************************/
void WriteInstruction (unsigned char dictate)
{   
    flag1=0;flag2=0;flag3=0;flag4=0;
//   while(BusyTest()==1); //如果忙就等待
         RS=0;                  //根据规定,RS和R/W同时为低电平时,可以写入指令
         RW=0;   
         E=0;                   //E置低电平(根据表8-6,写指令时,E为高脉冲,
                             // 就是让E从0到1发生正跳变,所以应先置"0"
         _nop_();
         _nop_();             //空操作两个机器周期,给硬件反应时间
         //P0=dictate;            //将数据送入P0口,即写入指令或地址
          
          if((dictate & 0x10 )){
          flag1=1;  }else
          {flag1=0;}
          if((dictate & 0x20 )){
          flag2=1;  }else
          {flag2=0;}
          if((dictate & 0x40 )){
          flag3=1;  }else
          {flag3=0;}
          if((dictate & 0x80 )){
          flag4=1;  }else
          {flag4=0;}

             tx=0;                                                          //可以执行下步
          delay(30);
        if(flag1==1&&flag2==1&&flag3==1&&flag4==1)        {PrintString1("L111100000");}       
   else if(flag1==0&&flag2==1&&flag3==1&&flag4==1)        {PrintString1("L011100000");}  
   else if(flag1==1&&flag2==0&&flag3==1&&flag4==1)        {PrintString1("L101100000");}
   else if(flag1==0&&flag2==0&&flag3==1&&flag4==1)        {PrintString1("L001100000");}
   else if(flag1==1&&flag2==1&&flag3==0&&flag4==1)        {PrintString1("L110100000");}   
   else if(flag1==0&&flag2==1&&flag3==0&&flag4==1)        {PrintString1("L010100000");}  
   else if(flag1==1&&flag2==0&&flag3==0&&flag4==1)        {PrintString1("L100100000");}
   else if(flag1==0&&flag2==0&&flag3==0&&flag4==1)        {PrintString1("L000100000");}
   else if(flag1==1&&flag2==1&&flag3==1&&flag4==0)        {PrintString1("L111000000");}
   else if(flag1==0&&flag2==1&&flag3==1&&flag4==0)        {PrintString1("L011000000");}
   else if(flag1==1&&flag2==0&&flag3==1&&flag4==0)        {PrintString1("L101000000");}  
   else if(flag1==0&&flag2==0&&flag3==1&&flag4==0)        {PrintString1("L001000000");}
   else if(flag1==1&&flag2==1&&flag3==0&&flag4==0)        {PrintString1("L110000000");}
   else if(flag1==0&&flag2==1&&flag3==0&&flag4==0)        {PrintString1("L010000000");}
   else if(flag1==1&&flag2==0&&flag3==0&&flag4==0)        {PrintString1("L100000000");}         
   else if(flag1==0&&flag2==0&&flag3==0&&flag4==0)  {PrintString1("L000000000");}  
   delay(30);                                                  //等待从机将信号置零
   tx=1;

   
     while(rx==1);                                          //如果从机已执行完
         // delay(80);
          if((dictate & 0x01 )){
          p00=1;  }else
          {p00=0;}
          if((dictate & 0x02 )){
          p01=1;  }else
          {p01=0;}
          if((dictate & 0x04 )){
          p02=1;  }else
          {p02=0;}
          if((dictate & 0x08 )){
          p03=1;  }else
          {p03=0;}

         _nop_();
         _nop_();
         _nop_();
         _nop_();               //空操作四个机器周期,给硬件反应时间
         E=1;                   //E置高电平
         _nop_();
         _nop_();
         _nop_();
         _nop_();               //空操作四个机器周期,给硬件反应时间
         E=0;                   //当E由高电平跳变成低电平时,液晶模块开始执行命令
         
}
/*****************************************************
函数功能:指定字符显示的实际地址
入口参数:x
***************************************************/
void WriteAddress(unsigned char x)
{
     WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
}
/*****************************************************
函数功能:将数据(字符的标准ASCII码)写入液晶模块
入口参数:y(为字符常量)
***************************************************/
void WriteData(unsigned char y)
{
     flag1=0;flag2=0;flag3=0;flag4=0;
   //  while(BusyTest()==1);  
          RS=1;           //RS为高电平,RW为低电平时,可以写入数据
          RW=0;
          E=0;            //E置低电平(根据表8-6,写指令时,E为高脉冲,
                       // 就是让E从0到1发生正跳变,所以应先置"0"
          //P0=0x23;           //将数据送入P0口,即将数据写入液晶模块
          if(y & 0x10 ){
          flag1=1;  }else
          {flag1=0;}
          if(y & 0x20 ){
          flag2=1;  }else
          {flag2=0;}
          if(y & 0x40 ){
          flag3=1;  }else
          {flag3=0;}
          if(y & 0x80 ){
          flag4=1;  }else
          {flag4=0;}  

          /*
          if((y & 0x10 )){
          p04=1;  }else
          {p04=0;}
          if((y & 0x20 )){
          p05=1;  }else
          {p05=0;}
          if((y & 0x40 )){
          p06=1;  }else
          {p06=0;}
          if((y & 0x80 )){
          BF=1;  }else
          {BF=0;}
          */

            tx=0;                                                          //可以执行下步
         delay(30);
        if(flag1==1&&flag2==1&&flag3==1&&flag4==1)        {PrintString1("L111100000");}       
   else if(flag1==1&&flag2==1&&flag3==1&&flag4==0)        {PrintString1("L111000000");}  
   else if(flag1==1&&flag2==1&&flag3==0&&flag4==1)        {PrintString1("L110100000");}
   else if(flag1==1&&flag2==1&&flag3==0&&flag4==0)        {PrintString1("L110000000");}
   else if(flag1==1&&flag2==0&&flag3==1&&flag4==1)        {PrintString1("L101100000");}
   else if(flag1==1&&flag2==0&&flag3==1&&flag4==0)        {PrintString1("L101000000");}  
   else if(flag1==1&&flag2==0&&flag3==0&&flag4==1)        {PrintString1("L100100000");}
   else if(flag1==1&&flag2==0&&flag3==0&&flag4==0)        {PrintString1("L100000000");}
   else if(flag1==0&&flag2==1&&flag3==1&&flag4==1)        {PrintString1("L011100000");}  
   else if(flag1==0&&flag2==1&&flag3==1&&flag4==0)        {PrintString1("L011000000");}
   else if(flag1==0&&flag2==1&&flag3==0&&flag4==1)        {PrintString1("L010100000");}
   else if(flag1==0&&flag2==1&&flag3==0&&flag4==0)        {PrintString1("L010000000");}
   else if(flag1==0&&flag2==0&&flag3==1&&flag4==1)        {PrintString1("L001100000");}
   else if(flag1==0&&flag2==0&&flag3==1&&flag4==0)        {PrintString1("L001000000");}
   else if(flag1==0&&flag2==0&&flag3==0&&flag4==1)        {PrintString1("L000100000");}
   else if(flag1==0&&flag2==0&&flag3==0&&flag4==0)        {PrintString1("L000000000");}
     delay(30);
         tx=1;
         
          while(rx==1);       
         // delay(80);
      if((y & 0x01 )){
          p00=1;  }else
          {p00=0;}
          if((y & 0x02 )){
          p01=1;  }else
          {p01=0;}
          if((y & 0x04 )){
          p02=1;  }else
          {p02=0;}
          if((y & 0x08 )){
          p03=1;  }else
          {p03=0;}
          _nop_();
          _nop_();
          _nop_();
      _nop_();       //空操作四个机器周期,给硬件反应时间
          E=1;           //E置高电平
          _nop_();
          _nop_();
          _nop_();
          _nop_();        //空操作四个机器周期,给硬件反应时间
          E=0;            //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:对LCD的显示模式进行初始化设置
***************************************************/
void InitLCD1602(void)
{
    delay(200);               //延时15ms,首次写指令时应给LCD一段较长的反应时间
    WriteInstruction(0x38);   //显示模式设置:16×2显示,5×7点阵,8位数据接口
        delay(200);                //延时5ms 
        WriteInstruction(0x38);
        delay(200);
        WriteInstruction(0x38);         //0x38
        delay(200);
        WriteInstruction(0x0f);  //显示模式设置:显示开,有光标,光标闪烁
        delay(200);
        WriteInstruction(0x06);  //显示模式设置:光标右移,字符不移
        delay(200);
        WriteInstruction(0x01);  //清屏幕指令,将以前的显示内容清除
        delay(200);
}

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


void        main(void)
{
    delay(1000);
    uart1_init();
        uart2_init();
    InitLCD1602();//调用LCD初始化函数
        uart1_rd = 0;
        uart1_wr = 0;
        uart2_rd = 0;
        uart2_wr = 0;

//        AUXR |=  0x01;                //串口1使用独立波特率发生器, 波特率跟串口2一样
//        AUXR1 |= (1<<4);        //将UART2从P1口切换到 RXD2--P1.2切换到P4.2   TXD2---P1.3切换到P4.3

       
        while(1)
        {
           /*
                if(uart1_rd != uart1_wr)        //串口0转发
                {
                        UART1_TxByte(RX1_Buffer[uart1_rd]);
                        if(++uart1_rd >= BUF_LENTH)                uart1_rd = 0;
                }

                if(uart2_rd != uart2_wr)        //串口2转发
                {
                        UART2_TxByte(RX2_Buffer[uart2_rd]);
                        if(++uart2_rd >= BUF_LENTH)                uart2_rd = 0;
                }
                */
        //        PrintString1("123456789+");
        //        delay1();  
       
        WriteInstruction(0x01);//清显示:清屏幕指令
        delay(300);
        WriteAddress(0x00);    //设置显示位置为第一行的第5个字
        delay(300);
        WriteData('#');
        delay(300);               
        }
}

void        UART1_TxByte(unsigned char dat)
{
        B_TI = 0;
        SBUF = dat;
        while(!B_TI);
        B_TI = 0;
}

void        UART2_TxByte(unsigned char dat)
{
        B_TI2 = 0;
        S2BUF = dat;
        while(!B_TI2);
        B_TI2 = 0;
}

void PrintString1(unsigned char *puts)                //发送一串字符串
{
    for (; *puts != 0;        puts++)  UART1_TxByte(*puts);         //遇到停止符0结束
}

void PrintString2(unsigned char *puts)                //发送一串字符串
{
    for (; *puts != 0;        puts++)  UART2_TxByte(*puts);         //遇到停止符0结束
}



void        uart1_init(void)
{
        PCON |= 0x80;                //UART0 Double Rate Enable
        SCON = 0x50;                //UART0 set as 10bit , UART0 RX enable
        TMOD &= ~(1<<6);                //Timer1 Set as Timer, 12T
        TMOD = (TMOD & ~0x30) | 0x20;        //Timer1 set as 8 bits auto relaod
        TH1 = T1_TimerReload;                //Load the timer
        TR1  = 1;
        ES  = 1;
        EA = 1;
}



/**********************************************/
void UART0_RCV (void) interrupt 4
{
        if(RI)
        {
                RI = 0;
                RX1_Buffer[uart1_wr] = SBUF;
                if(++uart1_wr >= BUF_LENTH)        uart1_wr = 0;
        }

        if(TI)
        {
                TI = 0;
                B_TI = 1;
        }
}


/**********************************************/
void        uart2_init(void)
{
        AUXR |=  (1 << 3);                //串口2波特率加倍
        S2CON  = (S2CON & 0x3f) | (1<<6);        //串口2模式1,8位UART,(2^S2SMOD / 32) * BRT溢出率
        S2CON |= 1 << 4;                //允许串2接收

        AUXR |=  1 << 4;        //baudrate use BRT
        BRT = BRT_Reload;

        IE2 |=  1;                        //允许串口2中断
}

/**********************************************/
void UART2_RCV (void) interrupt 8
{
        if(RI2)
        {
                CLR_RI2();
                RX2_Buffer[uart2_wr] = S2BUF;
                if(++uart2_wr >= BUF_LENTH)        uart2_wr = 0;
        }

        if(TI2)
        {
                CLR_TI2();
                B_TI2 = 1;
        }
}
从机
/*************** 用户定义参数 *****************************/

#define MAIN_Fosc                22118400L        //define main clock

#define Baudrate1                9600                //define the baudrate, 如果使用BRT做波特率发生器,则波特率跟串口2一样
                                                                        //12T mode: 600~115200 for 22.1184MHZ, 300~57600 for 11.0592MHZ

#define Baudrate2                9600                //define the baudrate2,
                                                                        //12T mode: 600~115200 for 22.1184MHZ, 300~57600 for 11.0592MHZ

#define                BUF_LENTH        10                //定义串口接收缓冲长度

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

#include        <reg51.h>

sfr AUXR1 = 0xA2;
sfr        AUXR = 0x8E;
sfr S2CON = 0x9A;        //12C5A60S2双串口系列
sfr S2BUF = 0x9B;        //12C5A60S2双串口系列
sfr IE2   = 0xAF;        //STC12C5A60S2系列
sfr BRT   = 0x9C;

unsigned char         uart1_wr;                //写指针
unsigned char         uart1_rd;                //读指针
unsigned char         xdata RX1_Buffer[BUF_LENTH];
bit                B_TI;

unsigned char         uart2_wr;                //写指针
unsigned char         uart2_rd;                //读指针
unsigned char         xdata RX2_Buffer[BUF_LENTH];
bit                B_TI2;

sbit p00=P0^0;
sbit p01=P0^1;
sbit p02=P0^2;
sbit p03=P0^3;
sbit p04=P0^4;
sbit p05=P0^5;
sbit p06=P0^6;


sbit tx=P2^0;    //从机状态线
sbit rx=P2^1;    //从机状态线
/****************** 编译器自动生成,用户请勿修改 ************************************/

#define T1_TimerReload        (256 - MAIN_Fosc / 192 / Baudrate1)                        //Calculate the timer1 reload value        at 12T mode
#define BRT_Reload                (256 - MAIN_Fosc / 12 / 16 / Baudrate2)                //Calculate BRT reload value

#define        TimeOut1                (28800 / (unsigned long)Baudrate1 + 2)
#define        TimeOut2                (28800 / (unsigned long)Baudrate2 + 2)

#define        TI2                                (S2CON & 0x02) != 0
#define        RI2                                (S2CON & 0x01) != 0
#define        CLR_TI2()                S2CON &= ~0x02
#define        CLR_RI2()                S2CON &= ~0x01

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

/******************** 本地函数声明 ***************/
void        uart1_init(void);
void        uart2_init(void);
void        UART1_TxByte(unsigned char dat);
void        UART2_TxByte(unsigned char dat);
void        PrintString1(unsigned char code *puts);
void        PrintString2(unsigned char code *puts);



void        main(void)
{
        uart1_rd = 0;
        uart1_wr = 0;
        uart2_rd = 0;
        uart2_wr = 0;

//        AUXR |=  0x01;                //串口1使用独立波特率发生器, 波特率跟串口2一样
//        AUXR1 |= (1<<4);        //将UART2从P1口切换到 RXD2--P1.2切换到P4.2   TXD2---P1.3切换到P4.3
       
        uart1_init();
        uart2_init();

       
        while(1)
        {
            //if(tx==0){rx=1;}
                if((uart1_rd != uart1_wr)&&RX1_Buffer[0]=='1')        //串口0转发
                {
                        UART2_TxByte(RX1_Buffer[uart1_rd]);
                        if(++uart1_rd >= BUF_LENTH)                uart1_rd = 0;
                }else if((uart1_rd !=10 /*uart1_wr*/)&&RX1_Buffer[0]=='L'&&tx==0)        //串口0转发
                {
                     rx=1;                                                           //从机开始执行,主机等待
                         if(RX1_Buffer[1]=='1'){
                 p00=1;}else  {p00=0;}
                         if(RX1_Buffer[2]=='1'){
                         p01=1;}else  {p01=0;}         
                         if(RX1_Buffer[3]=='1'){
                         p03=1;}else  {p03=0;}
                         if(RX1_Buffer[4]=='1'){
                         p04=1; }else  {p04=0;}
                        UART2_TxByte(RX1_Buffer[uart1_rd]);
                        if(++uart1_rd >= BUF_LENTH)                uart1_rd = 0;
                        rx=0;                                                           //从机已执行完
                }

                if(uart2_rd != uart2_wr)        //串口2转发
                {
                        UART1_TxByte(RX2_Buffer[uart2_rd]);
                        if(++uart2_rd >= BUF_LENTH)                uart2_rd = 0;
                }
        }
}

void        UART1_TxByte(unsigned char dat)
{
        B_TI = 0;
        SBUF = dat;
        while(!B_TI);
        B_TI = 0;
}

void        UART2_TxByte(unsigned char dat)
{
        B_TI2 = 0;
        S2BUF = dat;
        while(!B_TI2);
        B_TI2 = 0;
}

void PrintString1(unsigned char code *puts)                //发送一串字符串
{
    for (; *puts != 0;        puts++)  UART1_TxByte(*puts);         //遇到停止符0结束
}

void PrintString2(unsigned char code *puts)                //发送一串字符串
{
    for (; *puts != 0;        puts++)  UART2_TxByte(*puts);         //遇到停止符0结束
}



void        uart1_init(void)
{
        PCON |= 0x80;                //UART0 Double Rate Enable
        SCON = 0x50;                //UART0 set as 10bit , UART0 RX enable
        TMOD &= ~(1<<6);                //Timer1 Set as Timer, 12T
        TMOD = (TMOD & ~0x30) | 0x20;        //Timer1 set as 8 bits auto relaod
        TH1 = T1_TimerReload;                //Load the timer
        TR1  = 1;
        ES  = 1;
        EA = 1;
}



/**********************************************/
void UART0_RCV (void) interrupt 4
{
        if(RI)
        {
                RI = 0;
                RX1_Buffer[uart1_wr] = SBUF;
                if(++uart1_wr >= BUF_LENTH)        uart1_wr = 0;
        }

        if(TI)
        {
                TI = 0;
                B_TI = 1;
        }
}


/**********************************************/
void        uart2_init(void)
{
        AUXR |=  (1 << 3);                //串口2波特率加倍
        S2CON  = (S2CON & 0x3f) | (1<<6);        //串口2模式1,8位UART,(2^S2SMOD / 32) * BRT溢出率
        S2CON |= 1 << 4;                //允许串2接收

        AUXR |=  1 << 4;        //baudrate use BRT
        BRT = BRT_Reload;

        IE2 |=  1;                        //允许串口2中断
}

/**********************************************/
void UART2_RCV (void) interrupt 8
{
        if(RI2)
        {
                CLR_RI2();
                RX2_Buffer[uart2_wr] = S2BUF;
                if(++uart2_wr >= BUF_LENTH)        uart2_wr = 0;
        }

        if(TI2)
        {
                CLR_TI2();
                B_TI2 = 1;
        }
}
回复

使用道具 举报

板凳
ID:883242 发表于 2022-7-16 23:46 | 只看该作者
思路本身就错了,两个单片机很难满足1602的时序要求,一个单片机可以轻松做到。
回复

使用道具 举报

地板
ID:213173 发表于 2022-7-17 08:03 | 只看该作者
用两块单片机共同控制一块lcd1602实施起来很困难,实在想不出这样做的必要性,楼主要画蛇添足???
回复

使用道具 举报

5#
ID:709636 发表于 2022-7-17 10:22 | 只看该作者
为啥要接两个单片机呢?如果想做双机通信的话,可以把1602接到主机上,数据在从机发啊。
回复

使用道具 举报

6#
ID:891089 发表于 2022-7-17 11:46 来自手机 | 只看该作者
wulin 发表于 2022-7-17 08:03
用两块单片机共同控制一块lcd1602实施起来很困难,实在想不出这样做的必要性,楼主要画蛇添足???

我也知道一个单片机好弄啊,我有特殊的必要性
回复

使用道具 举报

7#
ID:891089 发表于 2022-7-17 11:46 来自手机 | 只看该作者
fgfd 发表于 2022-7-17 10:22
为啥要接两个单片机呢?如果想做双机通信的话,可以把1602接到主机上,数据在从机发啊。

我也知道一个单片机好弄啊,我有特殊的必要性
回复

使用道具 举报

8#
ID:213173 发表于 2022-7-17 14:20 | 只看该作者
美琴的备胎 发表于 2022-7-17 11:46
我也知道一个单片机好弄啊,我有特殊的必要性

既然这样做你有特殊的必要性,应该是能够解决的。
1.如端口不够用可改4线驱动。
2.如没有一组完整端口可由任意端口组合。
3.两个单片机通过串口通讯很难满足1602对时序的要求。可以考虑两个单片机共用一个外部时钟,用中断+简单的串行通讯传输数据。
回复

使用道具 举报

9#
ID:624769 发表于 2022-7-17 14:32 来自手机 | 只看该作者
楼主这是在天马行空,做项目还是要脚踏实地,等雇了一群程序员给你打下手,再琢磨这些一拍脑门的想法吧,为什么说你是一拍脑门呢?你看看你自己提出的想法: a单片机的p0.0-0.4控制lcd1602 dat的低四位,b单片机的p0.0-0.4控制lcd1602 dat的高四位。 十个io,控制高低8位? 你自己真的仔细思考过,架构过,研究过,实验过这个设想么? 别说什么特殊需要,没有一个需要是需要这样来协同控制得。
回复

使用道具 举报

10#
ID:401564 发表于 2022-7-17 14:56 | 只看该作者
玩了很久的单片机,多多少少还是会一点点的
想了半天,实在是找不到要用两个单片机控制一个LCD的理由
1,如果是DIY,随便找一个IIC控制的LCD的直接用OLED不就行了?
2,如果是产品,不知道项目经理是干什么的?一个LCD1602能显示多少东西?需要用两个单片机去控制?两个单片机的资源在很多情况下,都能找到另一个型号的单片机来代替,比如串口,A单片机只有一个串口,那我肯定能找到有两个串口的单片机
从以往的经验分析,8051+LCD1602应该是一个DIY作品或者是测试架之类的,直接找一个IIC控制的LCD它不行吗?
回复

使用道具 举报

11#
ID:891089 发表于 2022-7-17 15:23 来自手机 | 只看该作者
188610329 发表于 2022-7-17 14:32
楼主这是在天马行空,做项目还是要脚踏实地,等雇了一群程序员给你打下手,再琢磨这些一拍脑门的想法吧,为 ...

首先,端口数算是个笔误。其次,这也不是一拍脑门的想法,从dat端口的io口分离,到串口通信,PCB设计,焊接,用了一周的时间。如果你非要认为是天马行空,或者一拍脑门,那我也觉得我的付出是值得的。至少我真的为此做出了努力。反倒是你们,不知道年纪多大了,做什么工作,是不是缺少了一些对新鲜事物的探索欲?
回复

使用道具 举报

12#
ID:891089 发表于 2022-7-17 15:26 来自手机 | 只看该作者
Y_G_G 发表于 2022-7-17 14:56
玩了很久的单片机,多多少少还是会一点点的
想了半天,实在是找不到要用两个单片机控制一个LCD的理由
1,如 ...

我玩单片机已经五年了,你说的iic我会不知道?我的标题已经说的很清楚了,是用并行数据口,如果你不愿意提供帮助,大可一笑而过,划出去。为什么要对我冷嘲热讽?难道你已经失去了对新鲜事物的接受能力?开始墨守陈规了?
回复

使用道具 举报

13#
ID:891089 发表于 2022-7-17 15:27 来自手机 | 只看该作者
wulin 发表于 2022-7-17 14:20
既然这样做你有特殊的必要性,应该是能够解决的。
1.如端口不够用可改4线驱动。
2.如没有一组完整端口 ...

我的必要理由就是必须用两个单片机并行通信。你说的公用一个晶振可能会有效果?
回复

使用道具 举报

14#
ID:401564 发表于 2022-7-17 15:58 | 只看该作者
美琴的备胎 发表于 2022-7-17 15:26
我玩单片机已经五年了,你说的iic我会不知道?我的标题已经说的很清楚了,是用并行数据口,如果你不愿意 ...

所谓"冷嘲热讽",只是你个人看法,我不带感情回复,这只是技术问题而已
所谓"难道你已经失去了对新鲜事物的接受能力?开始墨守陈规了?"
我不知道什么叫新鲜事物,如果说是把一件简单的事情复杂化也算是新鲜事物,那么,我承认,你这确实是很新鲜
把原本可以用一个单片机能做的事,分成两个单片机来做,这就叫创新?
墨守陈规,我并不是,我刚刚来论坛的时候,99SE还不会用,现在我会AD了
以前我是汇编的,现在我会C了,从开始有学STM32的想法,到入门STM32,我有了想法就去实现了
这是我几个月前的帖子,那个时候,我还不知道STM32库函数是怎么回事http://www.51hei.com/bbs/dpj-218698-1.html
这是我学了二十多天STM32之后的回复,这个时候,我已经开始可以帮助别人解答问题了
http://www.51hei.com/bbs/dpj-219967-1.html
我不是说我有多牛,我只想说明 ,我多少还是有着上进的心态的,还是有着学习的心态的

那我就在想:为什么非得要两个stc12c60s2去控制一个LCD不可呢?
stc12c60s2是比较久的单片机了?那我可不可以用STC8A8K来代替呢,后者有更多的串口,有内置上拉电阻,12位ADC,而且价格更便宜,货源也更稳定
在数据处理方便,为什么一定要两个单片机来做呢?为什么你不把整个项目的大概要求说一下,也许有更好的办法呢?
可以看出来,墨守陈规的人是你而已
至于你知不知道IIC,我不评论,那是你自己说的

对于帮助,并不是说你要代码就给代码,你要电路就给电路,那才叫帮助


你可以把不涉及商业机密的东西说一下,整个项目大概的要求,为什么要两个单片机?为什么不用IIC说一下
在一个电路中用两个单片机的,并不是什么新鲜事,那我就在想,可不可以把功能稍稍改一下,只用一个单片机来控制LCD呢?
我知道那么多字,你估计就是一眼扫过而已,不会认真看,这不重要,我就单纯的无聊而已,打发一下时间而已
回复

使用道具 举报

15#
ID:624769 发表于 2022-7-17 16:42 来自手机 | 只看该作者
美琴的备胎 发表于 2022-7-17 15:23
首先,端口数算是个笔误。其次,这也不是一拍脑门的想法,从dat端口的io口分离,到串口通信,PCB设计,焊 ...

你说对新事物的探索欲? 那你要给个"诱惑"出来啊 你这样做的好处是什么?"探索欲"前提是"提高和进步"我现在能通过你这个"灵光一闪"所假象到的任何"好处",都一一被否决了,我如何产生你所谓的"探索欲"?你知道串口通信要耗费多少时间么?要耗费多少io么?要耗费多少内存么?最后达到的效果呢? 加快了速度?没有,节约了io?没有,减少了成本?也没有!怎么算都是入不敷出的投资,这何来探索欲?
回复

使用道具 举报

16#
ID:88256 发表于 2022-7-17 17:19 | 只看该作者
美琴的备胎 发表于 2022-7-17 15:26
我玩单片机已经五年了,你说的iic我会不知道?我的标题已经说的很清楚了,是用并行数据口,如果你不愿意 ...

1:标题根本未提及用并行数据口,正文有但是是不成功的,也未强调必须用并行。
2:10楼的只是表达自己的看法,我是看不出有什么冷嘲热讽的,你指出来看看?
3:在1楼你并未详细说明,坛友们给个更合理的建议有什么奇怪的,谁知道你方案定死打板验证了?反过来嘲笑坛友“失去了对新鲜事物的接受能力”,不知道你这方案有多大的优势是多么的新鲜?这又是求助于人的态度吗?
4:不知道拿玩单片机5年来说事有什么意义,回答的坛友们我估计玩单片机比你时间长的多的是,有什么好得意的?而且,玩单片机是否精,并不一定和年限挂钩,我看了一下你的主题,反而是发帖求助的居多,还不是早年间的
回复

使用道具 举报

17#
ID:401564 发表于 2022-7-17 17:50 | 只看该作者
hhdsdy 发表于 2022-7-17 17:19
1:标题根本未提及用并行数据口,正文有但是是不成功的,也未强调必须用并行。
2:10楼的只是表达自己的 ...

正常现象,有的人提问了,你回答的人还得放低自己的姿态去回答,不然,人家不高兴
而往往这种问题基本是最终无解的
就拿这个问题来说,一开始楼主的目的是想知道"两个单片机控制一个LCD"的
现在看来,这个问题显然已经不重要了,重心已经变成了"谁才是失去了对新鲜事物接受能力的人"
还好没有说我老,他要是说我老了,我就会很伤心的,因为这是事实,我真是个老头子,老头子最怕别人说自己是老头子
回复

使用道具 举报

18#
ID:161164 发表于 2022-7-17 18:59 | 只看该作者
不明白为什么要单问题覆杂化
1. LCD1602有四线模式的,以你的情况,一个单片机己经可以驱动LCD1602
2. 即使是为了实验,明明传一个字节的数据己经足够,为什么要把4位元数据化为十个字节("LXXXX0000/0")?
3. 就算要传十个字节,明明有更简洁的方法,为什么要写得这么累赘?
  1. char String[] = {"L000000000\0"};

  2.         if(flag1)String[1] = '1';else String[1] = '0';
  3.         if(flag2)String[2] = '1';else String[2] = '0';
  4.         if(flag3)String[3] = '1';else String[3] = '0';
  5.         if(flag4)String[4] = '1';else String[4] = '0';
  6.         PrintString1(String);
复制代码



回复

使用道具 举报

19#
ID:891089 发表于 2022-7-17 20:13 来自手机 | 只看该作者
hhdsdy 发表于 2022-7-17 17:19
1:标题根本未提及用并行数据口,正文有但是是不成功的,也未强调必须用并行。
2:10楼的只是表达自己的 ...

标题没有,正文有没有,连看都不看是吧?八位dat口不是并行是什么?难道我问题多不是因为我做的东西多吗?你看看我提问的有一个是直接要程序的吗?有的人一年做不了几个项目,做的还都是csdn一搜就能搜到的,你好好看看我是提问题提的多,还是提供程序提供的多?我800多积分都是提问题提出的吗?再说其他人,我开篇就写了八位dat,还说用iic,要么给我提些建议,要么直接划走,说一堆无所谓的话是为了显示他知道的多吗?都说了两块单片机,dat口,还给我扯到用stc8,说这些有用吗
回复

使用道具 举报

20#
ID:891089 发表于 2022-7-17 20:19 来自手机 | 只看该作者
188610329 发表于 2022-7-17 16:42
你说对新事物的探索欲? 那你要给个"诱惑"出来啊 你这样做的好处是什么?"探索欲"前提是"提高和进步"我现 ...

标题就是我的欲望,诱惑就是这样做出来我能开心。我只是自己玩,有必要把io内存这些资源算的这么清楚吗?难道两块单片机控制lcd1602不是探索?不是创新?你可以觉得很滑稽,很搞笑,很浪费,但我就是觉得很有趣,你认为的'提高和进步'明显已经功利化了,你认为降低成本才是提高和创新,抱歉,我还年轻,我还可以挥霍
回复

使用道具 举报

21#
ID:891089 发表于 2022-7-17 20:21 来自手机 | 只看该作者
Y_G_G 发表于 2022-7-17 15:58
所谓"冷嘲热讽",只是你个人看法,我不带感情回复,这只是技术问题而已
所谓"难道你已经失去了对新鲜事物的 ...

真的搞不懂,明明跟简单的问题,可以,有什么错误指出来,或者不行。你用了一多半的篇幅提那么多没用的东西干嘛,引经据典看似字数很多,实则长篇大论,整个文章的重点只有一小段话,你是抓不到重点吗?
回复

使用道具 举报

22#
ID:891089 发表于 2022-7-17 20:25 来自手机 | 只看该作者
lkc8210 发表于 2022-7-17 18:59
不明白为什么要单问题覆杂化
1. LCD1602有四线模式的,以你的情况,一个单片机己经可以驱动LCD1602
2. 即 ...

因为我要传的东西很多,比如L代表是传输lcd1602信号,类似的还有P是代表传输的io口数据,U代表传输的串口数据,前四位不用解释了,是io口,其他位计划要带数据的,就是显示的内容
回复

使用道具 举报

23#
ID:624769 发表于 2022-7-17 20:44 来自手机 | 只看该作者
美琴的备胎 发表于 2022-7-17 20:21
真的搞不懂,明明跟简单的问题,可以,有什么错误指出来,或者不行。你用了一多半的篇幅提那么多没用的东 ...

用最简单的话来讲:
可以,10楼的提到的第3点已经指出了一个方向,虽然不是唯一方向。可惜你看不明白。
不可以,因为你的知识储备,和对单片机的原理,以及LCD的工作原理的理解不够,不足以支撑你完成这样构想。
撇开实用性不讲,如果,你纯粹为了达成这样的构想而要继续做下去的话,建议你了解一下"同步时钟"的概念,这是你这个项目继续下去的必要条件。
回复

使用道具 举报

24#
ID:624769 发表于 2022-7-17 20:46 来自手机 | 只看该作者
美琴的备胎 发表于 2022-7-17 20:21
真的搞不懂,明明跟简单的问题,可以,有什么错误指出来,或者不行。你用了一多半的篇幅提那么多没用的东 ...

用最简单的话来讲:
可以,
这里更正一下:   
8楼的提到的第3点已经指出了一个方向,虽然不是唯一方向。可惜你看不明白。
不可以,因为你的知识储备,和对单片机的原理,以及LCD的工作原理的理解不够,不足以支撑你完成这样构想。
撇开实用性不讲,如果,你纯粹为了达成这样的构想而要继续做下去的话,建议你了解一下"同步时钟"的概念,这是你这个项目继续下去的必要条件。
回复

使用道具 举报

25#
ID:401564 发表于 2022-7-17 21:28 | 只看该作者
美琴的备胎 发表于 2022-7-17 20:21
真的搞不懂,明明跟简单的问题,可以,有什么错误指出来,或者不行。你用了一多半的篇幅提那么多没用的东 ...

你的目的是想知道"关于两块51单片机共同控制lcd1602"
很显然,这个问题已经不重要了,整个问题的重心已经变成了谁失去了对新鲜事物的接受能力,谁比谁年轻
再讨论下去可能就会变成我的技术比你好,或者是你的技术比我好之类的了
你本来是想要一条鱼的,我觉得单给你一条鱼好像不能解决问题,我就笑咪咪问你"你为什么要鱼呢?要不要我教你怎么打鱼"
我的笑到了你那里,就变成嘲笑,然后,你就开始跟我争论谁比谁思想更先进
至于你原本想要的鱼,早就不重要了
如果是我问题这个问题,肯定不是你这样的
我会把我的想法告诉大家,我要做什么东西,比如是接收某个串口的数据,然后控制另外一个硬件
如果别人嘲笑我想法很蠢,那我就会问"那怎么做好点呢?"
如果不是商业机密,我还会把硬件电路上传
而不是像你这样,把时间浪费在跟不认识的人去争论一个跟问题本身没有半点关系,而且不会结果的答案这就是你跟我的不同
我就是无聊,打字就是打发时间,那么,我的目的已经达到了
回复

使用道具 举报

26#
ID:213173 发表于 2022-7-17 22:09 | 只看该作者
美琴的备胎 发表于 2022-7-17 15:27
我的必要理由就是必须用两个单片机并行通信。你说的公用一个晶振可能会有效果?

虽说这样驱动1602有点自找麻烦,但还是能成功。仿真没有问题,未经实物验证。


测试程序 仿真.rar (98.23 KB, 下载次数: 5)

回复

使用道具 举报

27#
ID:891089 发表于 2022-7-18 21:59 来自手机 | 只看该作者
很抱歉,已经做出来了,此贴封楼

IMG20220718215814.jpg (1.39 MB, 下载次数: 104)

IMG20220718215814.jpg

IMG20220718215808.jpg (1.17 MB, 下载次数: 104)

IMG20220718215808.jpg
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表