【Proteus仿真】51单片机+LCD1602+74HC164驱动显示

【Proteus仿真】51单片机+LCD1602+74HC164仅用2个IO驱动显示


  • 🌼Proteus效果展示:
    在这里插入图片描述在这里插入图片描述
  • 🛠也可以通过两个数据输入端(DSA和DSB)的逻辑与接一起再和和数据输出端Q5逻辑与实现
    在这里插入图片描述
  • 🌿74hc164时序图
    在这里插入图片描述
  • 📝main主程序代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "lcd1602.h"


void main()
{
LCD1602\_Init();//LCD1602初始化
LCD1602\_write\_str("Hello World");
LCD1602\_Write\_Data(0,0xc0); //切换到第二行显示
LCD1602\_write\_str("Perseverance51");
LCD1602\_delay\_ms(2000);
// LCD\_Clear();//清屏函数
while(1)
{

}
}

  • lcd1602.c代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "lcd1602.h"

//LCD1602初始化使用延时
void Delay100us()
{
unsigned char i;
\_nop\_();
i = 47;
while (--i);
}
//LCD1602写入数据或指令
//0指令,1数据
void LCD1602\_Write\_Data(bit CD,u8 dat)
{
u8 i;
//先传输高4位
//第一步,低电平
for(i=0;i<6;i++)
{
HC164_CP=0;
HC164_DI=0;//先传输最高位;
HC164_CP=1;
}

HC164_CP=0;
HC164_DI=1;//E高电平
HC164_CP=1;

HC164_CP=0;
HC164_DI=CD;//传输命令位
HC164_CP=1;

for(i=0;i<4;i++)//传输数据高4位
{
HC164_CP=0;
HC164_DI=dat&0x80;//先传输最高位;
HC164_CP=1;
dat<<=1;//次高位左移到最高位
}
HC164_DI=1;HC164_DI=0;//LCD1602吸收数据
//如果DI=0;那么此时DI=1;DI=0即可
//如果DI=1;那么DI=0即可

//传输低4位数据,操作同上
for(i=0;i<6;i++)
{
HC164_CP=0;
HC164_DI=0;
HC164_CP=1;
}

HC164_CP=0;
HC164_DI=1;//E高电平
HC164_CP=1;

HC164_CP=0;
HC164_DI=CD;//传输命令位
HC164_CP=1;

//这里的移位可以接着传输
for(i=0;i<4;i++)//传输低4位数据
{
HC164_CP=0;
HC164_DI=dat&0x80;//先传输高位;
HC164_CP=1;
dat<<=1;//次高位左移到最高位
}
HC164_DI=1;HC164_DI=0;//LCD1602吸收数据
}
//\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
//MS延时函数(12M晶振下测试)
//\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
void LCD1602\_delay\_ms(unsigned int n)
{
unsigned int i,j;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}

void LCD1602\_Init()//LCD1602初始化
{

LCD1602\_Write\_Data(0,0x02);//光标复位
LCD1602\_delay\_ms(1);
LCD1602\_Write\_Data(0,0x28);//四位总线,双行显示
LCD1602\_delay\_ms(1);
LCD1602\_Write\_Data(0,0x01);//清除显示
LCD1602\_delay\_ms(1);
LCD1602\_Write\_Data(0,0x06);//光标移动方向
LCD1602\_delay\_ms(1);
LCD1602\_Write\_Data(0,0x0c);//整体显示开,无光标
LCD1602\_delay\_ms(1);
LCD1602\_Write\_Data(0,0x14);//光标随着字右移
LCD1602\_delay\_ms(1);

}
/\*------------------------------------------------
清屏函数
------------------------------------------------\*/
void LCD\_Clear(void)
{
LCD1602\_Write\_Data(0,0x01);

}
/\*------------------------------------------------
写入字符函数
------------------------------------------------\*/
void LCD\_Write\_Char(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0)
{
LCD1602\_Write\_Data(0,0x80 + x); //第一行显示
}
else
{
LCD1602\_Write\_Data(0,0xC0 + x); //第二行显示
}
LCD1602\_Write\_Data(1,Data);
}
//\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
//连续写字符
//\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
void LCD1602\_write\_str(unsigned char \*s)
{
while(\*s>0)
{
LCD1602\_Write\_Data(1,\*s);
s++;
}
}




  • lcd1602.h代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef \_\_LCD1602\_H\_\_
#define \_\_LCD1602\_H\_\_

#include <REGX52.H>
#include <intrins.h>

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;


sbit HC164_DI=P2^1;//数据引脚
sbit HC164_CP=P2^0;//时钟引脚


void LCD1602\_delay\_ms(unsigned int n);
void LCD1602\_Init();//LCD1602初始化
void LCD1602\_Write\_Data(bit CD,u8 dat);
void LCD\_Write\_Char(unsigned char x,unsigned char y,unsigned char Data);
void LCD1602\_write\_str(unsigned char \*s);//字符串显示
void LCD\_Clear(void) ;//清屏函数

#endif

📚程序源码和仿真资源

  • 基于Proteus8.12平台
1
2
3
链接:https://pan.baidu.com/s/1I7BNFZGxCnmAesRfxecwgA 
提取码:9wmw