51单片机+74HC595联级+DS1302简易时钟+Proteus仿真

51单片机+74HC595联级+DS1302简易时钟+Proteus仿真


  • 🎬Proteus仿真演示:
    在这里插入图片描述
本实例主要是实现时钟显示,没有加入按键设置功能,需要其他功能可以自行扩展或者移植使用。

📝实例代码

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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
//ds1302
sbit RST = P1^0;//复位引脚
sbit IO = P1^1; //数据引脚
sbit SCLK = P1^2; //时钟引脚

sbit HC595_DS = P2^7;//DS 串行数据输入引脚
sbit HC595_ST = P2^5; //ST 存储寄存器时钟输入引脚。上升沿时,数据从移位寄存器转存到存储寄存器。
sbit HC595_SH = P2^6; //SH 移位寄存器时钟引脚,上升沿时,移位寄存器中的bit 数据整体后移
//unsigned char code led\_dian[]={0xbF,0x86,0xdB,0xcF,0xe6,0xeD,0xfD,0x87,0xfF,0xeF};//带小数点显示
unsigned char code led_duan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//共阴数码管:0 - 9数字
// unsigned char code led\_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳数码管段码表,0-9段码

unsigned char hour,hour1,hour2;
unsigned char min,min1,min2;
unsigned char sec,sec1,sec2;

void Delay\_Ms(uchar q)
{
uchar p;
while(q--)
{
for(p=0;p<113;p++);
}
}
//数据发送子程序
void send\_595(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(dat&0x80)
HC595_DS = 1;
else
HC595_DS = 0;
HC595_SH = 0;
HC595_SH = 1;
dat = dat<<1;
}
}
//写命令
void write\_byte(uchar date)
{
uchar i;
SCLK = 0;
for(i=0;i<8;i++)
{
SCLK = 0;
IO = date & 0x01;
SCLK = 1;
date >>= 1;
}
}
//写数据
void write\_ds1302(uchar addr,uchar date)
{
uchar num;
RST = 0;
SCLK = 0;
RST = 1;
write\_byte(addr);
num = (date/10<<4)|(date%10);
write\_byte(num);
RST = 0;
SCLK = 1;
}
//读命令
uchar read\_byte()
{
uchar i;
uchar dat = 0x00;
for(i=0;i<8;i++)
{
SCLK = 0;
dat >>= 1;
if(IO)
{
dat |= 0X80;
}

SCLK = 1;
SCLK = 0;
}
return dat;
}
//读数据
uchar read\_ds1302(uchar addr)
{
uchar dat;
uchar dat1;
uchar dat2;

RST = 0;
SCLK = 0;
RST = 1;
write\_byte(addr);
dat = read\_byte();
RST = 0;
SCLK = 1;

dat1 = dat/16;
dat2 = dat%16;
dat = dat1\*10+dat2; //转换为10进制

return dat;
}
//初始化DS1302
void init\_ds1302()
{
write\_ds1302(0x8e,0x00);//WP=0,写保护位清零操作。
//写入年、月、日和星期到DS1302指定寄存器中
write\_ds1302(0x84,23); //时
write\_ds1302(0x82,59); //分
write\_ds1302(0x80,50); //秒

write\_ds1302(0x8e,0x80);//WP=1,开启写保护位。
}
//获取DS1302时间
void get\_time()
{
write\_ds1302(0x8e,0x00);
//从DS1302指定寄存器中读取年、月、日和星期
hour = read\_ds1302(0x85); //时
min = read\_ds1302(0x83); //分
sec = read\_ds1302(0x81); //秒

write\_ds1302(0x8e,0x80);
}

void main()
{
init\_ds1302();
Delay\_Ms(5);
while(1)
{
get\_time();//获取时间
hour1 = hour/10;
hour2 = hour%10;
min1 = min/10;
min2 = min%10;
sec1 = sec/10;
sec2 = sec%10;

send\_595(0xfe);//位选,数码管第一位显示
send\_595(led_duan[hour1]);
HC595_ST = 0; //0->1 上升沿发送。
HC595_ST = 1; //将数据写入到数码管中。

send\_595(0xfd);//位选,数码管第er位显示
send\_595(led_duan[hour2]);
HC595_ST = 0;
HC595_ST = 1;

send\_595(0xfb);//位选,数码管第三位显示
send\_595(0x40);//显示‘-’
HC595_ST = 0;
HC595_ST = 1;

send\_595(0xf7);//位选,数码管第四位显示
send\_595(led_duan[min1]);
HC595_ST = 0;
HC595_ST = 1;

send\_595(0xef);//位选,数码管第五位显示
send\_595(led_duan[min2]);
HC595_ST = 0;
HC595_ST = 1;

send\_595(0xdf);//位选,数码管第六位显示
send\_595(0x40);//显示‘-’
HC595_ST = 0;
HC595_ST = 1;

send\_595(0xbf);//位选,数码管第七位显示
send\_595(led_duan[sec1]);
HC595_ST = 0;
HC595_ST = 1;

send\_595(0x7f);//位选,数码管第八位显示
send\_595(led_duan[sec2]);
HC595_ST = 0;
HC595_ST = 1;
}
}

📚程序源码和仿真资源

1
2
3
链接:https://pan.baidu.com/s/1Og0Z94IsQKQcNJtbqD8G9w 
提取码:ckje