题目
利用定时器产生一个0-99变化秒表,并且显示在数码管上,每过一秒将变化写在板上,当关闭实验板时,再次打开实验板时,继续变化并显示在实验板上,
分析
对于此题,我比较头疼的是,怎么让数码管和i2c之间怎么组合,然后并读出,因此开始时考虑的是断电便可以读出,因此,每次写入时,都应该把读出的数据保存,并且直接读出保存的数据,因此这是第一步,就是直接读出保存的数据,才能保证下一步断电才可以直接读出,接着,就是数码管的显示,数码管的显示如果是shige的话,开始的时候,会出现均为0 的情况,这是不对的,因此必须用从读出的数据来表示出来,就是num/10,num%10,来表示,是最好的方法,而不是shige会出现00的情况,然后展示数码管,在定时器有时需要标志位,当函数很复杂时,是需要标志位的,特别是中断,考虑标志位,因为中断的复杂性,很容易考虑到标志位,然后标志位清0,然后add写入数据,此题关键就是中间的衔接部分不知道怎么写,考虑时注意顺序,
代码
1 # include <reg52.h>
2 # define UCHAR unsigned char
3 # define UINT unsigned int
4 sbit scl = P2^ 1;
5 sbit sda = P2^ 0;
6 sbit dula = P2^ 6;
7 sbit wela = P2^ 7;
8 UCHAR num,i,write;
9 UCHAR code dulai[]=
10 {
11 0x3f, 0x06, 0x5b, 0x4f,
12 0x66, 0x6d, 0x7d, 0x07,
13 0x7f, 0x6f, 0x77, 0x7c,
14 0x39, 0x5e, 0x79, 0x71
15 };
16 void delay()
17 {
18 ;;
19 }
20 void init()
21 {
22 scl = 1;
23 delay();
24 sda = 1;
25 delay();
26 TMOD = 0x01;
27 TH0 = ( 65536- 50000)/ 256;
28 TL0 = ( 65536- 50000)% 256;
29 EA = 1;
30 ET0 = 1;
31 TR0 = 1;
32 }
33
34 void start()
35 {
36 sda = 1;
37 delay();
38 scl = 1;
39 delay();
40 sda = 0;
41 delay();
42 }
43
44 void stop()
45 {
46 sda = 0;
47 delay();
48 scl = 1;
49 delay();
50 sda = 1;
51 delay();
52 }
53
54 void respons()
55 {
56 UCHAR i = 0;
57 scl = 1;
58 delay();
59 while((sda == 1)&&(i< 250))
60 i++;
61 scl = 0; // 第九个时钟拉低
62 delay();
63 }
64
65 void delay1(UCHAR x)
66 {
67 UCHAR y,z;
68 for(y = x;y > 0;y--)
69 for(z = 110;z> 0;z--);
70 }
71
72 void write_byte(UCHAR date)
73 {
74 UCHAR temp,i;
75 temp =date;
76 for(i = 0;i< 8;i++)
77 {
78 temp=temp<< 1;
79 scl = 0;
80 delay();
81 sda = CY;
82 delay();
83 scl = 1;
84 delay();
85 }
86 scl = 0;
87 delay();
88 sda = 1;
89 delay();
90
91 }
92
93 UCHAR read_byte()
94 {
95 UCHAR k,i;
96 scl = 0;
97 delay();
98 sda = 1;
99 delay();
100 for(i = 0;i< 8;i++)
101 {
102 scl = 1;
103 delay();
104 k = k<< 1|sda;
105 delay();
106 scl = 0;
107 delay();
108 }
109 return k;
110 }
111
112 void write_add(UCHAR adress,UCHAR date)
113 {
114 start();
115 write_byte( 0xa0);
116 respons();
117 write_byte(adress);
118 respons();
119 write_byte(date);
120 respons();
121 stop();
122
123 }
124
125 UCHAR read_add(UCHAR address)
126 {
127 UCHAR date;
128 start();
129 write_byte( 0xa0);
130 respons();
131 write_byte(address);
132 respons();
133 start();
134 write_byte( 0xa1);
135 respons();
136 date = read_byte();
137 stop();
138 return date;
139
140
141 }
142 void display(UCHAR shi,UCHAR ge)
143 {
144 wela = 1;
145 P0 = 0xfe;
146 wela = 0;
147 P0 = 0xff;
148 dula = 1;
149 P0= dulai[shi];
150 dula = 0;
151 delay1( 5);
152
153 wela = 1;
154 P0 = 0xfd;
155 wela = 0;
156 P0 = 0xff;
157 dula = 1;
158 P0= dulai[ge];
159 dula = 0;
160 delay1( 5);
161 }
162 void main()
163 {
164 init();
165 num = read_add( 2); // 上去都要读,因为掉电,就是上去就要读出的
166 if(num > 100)
167 num = 0;
168 // delay1(100);
169
170 while( 1)
171 {
172 display(num/ 10,num% 10); // 因为num的原因,如果是shige的话,就会出现开始为0的情况
173 if(write == 1) // write是重点,标志位
174 {
175 write = 0;
176 write_add( 2,num);
177 }
178 }
179 }
180 void timer0 () interrupt 1
181 {
182 TH0 = ( 65536- 50000)/ 256;
183 TL0 = ( 65536- 50000)% 256;
184 i++;
185 if(i == 20)
186 {
187 i = 0;
188 num++;
189 write = 1;
190 if(num == 99)
191 num = 0;
192 }
193 }
2 # define UCHAR unsigned char
3 # define UINT unsigned int
4 sbit scl = P2^ 1;
5 sbit sda = P2^ 0;
6 sbit dula = P2^ 6;
7 sbit wela = P2^ 7;
8 UCHAR num,i,write;
9 UCHAR code dulai[]=
10 {
11 0x3f, 0x06, 0x5b, 0x4f,
12 0x66, 0x6d, 0x7d, 0x07,
13 0x7f, 0x6f, 0x77, 0x7c,
14 0x39, 0x5e, 0x79, 0x71
15 };
16 void delay()
17 {
18 ;;
19 }
20 void init()
21 {
22 scl = 1;
23 delay();
24 sda = 1;
25 delay();
26 TMOD = 0x01;
27 TH0 = ( 65536- 50000)/ 256;
28 TL0 = ( 65536- 50000)% 256;
29 EA = 1;
30 ET0 = 1;
31 TR0 = 1;
32 }
33
34 void start()
35 {
36 sda = 1;
37 delay();
38 scl = 1;
39 delay();
40 sda = 0;
41 delay();
42 }
43
44 void stop()
45 {
46 sda = 0;
47 delay();
48 scl = 1;
49 delay();
50 sda = 1;
51 delay();
52 }
53
54 void respons()
55 {
56 UCHAR i = 0;
57 scl = 1;
58 delay();
59 while((sda == 1)&&(i< 250))
60 i++;
61 scl = 0; // 第九个时钟拉低
62 delay();
63 }
64
65 void delay1(UCHAR x)
66 {
67 UCHAR y,z;
68 for(y = x;y > 0;y--)
69 for(z = 110;z> 0;z--);
70 }
71
72 void write_byte(UCHAR date)
73 {
74 UCHAR temp,i;
75 temp =date;
76 for(i = 0;i< 8;i++)
77 {
78 temp=temp<< 1;
79 scl = 0;
80 delay();
81 sda = CY;
82 delay();
83 scl = 1;
84 delay();
85 }
86 scl = 0;
87 delay();
88 sda = 1;
89 delay();
90
91 }
92
93 UCHAR read_byte()
94 {
95 UCHAR k,i;
96 scl = 0;
97 delay();
98 sda = 1;
99 delay();
100 for(i = 0;i< 8;i++)
101 {
102 scl = 1;
103 delay();
104 k = k<< 1|sda;
105 delay();
106 scl = 0;
107 delay();
108 }
109 return k;
110 }
111
112 void write_add(UCHAR adress,UCHAR date)
113 {
114 start();
115 write_byte( 0xa0);
116 respons();
117 write_byte(adress);
118 respons();
119 write_byte(date);
120 respons();
121 stop();
122
123 }
124
125 UCHAR read_add(UCHAR address)
126 {
127 UCHAR date;
128 start();
129 write_byte( 0xa0);
130 respons();
131 write_byte(address);
132 respons();
133 start();
134 write_byte( 0xa1);
135 respons();
136 date = read_byte();
137 stop();
138 return date;
139
140
141 }
142 void display(UCHAR shi,UCHAR ge)
143 {
144 wela = 1;
145 P0 = 0xfe;
146 wela = 0;
147 P0 = 0xff;
148 dula = 1;
149 P0= dulai[shi];
150 dula = 0;
151 delay1( 5);
152
153 wela = 1;
154 P0 = 0xfd;
155 wela = 0;
156 P0 = 0xff;
157 dula = 1;
158 P0= dulai[ge];
159 dula = 0;
160 delay1( 5);
161 }
162 void main()
163 {
164 init();
165 num = read_add( 2); // 上去都要读,因为掉电,就是上去就要读出的
166 if(num > 100)
167 num = 0;
168 // delay1(100);
169
170 while( 1)
171 {
172 display(num/ 10,num% 10); // 因为num的原因,如果是shige的话,就会出现开始为0的情况
173 if(write == 1) // write是重点,标志位
174 {
175 write = 0;
176 write_add( 2,num);
177 }
178 }
179 }
180 void timer0 () interrupt 1
181 {
182 TH0 = ( 65536- 50000)/ 256;
183 TL0 = ( 65536- 50000)% 256;
184 i++;
185 if(i == 20)
186 {
187 i = 0;
188 num++;
189 write = 1;
190 if(num == 99)
191 num = 0;
192 }
193 }