找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

帖子
查看: 5088|回復(fù): 4
收起左側(cè)

基于51單片機(jī)ADC的熱敏電阻測(cè)溫裝置制作 附仿真代碼 誤差1度

  [復(fù)制鏈接]
ID:834632 發(fā)表于 2021-1-2 16:59 | 顯示全部樓層 |閱讀模式
    作為一個(gè)51單片機(jī)的初學(xué)者,自己完成一個(gè)實(shí)物制作是感到很有成就感的事,在這里與大家分享,也希望可以和這里的大佬們進(jìn)行交流和學(xué)習(xí)。本人算是入門新手,有錯(cuò)誤或者不足的地方希望大佬可以指正和交流,在這里先提前請(qǐng)教。有想要做關(guān)于熱敏電阻測(cè)溫的也可以拿去參考希望我的這個(gè)拙作能給你帶來(lái)一些啟發(fā)。
    首先我來(lái)談一談熱敏電阻測(cè)溫裝置制作中遇到的困難,這個(gè)東西大概花費(fèi)了一周的時(shí)間,最難完成的部分就是測(cè)溫不準(zhǔn)確的問(wèn)題,首先我寫程序的時(shí)候,關(guān)于采集的電壓值轉(zhuǎn)化為ADC值,最后又轉(zhuǎn)化為溫度的這個(gè)過(guò)程,最初是使用了公式進(jìn)行轉(zhuǎn)換的,但是,進(jìn)入調(diào)試環(huán)節(jié)后發(fā)現(xiàn),顯示的不準(zhǔn)確,因?yàn)槊恳粋€(gè)不同的NTC熱敏電阻不會(huì)和它自身B值所計(jì)算的電阻值那么吻合,實(shí)際的使用中有著許多不確定的因素,所以我最后就確定使用EXCEL 表格去計(jì)算出對(duì)應(yīng)的電壓值,最后在得出我需要的ADC值,然后放在數(shù)組中,直接使用。
    硬件部分的Proteus仿真圖如下:
U$LKC~FAV4[_4OD({717APE.png


   我使用的AD是adc0832 8位并行的芯片,測(cè)溫范圍為0-200度,所以精度不高,誤差有1度左右,還是挺大的,如果追求高精度的可以選擇12位或者更高位的AD轉(zhuǎn)化芯片。溫度采集使用的分壓式,分壓電阻是2K歐姆,熱敏電阻是10K電阻B值為3940.
制作出來(lái)的實(shí)物圖如下:
新建文件夾IMG_20201225_124745.jpg

新建文件夾IMG_20201225_124822.jpg


/*單片機(jī)程序如下*/
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit CS =P1^0;
  6. sbit CLK=P1^1;
  7. sbit DIO =P1^2;
  8. sbit K_H=P1^3;
  9. sbit K_L=P1^4;
  10. sbit LED_U=P1^5;
  11. sbit LED_D=P1^6;
  12. sbit SOUNDER=P1^7;
  13. sbit K_T =P3^1;
  14. sbit K_U =P3^2;
  15. sbit K_D =P3^3;
  16. uint i,j,m,n,H,L,T,num,date,a=0,b=0;


  17. void Delay10ms(unsigned int c) //延遲為10ms的延遲函數(shù),用于按鍵的延遲去抖
  18. {
  19.     unsigned char a, b;
  20.     for (;c>0;c--)
  21.         {
  22.                 for (b=38;b>0;b--)
  23.                 {
  24.                         for (a=130;a>0;a--);
  25.                 }
  26.     }
  27. }


  28. uchar code table[]={//共陰數(shù)碼管段碼"0~f"
  29. 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x80};


  30. uchar data dis_buf[4];


  31. uchar code Temp[201]={//溫度:0-200  對(duì)應(yīng)的ADC值
  32. 255.9,255.8, 255.7, 255.6, 255.5, 255.4, 255.3, 255.2, 255.1, 254.1, 253.1, 252.1, 251.0, 249.9, 248.7, 247.6, 246.4, 245.1,
  33. 243.8, 242.5, 241.1, 239.8, 238.3, 236.9, 235.4, 233.8, 232.2, 230.6, 229.0, 227.3, 225.6, 223.8, 222.0, 220.2, 218.4, 216.5,
  34. 214.6, 212.6, 210.6, 208.6, 206.6, 204.5, 202.5, 200.4, 198.2, 196.1, 193.9, 191.7, 189.5, 187.3, 185.1, 182.8, 180.6, 178.3,
  35. 176.0, 173.8, 171.5, 169.2, 166.9, 164.6, 162.3, 160.1, 157.8, 155.5, 153.2, 151.0, 148.7, 146.5, 144.3, 142.1, 139.9, 137.7,
  36. 135.6, 133.4, 131.3, 129.2, 127.1, 125.1, 123.0, 121.0, 119.1, 117.1, 115.2, 113.2, 111.4, 109.5, 107.7, 105.9, 104.1, 102.4,
  37. 100.6, 98.9 ,97.3 ,95.7 ,94.0 ,92.5 ,90.9 ,89.4 ,87.9 ,86.4 ,85.0 ,83.6 ,82.2 ,80.9 ,79.5 ,78.2 ,77.0 ,75.7 ,74.5 ,72.7 ,72.1 ,71.0 ,69.9 ,
  38. 68.8 ,67.7 ,66.6 ,65.6 ,64.6 ,63.6 ,62.7 ,61.7 ,60.8 ,59.9 ,59.0 ,58.2 ,57.4 ,56.5 ,55.7 ,55.0 ,54.2 ,53.5 ,52.7 ,52.0 ,51.3 ,50.7 ,50.0 ,
  39. 49.4 ,48.7 ,48.1 ,47.5 ,46.9 ,46.4 ,45.8 ,45.3 ,44.7 ,44.2 ,43.7 ,43.2 ,42.7 ,42.3 ,41.8 ,41.3 ,40.9 ,40.5 ,40.1 ,39.6 ,39.2 ,38.9 ,38.5 ,38.1 ,
  40. 37.7 ,37.4 ,37.0 ,36.7 ,36.4 ,36.0 ,35.7 ,35.4 ,35.1 ,34.8 ,34.5 ,34.3 ,34.0 ,33.7 ,33.5 ,33.2 ,33.0 ,32.7 ,32.5 ,32.3 ,32.0 ,31.8 ,31.6 ,
  41. 31.4 ,31.2 ,31.0 ,30.8 ,30.6 ,30.4 ,30.2 ,30.0 ,29.9 ,29.7 ,29.9 ,29.7 ,29.5 ,29.0 ,28.9 ,28.7 ,28.6 ,28.4 ,
  42. };        
  43. uchar ADC0832()  //ADC0832 8位串行的AD轉(zhuǎn)換芯片
  44. {
  45.         uchar aaa,temp;
  46.         CS=1; //一個(gè)轉(zhuǎn)換周期開(kāi)始
  47.         CLK=0; //為第一個(gè)脈沖作準(zhǔn)備
  48.         CS=0; //CS置0,片選有效
  49.         DIO=1; //DIO置1,規(guī)定的起始信號(hào)
  50.         CLK=1; //第一個(gè)脈沖
  51.         CLK=0; //第一個(gè)脈沖的下降沿,此前DIO必須是高電平
  52.         DIO=1; //DIO置1, 通道選擇信號(hào)
  53.         CLK=1; //第二個(gè)脈沖,第2、3個(gè)脈沖下沉之前,DI必須跟別輸入兩位數(shù)據(jù)用于選擇通道,這里選通道CH0
  54.         CLK=0; //第二個(gè)脈沖下降沿
  55.         DIO=0; //DI置0,選擇通道0
  56.         CLK=1; //第三個(gè)脈沖
  57.         CLK=0; //第三個(gè)脈沖下降沿
  58.         DIO=1; //第三個(gè)脈沖下沉之后,輸入端DIO失去作用,應(yīng)置1
  59.         CLK=1; //第四個(gè)脈沖
  60.         for(aaa=0;aaa<8;aaa++) //高位在前
  61.         {
  62.                 CLK=1; //第四個(gè)脈沖
  63.                 CLK=0;
  64.                 temp<<=1; //將下面儲(chǔ)存的低位數(shù)據(jù)向右移
  65.                 temp|=(uchar)DIO; //將輸出數(shù)據(jù)DIO通過(guò)或運(yùn)算儲(chǔ)存在dat最低位
  66.         }
  67.         CS=1; //片選無(wú)效
  68.         return temp; //將讀的數(shù)據(jù)返回
  69. }


  70. void delay(uint n)
  71. {
  72. uint i,j;
  73. for(i=n;i>0;i--)
  74. for(j=30;j>0;j--);
  75. }
  76. void LED_SOUND() //LED和蜂鳴器的報(bào)警顯示
  77. {
  78. LED_U=0;
  79. LED_D=0;
  80. SOUNDER=0;
  81.   if(T>=H)                //溫度高于上限紅色LED燈亮,同時(shí)蜂鳴器報(bào)警
  82.   {
  83.    LED_U=1;
  84.    SOUNDER=1;
  85.   }
  86.   if(T<=L)                //溫度低于下限黃燈點(diǎn)亮,同時(shí)蜂鳴器報(bào)警
  87.   {
  88.    LED_D=1;
  89.    SOUNDER=1;
  90.   }
  91. }


  92. void xianshi()         //用于數(shù)碼管顯示的函數(shù)
  93. {
  94. static uchar i=0;
  95. P0=0x00;
  96. P2=~(0x01<<i);
  97. delay(1);
  98. P0=dis_buf[ i];[ i]
  99. i++;
  100. i%=4;
  101. }


  102. void main()
  103. {
  104. LED_U=0;
  105. EX0=1;                 
  106. IT0=1;                                   
  107. EX1=1;                 
  108. IT1=1;
  109. EA=1;
  110. while(1)
  111.   {
  112.    for(j=0;j<5;j++)           //多次采集求平均值,用于防止顯示時(shí)值的不穩(wěn)定
  113.    {
  114.      num+=ADC0832();        
  115.      date=num/5;
  116.    }


  117.    j=0;
  118.    num=0;
  119.          
  120.    for(i=0;i<201;i++) //用于判斷ADC值在那個(gè)值的范圍內(nèi),然后輸出數(shù)組值,也就是對(duì)應(yīng)的溫度值
  121.    {
  122.      if(date<=Temp[ i]&&date>Temp[i+1])[ i]
  123.       {
  124.        T=i;
  125.        break;
  126.       }
  127.    }


  128.    dis_buf[0]=table[T/100];          //個(gè)位顯示
  129.    dis_buf[1]=table[T/10%10]; //十位顯示
  130.    dis_buf[2]=table[T%10];          //百位顯示
  131.    dis_buf[3]=0x39;          //顯示“C”
  132.    xianshi();
  133.    delay(1);


  134.    if(K_H==0)                 //按鍵是否按下
  135.    {
  136.      Delay10ms(1);                //按鍵的延遲去抖
  137.           if(K_H==0)
  138.            {
  139.             while(1)                //用于顯示上限的報(bào)警數(shù)值
  140.             {
  141.                  H=20+a;
  142.              dis_buf[0]=0x76;
  143.              dis_buf[1]=table[H/100];
  144.          dis_buf[2]=table[H/10%10];
  145.          dis_buf[3]=table[H%10];
  146.          xianshi();


  147.                  if(K_H==0)                  //再次按下按鍵,跳出調(diào)節(jié)上限的顯示界面,繼續(xù)顯示溫度
  148.                   {
  149.                    Delay10ms(1);
  150.                    if(K_H==0)
  151.                    break;         
  152.                   }        
  153.             }           
  154.           }
  155.    }
  156.    if(K_L==0)                           //按鍵是否按下
  157.    {
  158.     Delay10ms(1);                    //按鍵的延遲去抖
  159.          if(K_L==0)
  160.          {
  161.           while(1)                                 //用于顯示下限的報(bào)警數(shù)值
  162.           {   
  163.            L=10+b;
  164.            dis_buf[0]=0x38;
  165.            dis_buf[1]=table[L/100];
  166.        dis_buf[2]=table[L/10%10];
  167.        dis_buf[3]=table[L%10];
  168.        xianshi();
  169.            if(K_L==0)                         //再次按下按鍵,跳出調(diào)節(jié)下限的顯示界面,繼續(xù)顯示溫度
  170.            {
  171.             Delay10ms(1);
  172.                 if(K_L==0)
  173.                 break;
  174.            }
  175.       }
  176.      }
  177.    }
  178.    LED_SOUND();                                   //報(bào)警函數(shù)
  179. }
  180. }


  181. void u_init() interrupt 0  //用于按鍵“加一”的中斷函數(shù)
  182. {
  183. if(K_U==0)
  184. {
  185.   Delay10ms(1);
  186.    if(K_U==0)
  187.    {
  188.     if(dis_buf[0]==0X76)  //用于判斷數(shù)碼管是否處于調(diào)節(jié)上限顯示的界面
  189.         {
  190.          a++;
  191.         }
  192.     if(dis_buf[0]==0X38)   //用于判斷數(shù)碼管是否處于調(diào)節(jié)下限顯示的界面
  193.         {
  194.          b++;
  195.         }        
  196.    }
  197. }
  198. }


  199. void d_init() interrupt 2          //用于按鍵“減一”的中斷函數(shù)
  200. {
  201. if(K_D==0)
  202.   {
  203.    Delay10ms(1);
  204.    if(K_D==0)
  205.    {
  206.     if(dis_buf[0]==0X76)  //用于判斷數(shù)碼管是否處于調(diào)節(jié)上限顯示的界面
  207.          {
  208.          a--;
  209.          }
  210.     if(dis_buf[0]==0X38)   //用于判斷數(shù)碼管是否處于調(diào)節(jié)下限顯示的界面
  211.          {
  212.          b--;
  213.          }        
  214.    }
  215.   }
  216. }
復(fù)制代碼
    51hei.png
51hei.png
最后我有將程序,仿真,還有ADC處理等放在附件內(nèi),有需要的可以下載,希望可以得到大家的指正和交流 。
           
全部資料51hei下載地址:
熱敏電阻測(cè)溫裝置.7z (79.56 KB, 下載次數(shù): 148)

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:834632 發(fā)表于 2021-1-2 22:08 | 顯示全部樓層
請(qǐng)大家多多指教,一起學(xué)習(xí)一起進(jìn)步
回復(fù)

使用道具 舉報(bào)

ID:856401 發(fā)表于 2021-1-9 21:16 | 顯示全部樓層
樓主,我也要做一個(gè)
回復(fù)

使用道具 舉報(bào)

ID:416575 發(fā)表于 2022-4-27 23:13 | 顯示全部樓層
if(date<=Temp[ i]&&date>Temp[i+1])[ i]這行編譯時(shí)錯(cuò)誤(235): error C141: syntax error near '['
回復(fù)

使用道具 舉報(bào)

ID:262 發(fā)表于 2022-4-27 23:18 | 顯示全部樓層
hsyxjm 發(fā)表于 2022-4-27 23:13
if(dateTemp)[ i]這行編譯時(shí)錯(cuò)誤(235): error C141: syntax error near '['

沒(méi)問(wèn)題  我用Keil5編譯樓主的附件 0個(gè)錯(cuò)誤  不要從網(wǎng)頁(yè)復(fù)制
51hei.png
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表