用 74HC595 把 LCD1602 改成串行数据接口

LCD1602 的接口形式是并行的,它有 8 条数据线、3 条控制线。这样就需要 11 条线来控制它的正常工作。虽然它还可以工作在 4 位数据线的形式,最精简的形式是 6 条线。


有位网友想要使用 74HC595 进行串-并转换,想要用 4 条线来控制 LCD1602。

可见链接:http://zhidao.baidu.com/question/458604195.html


多用了一块芯片,省下了单片机的引脚,这也算是一种方法吧,在系统规模较大、资源紧张的条件下,还是值得应用的。


74HC595 是“串入并出”的移位寄存器芯片,它需要用 3 条线控制数据的输入,才能正常的输出 8 位数据。


有了 8 位数据,这时,LCD1602 还需要至少两条控制线。


经过做而论道的精心设计,分时使用这些控制线,最终,仅仅使用了 3 条线,就完成了对 74HC595 和 LCD1602 的有效控制 !


这要比前面的网友提出的 4 条线的方案,还要更加精简,节省率提高了 25%。


精简后的电路图如下:


用 74HC595 把 LCD1602 改成串行数据接口 - 非著名博主 - 电子信息角落


图中是一个数字钟,是为另一个网友编写的,可以参考下面的链接:

http://hi.baidu.com/do_sermon/item/c8d1161d40768f10e3f98682

http://hi.baidu.com/%D7%F6%B6%F8%C2%DB%B5%C0/blog/item/a0c99e2343b541844423e865.html

百度空间在 2012 年 8 月,无聊的改版了,结果,把它自己的网站链接,都弄断了。因此,下面的链接,已经失效了。不删了,留作纪念吧。)


由于 LCD1602 的驱动电路发生了改变,所以数字钟的程序,也要相应的修改。

那么,针对本电路的程序如下:


//===================================================


#include<reg52.h>

#define uchar unsigned char 

#define uint unsigned int


#define KEY_IO P3


sbit LCD_RS = P2^0;

sbit LCD_EN = P2^2;


sbit SCK = P2^0;

sbit SDI = P2^1;

sbit RCK = P2^2;


sbit SPK = P1^2;

sbit LED = P2^4;


bit new_s, modify = 0;

char t0, sec = 50, min = 59, hour = 23;


char code LCD_line1[] = "Designed by ZELD";

char code LCD_line2[] = "Timer: 00:00:00 ";

char Timer_buf[] = "23:59:50";

//---------------------------------------------------

void delay(uint z)

{

    uint  x, y;

    for(x = z; x > 0; x--)  for(y = 100; y > 0; y--);

}

//---------------------------------------------------

void write_595(uchar date)//写入595

{

    uchar i;

    for(i = 0; i < 8; i++) {

      SCK = 0;  SDI = date & 0x80;

      SCK = 1;  date <<= 1;

    }

}

//---------------------------------------------------

void W_LCD_Com(uchar com)      //写指令

{

    write_595(com); LCD_RS = 0;//写入指令

    RCK = 1;  RCK = 0;  //令595输出, 并用EN输出一个高脉冲 

}

//---------------------------------------------------

void W_LCD_Dat(uchar dat)      //写数据

{

    write_595(dat); LCD_RS = 1;//写入数据

    RCK = 1;  RCK = 0;  //令595输出, 并用EN输出一个高脉冲 

}

//---------------------------------------------------

void W_LCD_STR(uchar *s)       //写字符串

{

    while(*s)  W_LCD_Dat(*s++);

}

//---------------------------------------------------

void W_BUFF(void)              //填写显示缓冲区

{

    Timer_buf[7] = sec % 10 + 48; Timer_buf[6] = sec / 10 + 48;

    Timer_buf[4] = min % 10 + 48; Timer_buf[3] = min / 10 + 48;

    Timer_buf[1] = hour % 10 + 48;Timer_buf[0] = hour / 10 + 48;

    W_LCD_Com(0xc0 + 7); W_LCD_STR(Timer_buf);

}

//---------------------------------------------------

uchar read_key(void)

{

    uchar  x1, x2;

    KEY_IO = 255;

    x1 = KEY_IO;

    if (x1 != 255) {

      delay(100);

      x2 = KEY_IO;

      if (x1 != x2)  return 255;

      while(x2 != 255) x2 = KEY_IO;

      if      (x1 == 0x7f)  return 0;

      else if (x1 == 0xbf)  return 1;

      else if (x1 == 0xdf)  return 2;

      else if (x1 == 0xef)  return 3;

      else if (x1 == 0xf7)  return 4;

    }

    return 255;

}

//---------------------------------------------------

void Init()

{

    W_LCD_Com(0x38); delay(50); 

    W_LCD_Com(0x38); delay(50); 

    W_LCD_Com(0x0c);

    W_LCD_Com(0x06);

    W_LCD_Com(0x01); delay(50); 

    W_LCD_Com(0x80); W_LCD_STR(LCD_line1);

    W_LCD_Com(0xC0); W_LCD_STR(LCD_line2);


    TMOD = 0x01;   //T0定时方式1

    TH0 = 0x4c; 

    TR0 = 1;       //启动T0

    PT0 = 1;       //高优先级, 以保证定时精度

    ET0 = 1;

    EA = 1;

}

//---------------------------------------------------

void main()

{

    uint i, j;

    uchar Key;

    Init();


    while(1)  {

//-------------------------------

      if (new_s) { //如果出现了新的一秒, 修改时间

        new_s = 0;    sec++;  sec %= 60;

        if(!sec)  {   min++;  min %= 60;

          if(!min)  { hour++; hour %= 24;}

        }

        W_BUFF();  //写显示

//-------------------------------

        if (!sec && !min) { //整点报时

          for (i = 0; i < 200; i++) {

            SPK = 0; for (j = 0; j < 100; j++);

            SPK = 1; for (j = 0; j < 100; j++);

        } }

      }

//-------------------------------

      Key = read_key();  //读出按键

      switch(Key) {      //分别处理四个按键

      case  0: modify = 1; break;

      case  1: if(modify) {min++;  min %= 60;  W_BUFF(); break;}

      case  2: if(modify) {hour++; hour %= 24; W_BUFF(); break;}

      case  3: modify = 0; break;

    } }

}

//---------------------------------------------------

void timer0(void) interrupt 1  //T0中断函数, 50ms执行一次

{

    TH0 = 0x4c; 

    t0++; t0 %= 20;   //20, 一秒钟

    if(t0 == 0)  {new_s = 1; LED = ~LED;}

    if(modify)  LED = 0;

}

//===================================================



  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用74HC595芯片来实现LCD1602的控制,具体步骤如下: 1. 连接电路 将74HC595的VCC引脚连接到Arduino的5V引脚,GND引脚连接到Arduino的GND引脚。将74HC595的SER引脚连接到Arduino的数字引脚(例如:D11),RCLK引脚连接到Arduino的数字引脚(例如:D10),SRCLK引脚连接到Arduino的数字引脚(例如:D9)。 将LCD1602的RS引脚连接到74HC595的Q0引脚,RW引脚连接到74HC595的Q1引脚,E引脚连接到74HC595的Q2引脚,D4-D7引脚分别连接到74HC595的Q3-Q6引脚。 2. 编写代码 使用Arduino IDE编写代码,包括对74HC595进行数据写入和对LCD1602进行初始化和显示控制。 以下是一个简单的示例代码: #include <LiquidCrystal.h> // 定义74HC595的引脚 #define SER 11 #define RCLK 10 #define SRCLK 9 // 定义LCD1602的引脚 LiquidCrystal lcd(2, 3, 4, 5, 6, 7); void setup() { // 初始化74HC595引脚 pinMode(SER, OUTPUT); pinMode(RCLK, OUTPUT); pinMode(SRCLK, OUTPUT); // 初始化LCD1602 lcd.begin(16, 2); lcd.print("Hello, world!"); } void loop() { // 向74HC595写入数据 shiftOut(SER, SRCLK, MSBFIRST, 0b00000001); // RS = 1 shiftOut(SER, SRCLK, MSBFIRST, 0b00000010); // RW = 1 shiftOut(SER, SRCLK, MSBFIRST, 0b00000100); // E = 1 shiftOut(SER, SRCLK, MSBFIRST, 0b00001000); // D4 = 1 shiftOut(SER, SRCLK, MSBFIRST, 0b00010000); // D5 = 0 shiftOut(SER, SRCLK, MSBFIRST, 0b00100000); // D6 = 0 shiftOut(SER, SRCLK, MSBFIRST, 0b01000000); // D7 = 0 shiftOut(SER, SRCLK, MSBFIRST, 0b10000000); // 使数据生效 digitalWrite(RCLK, HIGH); digitalWrite(RCLK, LOW); // 显示内容 lcd.setCursor(0, 1); lcd.print("Arduino"); delay(1000); } 3. 运行代码 将Arduino板连接到计算机上,上传代码到Arduino板中。接下来,LCD1602将显示“Hello, world!”和“Arduino”两行文字,每隔1秒钟切换一次。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值