標(biāo)題: 單片機(jī)模擬空調(diào)遙控恒溫控制 Proteus仿真源程序 [打印本頁]

作者: 謎鹿    時(shí)間: 2020-6-11 11:17
標(biāo)題: 單片機(jī)模擬空調(diào)遙控恒溫控制 Proteus仿真源程序

一年多沒碰51單片機(jī)了,當(dāng)時(shí)還是為STM32過渡學(xué)習(xí)的。


      這期開了單片機(jī)專業(yè)課,不得不重拾起來。想吐槽的就是,課上還用的proteus而不是實(shí)物,去年自學(xué)我好歹還五十來塊,買了個(gè)普中的。
大前天上午開了節(jié)實(shí)驗(yàn)課,一共五個(gè)實(shí)驗(yàn)。


     前天晚上都做完了,算是初步掌握了proteus簡單操作吧。本想用DS18B20測溫,百度搜了加熱元器件無果,就用燈泡指望燈絲加熱,降溫用一個(gè)風(fēng)扇轉(zhuǎn)轉(zhuǎn),做一個(gè)仿真真正能閉環(huán)控制的,但是proteus好像無法仿真出環(huán)境溫度的變化。模擬不出來就模擬不出來吧,做出來的意思到了就行。
    DS18B20有點(diǎn)玄乎,初始化時(shí)序那邊在proteus上面需要改改,不然失敗了,就只顯示000.60還是什么數(shù)字來著。按理說當(dāng)時(shí)實(shí)物也用的普中例程里面的能運(yùn)行才對。時(shí)序數(shù)值稍改了一下,能正常讀值測溫了。顯示部分用的數(shù)碼管,懶得在仿真上面費(fèi)工夫再去弄LCD1602了,有得有失吧,弊端就是讀DS18B20溫度時(shí),讀取函數(shù)放在數(shù)碼管顯示測得溫度和按鈕設(shè)定溫度之間,時(shí)間超出了視覺停留,會帶點(diǎn)閃動。用1602就沒這問題了,但玩過實(shí)物了,仿真沒興趣。矩陣鍵盤仿真圖里面放了,但沒有使用到,用了兩個(gè)帶外部中斷的按鈕,實(shí)現(xiàn)增溫減溫的功能,代替了矩陣鍵盤,仿真原理圖里面沒有刪去,沒啥大礙。大燈泡和風(fēng)扇都用了個(gè)繼電器。風(fēng)扇沒用PWM波去驅(qū)動,圖省事,接電就轉(zhuǎn)。想想了,好像也沒啥了。
    總的來說,難度一般,沒有隊(duì)里去年51任務(wù)最后一個(gè)難度大,要求做個(gè)萬年歷帶溫度,密碼鎖,串口上位機(jī)能修改時(shí)間,設(shè)定鬧鈴時(shí)間,鬧鈴關(guān)還是開等等。


   

   對了,上面忘了提及了,左邊是檢測溫度,右邊是設(shè)定溫度。

   用的多文件,proteus7版本的,keil4寫的。都是老版本莫得問題的話,應(yīng)該都能打開吧。用慣了keil5,再看看4真的簡陋,喵的,而且結(jié)合32的CubeMX,更香。習(xí)慣了32的變量類型方式,uint8_t就是uchar,依此類推,或者詳見typedef.h文件。

   代碼里面有些部分可能沒用到,但問題不大,工程是幾個(gè)實(shí)驗(yàn)慢慢添補(bǔ)的。沒記錯的話,定時(shí)器那邊計(jì)數(shù)還是給交通燈實(shí)驗(yàn)三開著的沒關(guān)。

   如果是我同學(xué)看到了這個(gè),起碼把原理圖位置改改,代碼函數(shù)變量改改,別照搬。我還要寫實(shí)驗(yàn)報(bào)告呢,課上我這實(shí)驗(yàn)也演示過了,雷同可不好哦。

   做完算是分享吧,如果該文件有什么問題,可以私信我

單片機(jī)源程序如下:
  1. #include "reg52.h"
  2. #include "tydefine.h"
  3. #include "led.h"
  4. #include "timer.h"
  5. #include "exit.h"
  6. #include "ds18b20.h"

  7. #define GPIO_KEY P1

  8. sbit LSA = P2^2;
  9. sbit LSB = P2^3;
  10. sbit LSC = P2^4;

  11. sbit FAN = P2^6;
  12. sbit LAMP = P2^7;

  13. extern uint16_t SetTemNum;
  14. uint16_t CurrentTemNum = 0;


  15. uint8_t code DigitalTubeSegment[] ={
  16.            0x3f,0x06,0x5b,0x4f,0x66,
  17.         0x6d,0x7d,0x07,0x7f,0x6f
  18. };

  19. uint8_t KeyValue = 0;
  20. uint8_t DisplayData[8];


  21. void delay_ms(uint32_t n);
  22. void KeyDown();
  23. void UsartInit();
  24. void DigitalTubeDisplay(uint8_t ShowNumber,uint8_t DigitNumber);
  25. void DisplayCurrentNumber(uint16_t CurrentNumber);
  26. void datapros(int32_t temp);
  27. void TemJudgement();

  28. void main()
  29. {
  30.         Exit0Init();
  31.         Exit1Init();
  32.         while(1)
  33.         {
  34.                 datapros(Ds18b20ReadTemp());
  35.                 DigitalTubeDisplay(DisplayData[2],6);
  36.                 DigitalTubeDisplay(DisplayData[3],5);
  37.                 TemJudgement();
  38.                 datapros(Ds18b20ReadTemp());
  39.                 DisplayCurrentNumber(SetTemNum);
  40.                 TemJudgement();
  41.         }
  42. }



  43. void delay_ms(uint32_t n)
  44. {
  45.     uint32_t i=0,j=0;
  46.     for(i=0;i<n;i++)
  47.         for(j=0;j<123;j++);
  48. }

  49. void KeyDown()
  50. {
  51.         uint8_t KeyWaitcount = 0;
  52.         GPIO_KEY = 0x0F;
  53.         if(GPIO_KEY != 0x0F)
  54.         {
  55.                 delay_ms(10);
  56.                 if(GPIO_KEY != 0x0F)
  57.                 {
  58.                         switch(GPIO_KEY)
  59.                         {
  60.                                 case 0x07:
  61.                                         KeyValue = 1;
  62.                                         break;
  63.                                 case 0x0B:
  64.                                         KeyValue = 2;
  65.                                         break;
  66.                                 case 0x0D:
  67.                                         KeyValue = 3;
  68.                                         break;
  69.                                 case 0x0E:
  70.                                         KeyValue = 4;
  71.                                         break;
  72.                         }
  73.                         GPIO_KEY = 0xF0;
  74.                         switch(GPIO_KEY)
  75.                         {
  76.                                 case 0xE0:
  77.                                         KeyValue = KeyValue;
  78.                                         break;
  79.                                 case 0xD0:
  80.                                         KeyValue = KeyValue + 4;
  81.                                         break;
  82.                                 case 0xB0:
  83.                                         KeyValue = KeyValue + 8;
  84.                                         break;
  85.                                 case 0x70:
  86.                                         KeyValue = KeyValue + 12;
  87.                                         break;
  88.                         }
  89.                         while((KeyWaitcount<50)&&(GPIO_KEY != 0xF0))
  90.                         {
  91.                                 delay_ms(10);
  92.                                 KeyWaitcount++;
  93.                         }

  94. //                        SBUF = KeyValue;
  95. //                        while(!TI);
  96. //                        TI = 0;                       
  97.                 }
  98.         }       
  99. }

  100. void DigitalTubeDisplay(uint8_t ShowNumber,uint8_t DigitNumber)
  101. {
  102.         switch(DigitNumber)
  103.         {
  104.                 case 1:
  105.                         LSC = 0;LSB = 0;LSA = 0;
  106.                         break;
  107.                 case 2:
  108.                         LSC = 0;LSB = 0;LSA = 1;
  109.                         break;
  110.                 case 3:
  111.                         LSC = 0;LSB = 1;LSA = 0;
  112.                         break;
  113.                 case 4:
  114.                         LSC = 0;LSB = 1;LSA = 1;
  115.                         break;
  116.                 case 5:
  117.                         LSC = 1;LSB = 0;LSA = 0;
  118.                         break;
  119.                 case 6:
  120.                         LSC = 1;LSB = 0;LSA = 1;
  121.                         break;
  122.         }
  123.         P0 = DigitalTubeSegment[ShowNumber];
  124.         delay_ms(1);
  125.         P0 = 0x00;
  126. }

  127. void DisplayCurrentNumber(uint16_t CurrentNumber)
  128. {
  129.         uint8_t UnitsDigit = 0;
  130.         uint8_t TensDigit = 0;
  131.         TensDigit = CurrentNumber/10;
  132.         UnitsDigit = CurrentNumber%10;
  133.         switch(3)
  134.         {
  135.                 case 1:
  136.                         DigitalTubeDisplay(TensDigit,6);
  137.                         DigitalTubeDisplay(UnitsDigit,5);
  138.                         break;
  139.                 case 2:
  140.                         DigitalTubeDisplay(TensDigit,4);
  141.                         DigitalTubeDisplay(UnitsDigit,3);
  142.                         break;
  143.                 case 3:
  144.                         DigitalTubeDisplay(TensDigit,2);
  145.                         DigitalTubeDisplay(UnitsDigit,1);
  146.                         break;
  147.         }       
  148. }

  149. void datapros(int32_t temp)          
  150. {
  151.            float tp;  
  152.         if(temp< 0)                                //當(dāng)溫度值為負(fù)數(shù)
  153.           {
  154.                 DisplayData[0] = 0x40;           //   -
  155.                 //因?yàn)樽x取的溫度是實(shí)際溫度的補(bǔ)碼,所以減1,再取反求出原碼
  156.                 temp=temp-1;
  157.                 temp=~temp;
  158.                 tp=temp;
  159.                 temp=tp*0.0625*100+0.5;       
  160.                 //留兩個(gè)小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
  161.                 //后面的數(shù)自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
  162.                 //算加上0.5,還是在小數(shù)點(diǎn)后面。

  163.           }
  164.         else
  165.           {                       
  166.                 DisplayData[0] = 0x00;
  167.                 tp=temp;//因?yàn)閿?shù)據(jù)處理有小數(shù)點(diǎn)所以將溫度賦給一個(gè)浮點(diǎn)型變量
  168.                 //如果溫度是正的那么,那么正數(shù)的原碼就是補(bǔ)碼它本身
  169.                 temp=tp*0.0625*100+0.5;       
  170.                 //留兩個(gè)小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
  171.                 //后面的數(shù)自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
  172.                 //算加上0.5,還是在小數(shù)點(diǎn)后面。
  173.         }
  174. //        DisplayData[1] = temp / 10000;
  175.         DisplayData[2] = temp % 10000 / 1000;
  176.         DisplayData[3] = temp % 1000 / 100;
  177.         CurrentTemNum =  DisplayData[2]*10 + DisplayData[3];
  178. //        DisplayData[4] = temp % 100 / 10;
  179. //        DisplayData[5] = temp % 10;
  180. }

  181. void TemJudgement()
  182. {
  183. //        CurrentTemNum        SetTemNum
  184.         if(CurrentTemNum > SetTemNum)
  185.         {
  186.                 FAN = 0;
  187.                 LAMP = 1;
  188.         }
  189.         else if(CurrentTemNum < SetTemNum)
  190.         {
  191.                 FAN = 1;
  192.                 LAMP = 0;
  193.         }
  194. }
復(fù)制代碼

所有資料51hei提供下載:
06085.zip (117.08 KB, 下載次數(shù): 55)



作者: 算術(shù)平均數(shù)    時(shí)間: 2020-6-14 23:28
你好,我想問一下,你會用DAC0832控制直流電機(jī)嗎?接線是這樣的
作者: 謎鹿    時(shí)間: 2020-12-11 14:58
算術(shù)平均數(shù) 發(fā)表于 2020-6-14 23:28
你好,我想問一下,你會用DAC0832控制直流電機(jī)嗎?接線是這樣的

沒做過這個(gè)仿真。不是課設(shè)的話,我都不用這軟件的。。。。。。當(dāng)初學(xué)的時(shí)候入手一個(gè)開發(fā)板實(shí)物。




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1