找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11375|回复: 8
打印 上一主题 下一主题
收起左侧

单片机+ADC0832+MQ2温度烟雾报警控制PCB原理图+源程序

  [复制链接]
跳转到指定楼层
楼主
大家好:
          偶然翻出上大学时候做的设计,因为篇幅有限,节省时间和资源所以压缩包里边有我归纳总结的心得以及详细的制作流程。
话不多说 ,有图有真相。

1,实物照片









2,Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)






元件清单:
1.    AT89C52
2.    40P底座
3.    8P底座
4.    5MM LED*2(红色、绿色)
5.    3MM LED(黄色)
6.    12M晶振
7.    30P瓷片电容*2
8.    10uf电解电容
9.    10K电阻*2
10.    1K电阻*5
11.    16P液晶底座
12.    103电位器*2
13.    9*15万用板
14.    ADC0832芯片
15.    1602液晶
16.    按键*5
17.    继电器
18.    蜂鸣器
19.    MQ2
20.    MQ2底座
21.    DS18B20
22.    3P圆孔母座
23.    8550三极管
24.    8050三极管
25.    自锁开关
26.    DC电源插口
27.    导线
28.    USB电源线


3整机程序
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include <key.h>
  4. #include "DS18B20.h"   
  5. #define uint unsigned int
  6. #define uchar unsigned char   //宏定义
  7. #define BEEP P3_4    //定义蜂鸣器
  8. #define hujiao P1_3
  9. sbit BEEP=P3^4;
  10. sbit hujiao=P1^3;
  11. sbit RS=P2^5;
  12. sbit RW=P2^6;
  13. sbit EN=P2^7;
  14. sbit led_h=P1^4;
  15. sbit led_l=P1^5;
  16. sbit JDQ=P2^0;
  17. sbit ADCS = P3^7;
  18. sbit ADCLK = P3^5;
  19. sbit ADDI = P3^6;
  20. sbit ADDO = P3^6;
  21. bit shanshuo_st;    //闪烁间隔标志
  22. bit beep_st;     //蜂鸣器间隔标志
  23. bit flag=0;//紧急呼叫标志
  24. sbit DIAN = P2^5;        //小数点
  25. uint abc;
  26. uchar x=4;      //计数器
  27. signed char m;     //温度值全局变量
  28. uchar n;      //温度值全局变量
  29. uchar data disdata[5];
  30. uchar code LEDData[]={0x28,0xeb,0x32,0xa2,0xe1,0xa4,0x24,0xea,0x20,0xa0};
  31. uchar code table[8]={0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00}; // 摄氏温度符号
  32. /*****初始化定时器0*****/
  33. void InitTimer(void)
  34. {
  35. TMOD=0x1;
  36. TH0=0x4c;
  37. TL0=0x00;     //50ms(晶振11.0592M)
  38. }
  39. /*****定时器0中断服务程序*****/
  40. void timer0(void) interrupt 1
  41. {
  42. TH0=0x4c;
  43. TL0=0x00;
  44. x++;
  45. }
  46. /*****读取温度*****/
  47. void check_wendu(void)
  48. {
  49. uint a,b,c;
  50. c=ReadTemperature()-5; //获取温度值并减去DS18B20的温漂误差
  51. a=c/100;     //计算得到十位数字
  52. b=c/10-a*10;    //计算得到个位数字
  53. m=c/10;      //计算得到整数位
  54. n=c-a*100-b*10;    //计算得到小数位
  55. if(m<0){m=0;n=0;}   //设置温度显示上限
  56. if(m>99){m=99;n=9;}   //设置温度显示上限   
  57. }
  58. /*************************lcd1602程序**************************/
  59. void delay1ms(uint ms)//延时1毫秒(不够精确的)
  60. {  uint i,j;
  61.    for(i=0;i<ms;i++)
  62.     for(j=0;j<100;j++);
  63. }
  64. unsigned char rolmove(unsigned  char m)
  65. {
  66.   
  67.   unsigned char   a,b,c,d,e,f,g,h;               
  68. a=(m&0x01)<<7;
  69. b=(m&0x02)<<5;
  70. c=(m&0x04)<<3;
  71. d=(m&0x08)<<1;
  72. e=(m&0x10)>>1;
  73. f=(m&0x20)>>3;
  74. g=(m&0x40)>>5;
  75. h=(m&0x80)>>7;
  76. m=a|b|c|d|e|f|g|h;
  77. return m;
  78. }
  79. void wr_com(uchar com)//写指令//
  80. { delay1ms(1);
  81.    RS=0;
  82.    RW=0;
  83.    EN=0;
  84.    P0=rolmove(com);
  85.    delay1ms(1);
  86.    EN=1;
  87.    delay1ms(1);
  88.    EN=0;
  89. }
  90. void wr_dat(uchar dat)//写数据//
  91. { delay1ms(1);;
  92.    RS=1;
  93.    RW=0;
  94.    EN=0;
  95.    P0=rolmove(dat);
  96.    delay1ms(1);
  97.    EN=1;
  98.    delay1ms(1);
  99.    EN=0;
  100. }
  101. void wr_new()    //写新字符
  102. {
  103. uchar i;
  104. wr_com(0x40);
  105. for(i=0;i<8;i++)
  106. {
  107.   wr_dat(table[i]);
  108. }
  109. }
  110. void lcd_init()//初始化设置//
  111. { delay1ms(15);
  112. wr_com(0x38);delay1ms(5);
  113. wr_com(0x08);delay1ms(5);
  114. wr_com(0x01);delay1ms(5);
  115.   wr_com(0x06);delay1ms(5);
  116. wr_com(0x0c);delay1ms(5);
  117. wr_new();
  118. wr_com(0x80);
  119.     wr_dat('S');//A
  120. wr_com(0x81);
  121.     wr_dat('m');//:
  122.    wr_com(0x82);
  123.     wr_dat('o');
  124.    wr_com(0x83);
  125.     wr_dat('k');
  126. wr_com(0x84);
  127.     wr_dat('e');
  128.    wr_com(0x85);
  129.     wr_dat(':');
  130.    wr_com(0x87);
  131.     wr_dat('T');
  132. wr_com(0x88);
  133.     wr_dat('e');
  134.    wr_com(0x89);
  135.     wr_dat('m');
  136.    wr_com(0x8a);
  137.     wr_dat(':');
  138. wr_com(0x8d);
  139.     wr_dat('.');
  140. wr_com(0x8f);
  141.     wr_dat('C');
  142.    
  143. wr_com(0xc0);
  144.     wr_dat('A');
  145. wr_com(0xc1);
  146.     wr_dat('l');
  147. wr_com(0xc2);
  148.     wr_dat('a');
  149.    wr_com(0xc3);
  150.     wr_dat('r');
  151. wr_com(0xc4);
  152.     wr_dat('m');
  153. wr_com(0xc5);
  154.     wr_dat(':');
  155. wr_com(0xcb);
  156.     wr_dat('-');
  157.    wr_com(0xce);
  158.     wr_dat('C');   
  159. }
  160. /*****************显示函数******************************/
  161. void disp()//温度值显示
  162. {
  163.      disdata[0]=m/10+0x30;//十位数
  164.      disdata[1]=m%10+0x30;//个位数
  165.      disdata[2]=n+0x30;//小数位
  166.      disdata[3]=abc+0x30;//烟雾浓度
  167.     wr_com(0x8b);
  168.     wr_dat(disdata[0]);//显示十位
  169.     wr_com(0x8c);
  170.     wr_dat(disdata[1]);//显示个位
  171.     wr_com(0x8e);
  172.     wr_dat(disdata[2]);//显示小数位
  173.     wr_com(0x86);
  174.     wr_dat(disdata[3]);
  175. }
  176. void baojing()
  177. {
  178. wr_com(0xc9);
  179.     wr_dat(tab[0]+0x30);
  180. wr_com(0xca);
  181.     wr_dat(tab[1]+0x30);
  182. wr_com(0xcc);
  183.     wr_dat(tab[2]+0x30);
  184. wr_com(0xcd);
  185.     wr_dat(tab[3]+0x30);
  186. wr_com(0xc6);
  187.     wr_dat(tab[4]+0x30);
  188. }
  189. /*****报警子程序*****/
  190. void Alarm()
  191. {
  192. if((m>=shangxian&&beep_st==1)||(m<xiaxian&&beep_st==1))BEEP=1;
  193. else if(abc>=nongdu&&beep_st==1) BEEP=1;
  194. else BEEP=0;
  195. if(m>=shangxian||m<xiaxian) {led_h=0;led_l=1;JDQ=0;}
  196. else if(abc>=nongdu) {led_h=0;led_l=1;JDQ=0;}
  197. else {led_h=1;led_l=0;JDQ=1;}
  198. if(x>=10){beep_st=~beep_st;x=0;}
  199. }
  200. void Alarm1()
  201. {
  202. led_h=0;
  203. led_l=1;
  204. if(x>=10){beep_st=~beep_st;x=0;}
  205. if(beep_st==1)BEEP=1;
  206. else BEEP=0;
  207. led_h=0;
  208. led_l=1;
  209. JDQ=0;
  210. }
  211. uchar ADC0832(bit mode,bit channel)     //AD转换,返回结果
  212. {
  213. uchar i,dat,ndat;

  214. ADCS = 0;//拉低CS端
  215. _nop_();
  216. _nop_();

  217. ADDI = 1; //第1个下降沿为高电平
  218. ADCLK = 1;//拉高CLK端
  219. _nop_();
  220. _nop_();
  221. ADCLK = 0;//拉低CLK端,形成下降沿1
  222. _nop_();
  223. _nop_();

  224. ADDI = mode; //低电平为差分模式,高电平为单通道模式。
  225. ADCLK = 1;//拉高CLK端
  226. _nop_();
  227. _nop_();
  228. ADCLK = 0;//拉低CLK端,形成下降沿2
  229. _nop_();
  230. _nop_();

  231. ADDI = channel; //低电平为CH0,高电平为CH1
  232. ADCLK = 1;//拉高CLK端
  233. _nop_();
  234. _nop_();
  235. ADCLK = 0;//拉低CLK端,形成下降沿3

  236. ADDI = 1;//控制命令结束(经试验必需)
  237. dat = 0;
  238. //下面开始读取转换后的数据,从最高位开始依次输出(D7~D0)
  239. for(i = 0;i < 8;i++)
  240. {
  241.   dat <<= 1;
  242.   ADCLK=1;//拉高时钟端
  243.   _nop_();
  244.   _nop_();
  245.   ADCLK=0;//拉低时钟端形成一次时钟脉冲
  246.   _nop_();
  247.   _nop_();
  248.   dat |= ADDO;
  249. }
  250. ndat = 0;     //记录D0
  251. if(ADDO == 1)
  252. ndat |= 0x80;
  253. //下面开始继续读取反序的数据(从D1到D7)
  254. for(i = 0;i < 7;i++)
  255. {
  256.   ndat >>= 1;
  257.   ADCLK = 1;//拉高时钟端
  258.   _nop_();
  259.   _nop_();
  260.   ADCLK=0;//拉低时钟端形成一次时钟脉冲
  261.   _nop_();
  262.   _nop_();
  263.   if(ADDO==1)
  264.   ndat |= 0x80;
  265. }   
  266. ADCS=1;//拉高CS端,结束转换
  267. ADCLK=0;//拉低CLK端
  268. ADDI=1;//拉高数据端,回到初始状态
  269. if(dat==ndat)
  270. return(dat);
  271. else
  272. return 0;   
  273. }
  274. /*****主函数*****/
  275. void main(void)
  276. {
  277. InitTimer();    //初始化定时器
  278. EA=1;      //全局中断开关
  279. TR0=1;
  280. ET0=1;      //开启定时器0
  281. BEEP=0;
  282. led_h=1;
  283. led_l=1;
  284. JDQ=1;
  285. check_wendu();
  286. check_wendu();
  287. lcd_init();//初始化显示
  288. delay1ms(100);
  289. lcd_init();//初始化显示
  290. delay1ms(100);
  291. while(1)
  292. {
  293. if(hujiao==0)
  294. {
  295.    Delay(2000);
  296.    do{}while(hujiao==0);
  297.    flag=~flag;
  298. }
  299. checkkey();
  300.   abc = ADC0832(1,0);  //差分模式,CH0-CH1
  301.   abc = abc*19.607843; //转换为实际电压便于显示
  302.   abc=abc/1000%10;
  303.     check_wendu();
  304. disp();
  305. baojing();
  306. if(flag==1){Alarm1();JDQ=0;}
  307. else    Alarm();   //报警检测
  308. if(set_st==0) wr_com(0x0c);
  309. if(set_st==1)
  310. {
  311. wr_com(0xc6);
  312. wr_com(0x0d);
  313. delay1ms(150);
  314. }
  315. if(set_st==2)
  316. {
  317. wr_com(0xca);
  318. wr_com(0x0d);
  319. delay1ms(150);
  320. }
  321. if(set_st==3)
  322. {
  323. wr_com(0xcd);
  324. wr_com(0x0d);
  325. delay1ms(150);
  326. }
  327. }
  328. }/*****END*****/
复制代码

全部资料51hei下载地址:
单片机温度烟雾控制器设计(液晶版).7z (1.45 MB, 下载次数: 437)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏11 分享淘帖 顶1 踩
回复

使用道具 举报

来自 2#
ID:262 发表于 2022-2-27 18:25 | 只看该作者
2933367366 发表于 2022-2-27 13:04
不知道什么原因,仿真图没结果,1602不显示任何东西

楼主用的是Proteus7.5版本的仿真软件  我帮你转成了Proteus8.8版本的你用8.8打开就可以了

51hei.gif (118.32 KB, 下载次数: 35)

51hei.gif

Proteus8.8版本.7z

24.91 KB, 下载次数: 50, 下载积分: 黑币 -5

回复

使用道具 举报

板凳
ID:456792 发表于 2019-10-22 20:07 | 只看该作者
楼主继电器是什么封装的 感谢分享
回复

使用道具 举报

地板
ID:599674 发表于 2019-10-25 11:12 | 只看该作者
感谢楼主的分享
回复

使用道具 举报

5#
ID:640274 发表于 2019-11-19 11:56 | 只看该作者
感谢分享
回复

使用道具 举报

6#
ID:758176 发表于 2020-7-10 10:08 | 只看该作者
谢谢楼主 可真是太棒了呢!
回复

使用道具 举报

7#
ID:826327 发表于 2020-10-6 19:43 | 只看该作者
请问这个还可以再有一个输出给esp8266吗
回复

使用道具 举报

8#
ID:833323 发表于 2020-11-10 16:32 | 只看该作者
液晶屏改为2004的或者12864的咋改,求告知
回复

使用道具 举报

9#
ID:792989 发表于 2022-2-27 13:04 | 只看该作者
不知道什么原因,仿真图没结果,1602不显示任何东西
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表