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

发布者:心想的45号最新更新时间:2018-05-07 来源: eefocus关键字: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

#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;

}

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


关键字:74HC595  LCD1602  串行数据接口 引用地址:用 74HC595 把 LCD1602 改成串行数据接口

上一篇:PWM --真正的流水灯
下一篇:PWM --呼吸灯

推荐阅读最新更新时间:2024-03-16 16:01

AVRWARE++开发笔记7:74HC595串行控制LED灯实验
本文只针对于初学者,高手请绕过! 1、实验目的 利用单片机的IO口模拟SPI总线时序逻辑,通过74HC595控制24个LED,学会74HC595串行控制的使用方法。 2、实验内容 编写一段程序,使24个LED先全亮,然后以一秒为间隔从左至右的一列接一列的熄灭。 3、硬件原理 74HC595串行控制LED灯硬件原理图如下图所示,使用排线与端子P3相连,则单片机相应端口的0-2引脚与端子P3的CS_595_1、CLK_595_1、Data_595_1引脚相连接(例如,使用排线将P9与P3端子相连接,则PC0引脚接CS_595_1,PC1引脚接CLK_595_1,PC2引脚接Data_595_1)。C
[单片机]
AVRWARE++开发笔记7:<font color='red'>74HC595</font><font color='red'>串行</font>控制LED灯实验
LCD1602自定义字符的方法
LCD1602内含有八个自定义的字符空间,用户可以根据需要设置自定义字符,不过字符的像素通常是5X7。如果需要更大像素的字符,就只能用多个5X7的字符拼合。每个自定义字符的字节有8个,最后一个是0x00;每个字节的高3位为0,即000? ????。自定义字符设置与应用步骤如下: 1、设置自定义字符的代码并存入数组。每个字符分7行,每行有5个像素,如果需要显示,此位设定为1,否则为0。本人用VBA制作了《LCD1602自定义字符生成器》,使用简单,需要可函索。联系:51hei.com 2、按常规方法初始化LCD1602。 3、写命令:40H。 4、写数据:将代码数组写入LCD1602中的CGRAM中。 5、按常
[单片机]
LCD1602液晶显示器 C51模块化程序+电路图
下面是51单片机驱动1602液晶的电路图: 程序一共有3个文件: /********************** lcd.h 头文件 **********************/ #ifndef _LCD_H_ #define _LCD_H_ #include reg51.h extern void lcd_init(); extern void lcd_busy(); extern void lcd_write_dat(unsigned char dat); extern void lcd_write_com(unsigned char dat); extern void lcd_xy(unsigned char x,
[单片机]
<font color='red'>LCD1602</font>液晶显示器 C51模块化程序+电路图
一种嵌入式数字语音录放系统的设计
随着我国经济建设的迅猛发展, 公安、铁路、民航、金融等部门对语音记录的需求不断增长。把语音生成技术应用于工业监控系统、自动应答系统、多媒体查询系统、智能化仪表、办公自动化系统或家用电气产品中,使它们具有语音输出功能, 使之能在适当的时候用语音实时报告系统的工作状态、警告信息、提示信息或相关的解释说明等, 无疑在提高人机通信能力、减少对错误处理的遗漏、提高系统性能、减轻人们的工作强度等方面都有极大的好处。 数字录音系统是将现场的语音模拟信号转变为离散的数字信号, 然后存储在一定的存储介质上的一种录音方式,它也是数字语音处理技术中常用的一种方式。采用嵌入式数字录音技术具有较高的效率和自动化程度, 而且录音时间长, 并可将信息长期保存
[单片机]
一种嵌入式数字语音录放系统的设计
AVR的SPI驱动74HC595测试程序
#include avr/io.h #define uchar unsigned char #define uint unsigned int #define lat_on PORTB|=0x10 #define lat_off PORTB&=0xe0 void spi_init(void) { SPCR=0x70; SPSR=0X01; } void spi_send(uchar dd) { SPDR=dd; while(0==(SPSR&0X80)); } int main(void) { DDRB=0xff; PORTB=0XFF; spi_init(); lat_off; spi_send(0x92); spi_send
[单片机]
51单片机LED点阵实验(74HC595
实验目的:用8*8的LED点阵显示一颗爱心。 实验仪器:普中开发板(非广告) 实验背景:出于一些原因,最近在看Arduino,但仍觉得51好玩。遂,一边看Arduino,一边整理51。 8*8的LED点阵电路如图一所示,有两种方式。单片机上集成的电路方式为第二种。 其中,行由P0口控制,列由D7~D0(HC595芯片控制,见下方)控制。 图一 首先考虑,如何先点亮一个灯? eg:让P0^7的端口为低电平,P0的其他端口为高电平;D7的端口为高电平,则第一行第一列的led被点亮。 同样的方式也可以,让其他单独的led点亮。 接着考虑,如何控制多个led的点亮? 类似与数码管的动态显示,利用余晖来进
[单片机]
51单片机LED点阵实验(<font color='red'>74HC595</font>)
51单片机(STC89C52RC) lcd1602实验小结
  lcd1602是自带控制器的液晶显示模块,能够显示两行点阵数据,其引脚参数请google之. 在实际使用的时候碰到的现象:   第1行黑块,第2行空白,是1602本身上电复位成功的标志。意味着单片机根本没有进行初始化,需要检查电路.   如果碰到两行都是现实黑块,那么就是意味着初始化不正常,需要尝试使用更长的延时功能,确保数据不丢失.   仿真的时候是可以写入并显示数据的,并且检查电路连线没有问题,开始的时候碰到上述两种任意一种,但是写入数据后屏幕什么也米有了. 能够碰到上述的现象的任意一种的时候,就需要调节对比度端口,数据有可能已经写入了,只是没有显示出来,经实验证实,带背光的1602 lcd在上电复位的
[单片机]
LCD1602动态显示--基于MSP430F149单片机
main.c /*************************************************** 程序功能:动态显示文字“welcome!” ---------------------------------------------------- 测试说明:观察液晶显示 ****************************************************/ #include msp430.h #include Cry1602.h #define uchar unsigned char uchar *s1 = welcome! ; void main( void ) {
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多精选电路图
换一换 更多 相关热搜器件
更多每日新闻
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved