设计要求
实现温湿度传感度的温湿度采集
实现温湿度显示
实时采集两路电压数据,电压范围 0~5V,采集间隔 1 秒按键设置报警温度
能显示时间、学号
实现串口通信
可通过键盘设置数据上传时间间隔(1~9999 秒),切换功能,
系统框图
用的是80C51芯片,基本上定时器、IO口都用完了。这个大作业主要把之前串口通信、adc编制、lcd显示等结合了。
传感器模块
读时序
(1).数据线先置低电平“0”
(2).延时15微秒。
(3).按从低位到高位的顺序发送数据(一次只发送一位)。
(4).延时60微秒。
(5).将数据线拉到高电平。
(6).重复1~5步骤,直到发送完整的字节。
(7).最后将数据线拉高。
写时序
(1).将数据线拉低“0”。
(2).延时1微秒。
(3).将数据线拉高“1”,释放总线准备读数据。
(4).延时10微妙。
(5).读数据线的状态得到1个状态位,并进行数据处理。
(6).延时45微妙。
(7).重复1~7步骤,直到读完一个字节。
传感器就一个DS18B20温度模块,读写根据芯片手册的时序就行,我就直接copy网上的驱动代码了。
uchar ReadOneByte()
{
uchar i,dat=0;
DQ = 1;
_nop_(); //延时一个机器周期的时间
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
_nop_();
_nop_();
if(DQ)
dat |= 0X80;
delay(30);
DQ = 1;
}
return dat;
}
void WriteOneByte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat& 0x01;
delay(5);
DQ = 1;
dat >>= 1;
}
输出到lcd看结果
串口通信
串行口工作之前,应对其进行初始化,主要是设置产生波特率的定时器1、串行口控制和中断控制。
具体步骤如下:
确定T1的工作方式(编程TMOD寄存器);
计算T1的初值,装载TH1、TL1;
启动T1(编程TCON中的TR1位);
确定串行口控制(编程SCON寄存器);
串行口在中断方式工作时,要进行中断设置(编程IE、IP寄存器)。
总的源代码
1. /*************** writer:shopping.w ******************/
2. #include <reg52.h>
3. #include <intrins.h>
4. #define uint unsigned int
5. #define uchar unsigned char
6. #define delayNOP() {_nop_();_nop_();_nop_();_nop_();}
7. typedef unsigned int u16; //对数据类型进行声明定义
8. typedef unsigned char u8;
9. sbit DQ = P2^3;
10. sbit LCD_RS = P2^0;
11. sbit LCD_RW = P2^1;
12. sbit LCD_EN = P2^2;
13. sbit ale=P1^4;
14. sbit k1=P2^4;
15. sbit k2=P2^5;
16. unsigned char h=4,m=1,s=1,mode=1;
17. u16 ssec=0;
18. u16 num;
19. u8 k=1;
20. unsigned char sec;
21. u8 time[]={"Time: "};
22. u8 xuehao[]={"17041121"} ;
23. sbit CLK=P1^5;//时钟信号
24.
25. sbit ST=P1^6;//启动信号
26. sbit OE=P1^7;//输出使能
27. sbit EOC=P1^3;//转换结束信号
28.
29. uchar code Temp_Disp_Title[]={"Current Temp : "};
30. uchar Current_Temp_Display_Buffer[]={" TEMP: "};
31.
32. uchar code Temperature_Char[8] =
33. {
34. 0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00
35. };
36.
37. uchar code df_Table[]=
38. {
39. 0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9
40. };
41.
42. uchar CurrentT = 0;
43. uchar Temp_Value[]={0x00,0x00};
44. uchar Display_Digit[]={0,0,0,0};
45. u8 ti[]={0,0,0,0,0,0};
46. bit DS18B20_IS_OK = 1;
47. void Delay1ms(uint y)
48. {
49. uint x;
50. for( ; y>0; y--)
51. {
52. for(x=110; x>0; x--);
53. }
54. }
55. void delay(u16 i)
56. {
57. while(--i);
58. }
59.
60. u8 KeyScan(u8 mode)
61. {
62. static u8 keyen=1;
63. if(mode==1)
64. {
65. keyen=1;
66. }
67. if(keyen==1&&(k1==0||k2==0))
68. {
69. delay(1000); //消抖处理
70. keyen=0;
71. if(k1==0)return 1;
72. else if(k2==0)return 2;
73.
74. }
75. else if(k1==1&&k2==1)
76. {
77. keyen=1;
78. }
79. return 0;
80. }
81. void DelayXus(uint x)
82. {
83. uchar i;
84. while(x--)
85. {
86. for(i=0;i<200;i++);
87. }
88. }
89.
90.
91. bit LCD_Busy_Check()
92. {
93. bit result;
94. LCD_RS = 0;
95. LCD_RW = 1;
96. LCD_EN = 1;
97. delayNOP();
98. result = (bit)(P0&0x80);
99. LCD_EN=0;
100. return result;
101. }
102.
103. void Write_LCD_Command(uchar cmd)
104. {
105. while(LCD_Busy_Check());
106. LCD_RS = 0;
107. LCD_RW = 0;
108. LCD_EN = 0;
109. _nop_();
110. _nop_();
111. P0 = cmd;
112. delayNOP();
113. LCD_EN = 1;
114. delayNOP();
115. LCD_EN = 0;
116. }
117.
118. void Write_LCD_Data(uchar dat)
119. {
120. while(LCD_Busy_Check());
121. LCD_RS = 1;
122. LCD_RW = 0;
123. LCD_EN = 0;
124. P0 = dat;
125. delayNOP();
126. LCD_EN = 1;
127. delayNOP();
128. LCD_EN = 0;
129. }
130.
131. void LCD_Initialise()
132. {
133. Write_LCD_Command(0x01);
134. DelayXus(5);
135. Write_LCD_Command(0x38);
136. DelayXus(5);
137. Write_LCD_Command(0x0c);
138. DelayXus(5);
139. Write_LCD_Command(0x06);
140. DelayXus(5);
141. }
142.
143. void Set_LCD_POS(uchar pos)
144. {
145. Write_LCD_Command(pos|0x80);
146. }
147.
148.
149.
150. uchar Init_DS18B20()
151. {
152. uchar i;
153. DQ = 0;
154. i=70;
155. delay(i);
156. DQ = 1;
157. i=0;
158. while(DQ)
159. {
160. Delay1ms(1);
161. i++;
162. if(i>5)//等待>5MS
163. {
164. return 0;//初始化失败
165. }
166. }
167. return 1;
168. }
169.
170. uchar ReadOneByte()
171. {
172. uchar i,dat=0;
173. DQ = 1;
174. _nop_(); //延时一个机器周期的时间
175. for(i=0;i<8;i++)
176. {
177. DQ = 0;
178. dat >>= 1;
179. DQ = 1;
180. _nop_();
181. _nop_();
182. if(DQ)
183. dat |= 0X80;
184. delay(30);
185. DQ = 1;
186. }
187. return dat;
188. }
189.
190. void WriteOneByte(uchar dat)
191. {
192. uchar i;
193. for(i=0;i<8;i++)
194. {
195. DQ = 0;
196. DQ = dat& 0x01;
197. delay(5);
198. DQ = 1;
199. dat >>= 1;
200. }
201. }
202.
203. void Read_Temperature()
204. {
205. if(Init_DS18B20()==1)
206. DS18B20_IS_OK=0;
207. else
208. {
209. WriteOneByte(0xcc);
210. WriteOneByte(0x44);
211. Init_DS18B20();
212. WriteOneByte(0xcc);
213. WriteOneByte(0xbe);
214. Temp_Value[0] = ReadOneByte();
215. Temp_Value[1] = ReadOneByte();
216. DS18B20_IS_OK=1;
217. }
218. }
219.
220. void Display_Temperature()
221. {
222. uchar i;
223. uchar t = 150, ng = 0;
224. if((Temp_Value[1]&0xf8)==0xf8)
225. {
226. Temp_Value[1] = ~Temp_Value[1];
227. Temp_Value[0] = ~Temp_Value[0]+1;
228. if(Temp_Value[0]==0x00)
229. Temp_Value[1]++;
230. ng = 1;
231. }
232. Display_Digit[0] = df_Table[Temp_Value[0]&0x0f];
233. CurrentT = ((Temp_Value[0]&0xf0)>>4) | ((Temp_Value[1]&0x07)<<4);
234. Display_Digit[3] = CurrentT/100;
235. Display_Digit[2] = CurrentT%100/10;
236. Display_Digit[1] = CurrentT%10;
237.
238. Current_Temp_Display_Buffer[11] = Display_Digit[0] + '0';
239. Current_Temp_Display_Buffer[10] = '.';
240. Current_Temp_Display_Buffer[9] = Display_Digit[1] + '0';
241. Current_Temp_Display_Buffer[8] = Display_Digit[2] + '0';
242. Current_Temp_Display_Buffer[7] = Display_Digit[3] + '0';
243. if(Display_Digit[3] == 0)
244. Current_Temp_Display_Buffer[7] = ' ';
245. if(Display_Digit[2] == 0&&Display_Digit[3]==0)
246. Current_Temp_Display_Buffer[8] = ' ';
247. if(ng)
248. {
249. if(Current_Temp_Display_Buffer[8] == ' ')
250. Current_Temp_Display_Buffer[8] = '-';
251. else if(Current_Temp_Display_Buffer[7] == ' ')
252. Current_Temp_Display_Buffer[7] = '-';
253. else
254. Current_Temp_Display_Buffer[6] = '-';
255. }
256. Set_LCD_POS(0x00);
257. for(i=0;i<16;i++)
258. {
259. Write_LCD_Data(Temp_Disp_Title[i]);
260. }
261. Set_LCD_POS(0x40);
262. for(i=0;i<16;i++)
263. {
264. Write_LCD_Data(Current_Temp_Display_Buffer[i]);
265. }
266. Set_LCD_POS(0x4d);
267. Write_LCD_Data(0x00);
268. Set_LCD_POS(0x4e);
269. Write_LCD_Data('C');
270. }
271.
272.
273. void Display_Temperature2()
274. {
275. uchar i;
276. ti[0]=h/10;
277. ti[1]=h%10;
278. ti[2]=m/10;
279. ti[3]=m%10;
280. ti[4]=s/10;
281. ti[5]=s%10;
282.
283. time[7]=ti[0]+48;
284. time[8]=ti[1]+48;
285. time[9]=':';
286. time[10]=ti[2]+'0';
287. time[11]=ti[3]+'0';
288. time[12]=':';
289. time[13]=ti[4]+'0';
290. time[14]=ti[5]+'0';
291. Set_LCD_POS(0x00); //写地址
292. for(i=0;i<16;i++)
293. {
294. Write_LCD_Data(time[i]);
295. }
296. Set_LCD_POS(0x40);
297. for(i=0;i<16;i++)
298. {
299. Write_LCD_Data(xuehao[i]);
300. }
301.
302. }
303. void Display_Temperature1()
304. {
305. uchar i;
306. ti[0]=num/100;
307. ti[1]=num/10%10;
308. ti[2]=num%10;
309.
310.
311. time[7]=ti[0]+48;
312. time[8]='.';
313. time[9]=ti[1]+48;
314. time[10]=ti[2]+'0';
315. time[11]='V';
316. time[12]=' ';
317. time[13]=' ';
318. time[14]=' ';
319. time[15]=' ';
320.
321.
322. Set_LCD_POS(0x00); //写地址
323. for(i=5;i<16;i++)
324. {
325. Write_LCD_Data(time[i]);
326. }
327. Set_LCD_POS(0x40);
328. for(i=0;i<16;i++)
329. {
330. Write_LCD_Data(xuehao[i]);
331. }
332.
333. }
334. void Ddelay(uint x)
335. {
336. uchar i;
337. while(x--)
338. {
339. for(i=0;i<120;i++);
340. }
341. }
342. void putc_to_SerialPort(uchar c)
343. {
344. SBUF = c;
345. while(TI == 0);
346. TI = 0;
347. }
348.
349. void puts_to_SerialPort(uchar *s)
350. {
351. while(*s != '\0')
352. {
353. putc_to_SerialPort(*s);
354. s++;
355. Ddelay(5);
356. }
357. }
358. void sel(u8 mode)
359. {
360. switch(mode)
361. {
362. case 1: Read_Temperature();
363.
364.
365. if(DS18B20_IS_OK==1)
366. Display_Temperature();
367. if(s%k==0) {
368. puts_to_SerialPort(Current_Temp_Display_Buffer);
369. puts_to_SerialPort("\r\n---------------------------\r\n"); }
370. break;
371. case 2: Display_Temperature1();
372. if(s%k==0){
373. puts_to_SerialPort(time);
374. puts_to_SerialPort("\r\n---------------------------\r\n"); }
375. break;
376. case 3: Display_Temperature2();break;
377.
378. }
379. }
380.
381.
382. void Timer0Init()
383. {
384. TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
385.
386. TH0=(65536-6000)/256; //给定时器赋初值,定时10ms
387. TL0=(65536-6000)%256;
388. ET0=1;//打开定时器0中断允许
389. EA=1;//打开总中断
390. TR0=1;//打开定时器
391.
392.
393. }
394. void Timer0() interrupt 1
395. {
396. CLK=~CLK;
397. ssec++;
398. if(ssec>=180) //1s
399. {
400. ssec=0;
401. s++;
402. if(s==60)
403. {
404. s=0;
405. m++;
406. if(m==60)
407. {
408. m=0;
409. h++;
410. if(h==24)
411. h==0;
412. }
413. }
414. }
415.
416. }
417.
420. void main()
421. {
422. u8 c = 0;
423. u8 flag=1;
424. LCD_Initialise();
425. Read_Temperature();
426.
427. delay(50000);
428. delay(50000);
429. TMOD=0x20;//T1工作模式2
430. TH0=0x14;
431. TL0=0x00;
432. IE=0x82;
433. TR0=1;
434. P1=0xf8;//选择ADC0809的通道1(0111)(P1.4~P1.6)
435. SCON = 0x40;
436. TMOD = 0x20;
437. TH1 = 0xfd;
438. TL1 = 0xfd;
439. TI = 0;
440. TR1 = 1;
441.
442.
443. while(1)
444. {
447. flag=KeyScan(0);
448. if(flag==2)
449. k++;
450. if(flag==1)
451. {
452. mode++;
453. if(mode==4)
454. mode=1;
455. }
456. ST = 0;
457. ST = 1;
458. ST = 0;
459. while(EOC == 0);
460. OE = 1;
461. num=P3*500.000 / 256;
462. OE = 0;
464. sel(mode);
467. }