找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机多点温度控制程序和仿真

[复制链接]
跳转到指定楼层
楼主
51单片机做的一个ds18b20多点温度控制程序源码和proteus仿真


仿真工程文件和源码打包下载:
单片机多点温度控制系统.zip (92.29 KB, 下载次数: 49)

单片机源程序:
  1. //采用12MHz晶振
  2. #include<AT89X51.h>
  3. #define uchar unsigned char
  4. #define FALSE 0;
  5. #define TRUE 1;      
  6. sbit DQ =P3^0;//B20选择
  7. sbit button1=P1^0;//定义通信端口
  8. sbit button2=P1^1;//显示选择按钮
  9. sbit button3=P1^2;//位选端
  10. sbit button4=P1^3;//加1
  11. unsigned char ROM[8];//ROM位 最前面是lsb
  12. unsigned char FoundROM[3][8];//ROM代码表
  13. unsigned char lastDiscrep=0; //上次差值
  14. unsigned char doneFlag=0;         //完成标志
  15. unsigned int numROMs;                 //DS18B20个数
  16. unsigned char dowcrc;                 //crc校验值
  17. unsigned char DS_key=0;
  18. uchar code LED[] ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//0123456789
  19. uchar code LED1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0x00};//0-9的带小数点的段选码
  20. uchar code tab[] ={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//P2选通数组
  21. int temperature[2][11]={0x00,0x00,0x00,0x06,0x05,0x04,0x03,0x02,0x01,0x0a,0x00,
  22.                                                 //十分 个        十        高温                   低温
  23.                                                  0x00,0x00,0x00,0x05,0x05,0x04,0x02,0x02,0x01,0x0a,0x00
  24.                                                 }; //温度缓存数组
  25. uchar data con=0x00,conk1=0x00;conk2=0x00,cont0=0x00,cont1=0x00;
  26. //crc校验表
  27. uchar code dscrc_table[]={0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
  28.                            157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
  29.                            35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
  30.                            190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
  31.                            70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
  32.                            219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
  33.                            101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
  34.                            248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
  35.                            140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
  36.                            17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
  37.                            175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
  38.                            50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
  39.                            202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
  40.                            87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
  41.                            233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
  42.                            116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53
  43.                           };
  44. void delay(unsigned int i);
  45. unsigned char Init_DS18B20(void);
  46. unsigned char Read_One_bit(void);
  47. unsigned char Read_One_byte(void);
  48. void Write_One_bit(char bitval);
  49. void Write_One_byte(unsigned char dat);
  50. unsigned char ow_crc(unsigned char x);
  51. //void Read_Rom_Code(void);                                
  52. unsigned char Next(void);
  53. unsigned char First(void);
  54. void Find_Devices(void);
  55. unsigned char Send_Match_Rom(unsigned char DS_number);
  56. void Read_Temperature(unsigned char number);
  57. void Key_scan(void);
  58. void DS_Key_scan(void);
  59. void Show_Temp(void);
  60. void Compare(void);
  61. //延时函数
  62. void delay(unsigned int i)//9us延迟,调用此程序4us
  63. {
  64.         while(i--);
  65. }
  66. //初始化函数
  67. unsigned char Init_DS18B20(void)
  68. {        
  69.         unsigned char presence;
  70.         DQ=1; //DQ复位
  71.         delay(8);   //稍做延时
  72.         DQ=0; //单片机将DQ拉低
  73.         delay(80); //精确延时 大于 480us
  74.         DQ=1; //拉高总线
  75.         delay(5);
  76.         presence=DQ;    //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  77.         delay(15);
  78.         return(presence);
  79. }
  80. //读一个位
  81. unsigned char Read_One_bit(void)
  82. {
  83.         uchar i;
  84.         DQ=0;
  85.         DQ=1;
  86.         for(i=0;i<3;i++); //延迟15微妙
  87.         return(DQ);
  88. }
  89. //读一个字节
  90. unsigned char Read_One_byte(void)        
  91. {
  92.         unsigned char i=0;
  93.         unsigned char dat = 0;
  94.         for (i=0;i<8;i++)
  95.         {
  96.             if(Read_One_bit())
  97.                 dat|=0x01<<i;
  98.                 delay(9);
  99.         }
  100.         return(dat);
  101. }
  102. //写一个位
  103. void Write_One_bit(char bitval)        
  104. {
  105.         DQ=0;
  106.         if(bitval==1)
  107.         DQ=1;
  108.         delay(5);
  109.         DQ=1;
  110. }
  111. //写一个字节
  112. void Write_One_byte(unsigned char dat)         
  113. {
  114.         unsigned char i;
  115.         unsigned char temp;
  116.         for (i=0; i<8; i++)
  117.         {
  118.                    temp=dat>>i;
  119.                    temp&=0x01;
  120.                    Write_One_bit(temp);
  121.            }
  122.         delay(9);
  123. }
  124. //crc校验函数
  125. unsigned char ow_crc(unsigned char x)
  126. {
  127.     dowcrc=dscrc_table[dowcrc^x];
  128.         return dowcrc;
  129. }
  130. /*
  131. //读取单总线上的单个DS18B20的ROM,对于多个器件采用搜索ROM
  132. void Read_Rom_Code(void)
  133. {
  134.          int n;

  135.         if(!Init_DS18B20())
  136.         {
  137.         delay(20);
  138.          Write_One_byte(0x33);
  139.          for(n=0;n<8;n++)
  140.          {
  141.                  ROM[n]=Read_One_byte();
  142.          }
  143.         }
  144. }
  145. */
  146. //搜索单总线上的下一个器件,如果没有则返回假
  147. unsigned char Next(void)
  148. {
  149.         unsigned char m=1;
  150.         unsigned char n=0;
  151.         unsigned char k=1;
  152.         unsigned char x=0;
  153.         unsigned char discrepMaker=0;                //搜索定位到一个B20的标志位
  154.         unsigned char g;
  155.         unsigned char nxt;
  156.         int flag;
  157.         nxt=FALSE;
  158.         dowcrc=0;
  159.         flag=Init_DS18B20();
  160.         if(flag||doneFlag) //无器件,返回假值
  161.         {
  162.                  lastDiscrep=0;
  163.                  return FALSE;
  164.         }
  165.         Write_One_byte(0xf0);
  166.          do        
  167.         {
  168.             x=0;
  169.             if(Read_One_bit()==1) x=2;                                        //10 都为1
  170.               delay(10);                                                                //01 都为0
  171.             if(Read_One_bit()==1) x|=1;                                        //00 存在两个以上,第一位不相等
  172.             delay(10);                                                                //11 没有器件
  173.             if(x==3) break;
  174.               else
  175.                 {
  176.                      if(x>0) g=x>>1;                                                  //x=1或x=2
  177.                      else
  178.                         {                                                                          //x=0
  179.                                    if(m<lastDiscrep) g=((ROM[n]&k)>0);
  180.                                    else g=(m==lastDiscrep);
  181.                                    if(g==0) discrepMaker=m;
  182.                      }
  183.                 if(g==1) ROM[n]|=k;                //写1
  184.                 else ROM[n]&=~k;                        //写0
  185.                 Write_One_bit(g);
  186.                         delay(10);
  187.                 m++;
  188.                 k=k<<1;                                   //k循环右移1位,
  189.                 if(k==0)
  190.                 {
  191.                          ow_crc(ROM[n]);
  192.                          n++;k++;
  193.                 }         
  194.         }
  195.    }while(n<8);
  196.     if(m<65||dowcrc) lastDiscrep=0;        //搜索未成功
  197.     else
  198.         {                                                        //搜索成功,置各个标志位,返回还有其他器件,
  199.             lastDiscrep=discrepMaker;         
  200.                 doneFlag=(lastDiscrep==0);        //完成置1
  201.                 nxt=TRUE;
  202.      }
  203.         return(nxt);
  204. }
  205. //复位当前ROM搜索状态并调用Next函数搜索单总线的第一个器件
  206. unsigned char First(void)
  207. {
  208.         lastDiscrep=0;
  209.         doneFlag=FALSE;
  210.         return Next();
  211. }
  212. //复位单总线以确定是否存在任何器件,如果存在将其唤醒,然后调用First函数跟踪冲突位
  213. //并返回Next函数,Next函数完成鉴别单总线上的每个器件唯一ROM代码的大部分工作
  214. void Find_Devices(void)
  215. {
  216.         unsigned char m;
  217.         if(!Init_DS18B20())
  218.         {
  219.             if(First())
  220.                 {
  221.                     numROMs=0;
  222.                           do{
  223.                             for(m=0;m<8;m++)
  224.                                 {
  225.                                     FoundROM[numROMs][m]=ROM[m];
  226.                         }
  227.                           numROMs++;
  228.                                  }while(Next()&&(numROMs<4));                                   //两个B20
  229.                 }
  230.         }
  231.   }
  232. //匹配单个DS18B20
  233. unsigned char Send_Match_Rom(unsigned char DS_number)
  234. {
  235.         unsigned char i;
  236.         if(Init_DS18B20())
  237.         return FALSE;
  238. //        delay(20);
  239.         Write_One_byte(0x55);
  240.         for(i=0;i<8;i++)
  241.         {
  242.             Write_One_byte(FoundROM[DS_number][i]);
  243.         }
  244.         return TRUE;
  245. }
  246. //读取温度
  247. void Read_Temperature(unsigned char number)
  248. {        
  249.         unsigned char fu;
  250.         float m;
  251.         unsigned char temp_lsb=0;
  252.         unsigned char temp_msb=0;
  253.         unsigned int temp_value=0;
  254.         int show,n;
  255.         Init_DS18B20();     //初始化函数DS18B20
  256.         Send_Match_Rom(number);//匹配ROM
  257. //        Write_One_byte(0xCC); // 跳过读序号列号的操作
  258.         Write_One_byte(0x44); // 启动温度转换
  259.         Init_DS18B20();
  260.         Send_Match_Rom(number);//匹配ROM
  261. //        Write_One_byte(0xCC); //跳过读序号列号的操作
  262.         Write_One_byte(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  263.         temp_lsb=Read_One_byte();        //温度lsb
  264.         temp_msb=Read_One_byte();        //温度msb
  265.         temp_value=temp_msb;
  266.         temp_value<<=8;                                 //左移8位
  267.         temp_value=temp_value|temp_lsb;
  268.         fu=temp_msb;
  269.         fu=fu&0x08;
  270.         if(fu!=0)                        //判断正负
  271.            {temp_value=~temp_value+1;}
  272.         m=temp_value*0.0625;                 //将十进制m向左移动4个小数点
  273.         show=m;
  274.         temperature[number][2]=show/10;//十位
  275.     temperature[number][1]=show%10;//个位
  276.         n=((m-show)*100+0.5);
  277.         temperature[number][0]=n/10;//十分位
  278.         }
  279. //按钮扫描
  280. void DS_Key_scan(void)
  281. {
  282.         EA=0;
  283.         if(conk2==0)
  284.         {
  285.                 if(button2==0) //按键1
  286.                 {
  287.                      delay(1000);  //延迟9毫秒,消抖延迟
  288.                         while(button2==0);
  289.         //                TR1=0;ET1=0;TH1=0x3c;TL1=0xB0;
  290.         //                TR1=1;ET1=1;
  291.                          con=con+3;                                 
  292.                          if(con==9)
  293.                          con=0;
  294.                 }
  295.            }
  296.         
  297.         if(con!=0)         //按键2
  298.         {
  299.                 if(con==3||con==6)
  300.                 {
  301.                            if(button3==0)                              
  302.                         {
  303.                                 delay(1000);  //消抖延迟
  304.                                   while(button3==0);
  305.                                   if(temperature[DS_key][con+conk1]==0x0a)
  306.                         {
  307.                                     temperature[DS_key][10]=temperature[DS_key][con+conk1];
  308.                                     temperature[DS_key][con+conk1]=temperature[DS_key][9];
  309.                                     temperature[DS_key][9]=temperature[DS_key][10];
  310.                          }
  311.                
  312.                                 TR0=1;ET0=1;
  313.                 //                TR1=0;ET1=0;TH1=0x3c;TL1=0xB0;
  314.             //                TR1=1;ET1=1;
  315.                                 conk1++;
  316.                                 conk2++;
  317.                                 if(conk1==3)
  318.                                    conk1=0;
  319.                                 if(conk2==4)
  320.                                   {
  321.                                     conk2=0;
  322.                                          con=0;
  323.                                     TR0=0;ET0=0;
  324.                                         conk1=0;     
  325.                                    }
  326.                         }        
  327.                  }
  328.          }  
  329.                                                                                                                                                                                                                            
  330.         if(con!=0&&conk2!=0)                         //按键3                                          
  331.          {
  332.                    if(con==3||con==6)
  333.            {
  334.                      if(button4==0)         
  335.                      {
  336.                                delay(1000);                //消抖延迟  
  337.                                   while(button4==0);
  338.                                    if(temperature[DS_key][con+conk1]==10)
  339.                                    {
  340.                                    temperature[DS_key][10]=temperature[DS_key][con+conk1];
  341.                                    temperature[DS_key][con+conk1]=temperature[DS_key][9];
  342.                                    temperature[DS_key][9]=temperature[DS_key][10];
  343.                                    }
  344.                   //        TR1=0;ET1=0;TH1=0x3c;TL1=0xB0;
  345.               //        TR1=1;ET1=1;
  346.                                temperature[DS_key][con+conk1]++;
  347.                                if(temperature[DS_key][con+conk1]>=10)
  348.                                {
  349.                                            temperature[DS_key][con+conk1]=0;
  350.                                 }
  351.                                temperature[DS_key][9]=0x0a;
  352.                         }
  353.                  }
  354.         }        
  355.         EA=1;         
  356. }
  357. //DS18B20选择
  358. void Key_scan(void)
  359. {
  360.         if(button1==0) //按键4
  361.                    {
  362.                         delay(1000);  //延迟9毫秒,消抖延迟
  363.                         while(button1==0);
  364.                         
  365.                                 DS_key++;
  366.                                 if(DS_key==2)
  367.                                 DS_key=0;
  368.                 }
  369.                 DS_Key_scan();
  370.         
  371. }
  372. //定时器0中断0.4秒
  373. void time_int0(void) interrupt 1         
  374. {
  375.         EA=0;TR0=0;TH0=0x3c;TL0=0xB0;TR0=1;
  376.            cont0++;
  377.            if(cont0==6)
  378.         {
  379.                 cont0=0x00;
  380.                 temperature[DS_key][10]=temperature[DS_key][con+conk1];
  381.                 temperature[DS_key][con+conk1]=temperature[DS_key][9];
  382.                 temperature[DS_key][9]=temperature[DS_key][10];
  383.         }
  384.         ET0=1;
  385. }
  386. //定时器1中断
  387. /*void time_int1(void) interrupt 3        
  388. {                                                                                       
  389.         EA=0,TR1=0;TH1=0x3c;TL1=0xB0;TR1=1;
  390.     cont1++;
  391.            if(cont1==100)          //延迟5秒,5秒后恢复到显示18B20值
  392.            {
  393.                 if(temperature[con+conk1]==0x0a)
  394.                 {
  395.                         temperature[10]=temperature[con+conk1];
  396.                         temperature[con+conk1]=temperature[9];
  397.                         temperature[9]=temperature[10];
  398.                 }
  399.    
  400.             cont1=0x00;
  401.                 con=0;
  402.                 conk1=0;
  403.                 conk2=0;
  404.                 TR1=0;ET1=0;
  405.                 TR0=0;ET0=0;
  406.          }
  407.   
  408.           ET1=1;        
  409. }  
  410. */

  411. //输出显示函数
  412. void Show_Temp(void)                                       
  413. {
  414.         int i,j,m,n;
  415.         for(i=0;i<3;i++)
  416.         {
  417.                 if(DS_key==0)
  418.                 {
  419.                         j=con+i;
  420.                         n=i;
  421.                  }
  422.                  else
  423.                  {
  424.                          j=i;
  425.                         n=con+i;
  426.                  }
  427.                 m=i+3;
  428.                 P2=tab[i];
  429.                 if(i==1)
  430.                         P0=LED1[temperature[0][j]];

  431.                 else   
  432.                         P0=LED[temperature[0][j]];
  433.                 delay(150);

  434.                 P2=tab[m];
  435.                 if(m==4)
  436.                         P0=LED1[temperature[1][n]];
  437.                 else
  438.                         P0=LED[temperature[1][n]];
  439.                
  440.                 delay(150);
  441.         }
  442.                 P2=tab[7];
  443.                 P0=LED[DS_key+1];
  444.                 delay(150);
  445.                   P2=0xff;
  446. }

  447. //比较函数
  448. void Compare(void)
  449. {
  450.          unsigned int test1,high1,low1;
  451.         unsigned int test2,high2,low2;
  452.          test1=temperature[0][2]*100+temperature[0][1]*10+temperature[0][0];
  453.         high1=temperature[0][5]*100+temperature[0][4]*10+temperature[0][3];
  454.         low1=temperature[0][8]*100+temperature[0][7]*10+temperature[0][6];
  455.         test2=temperature[1][2]*100+temperature[1][1]*10+temperature[1][0];
  456.         high2=temperature[1][5]*100+temperature[1][4]*10+temperature[1][3];
  457.         low2=temperature[1][8]*100+temperature[1][7]*10+temperature[1][6];
  458.         P1_4=1;
  459.         P1_5=1;
  460.         P1_6=1;
  461.         P1_7=1;

  462.         if(test1>high1)
  463.         {
  464.                 P1_7=0;
  465.          }
  466.          if(test2>high2)
  467.         {
  468.                 P1_5=0;
  469.          }

  470.         if(test1<low1)
  471.         {
  472.                 P1_6=0;
  473.         }
  474.          if(test2<low2)
  475.         {
  476.                 P1_4=0;
  477.         }
  478. }

  479. void main()
  480. {      
  481.         //int num=0;
  482.         TH0=0x3C;TL0=0xB0;                //50毫秒延迟
  483.         TH1=0x3C;TL1=0xB0;                //50毫秒延迟
  484.         TMOD=0x11;ET0=0;TR0=0;ET1=0;TR1=0;
  485.         EA=0;
  486.         Init_DS18B20();
  487. //        Read_Rom_Code();
  488. //        First();
  489.         Find_Devices();
  490.         while(1)
  491.            {        
  492.                   Show_Temp();
  493.                 Read_Temperature(0);
  494. //                delay(20);
  495.                 Show_Temp();
  496.                 Read_Temperature(1);
  497.                 Key_scan();
  498. //                DS_Key_scan(0);
  499.             Compare();
  500.         
  501.         }
  502. }
复制代码


评分

参与人数 2黑币 +55 收起 理由
aaa12222 + 5 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:190731 发表于 2017-4-18 10:44 | 只看该作者
这个是不是无线的呢
回复

使用道具 举报

板凳
ID:245839 发表于 2017-11-3 21:12 | 只看该作者
温度传感器接在同一个口会不会使程序复杂?
回复

使用道具 举报

地板
ID:265012 发表于 2017-12-21 20:44 | 只看该作者
最近想做一个,简单的温度控制好做,改变一下是否可以
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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