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

QQ登錄

只需一步,快速開始

搜索
查看: 4287|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)模擬空調(diào)遙控恒溫控制 Proteus仿真源程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主

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


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

  • 流水燈
  • 外部中斷
  • 數(shù)碼管,定時(shí)器
  • 矩陣鍵盤,串口
  • 空調(diào)模擬。。。。。。。

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


   

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

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

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

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

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

單片機(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)镃語(yǔ)言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
  161.                 //后面的數(shù)自動(dòng)去掉,不管是否大于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)镃語(yǔ)言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
  171.                 //后面的數(shù)自動(dòng)去掉,不管是否大于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)


評(píng)分

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

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:744425 發(fā)表于 2020-6-14 23:28 | 只看該作者
你好,我想問一下,你會(huì)用DAC0832控制直流電機(jī)嗎?接線是這樣的
回復(fù)

使用道具 舉報(bào)

板凳
ID:421451 發(fā)表于 2020-12-11 14:58 | 只看該作者
算術(shù)平均數(shù) 發(fā)表于 2020-6-14 23:28
你好,我想問一下,你會(huì)用DAC0832控制直流電機(jī)嗎?接線是這樣的

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

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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