找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3611|回复: 2
收起左侧

单片机模拟空调遥控恒温控制 Proteus仿真源程序

[复制链接]
ID:421451 发表于 2020-6-11 11:17 | 显示全部楼层 |阅读模式

一年多没碰51单片机了,当时还是为STM32过渡学习的。


      这期开了单片机专业课,不得不重拾起来。想吐槽的就是,课上还用的proteus而不是实物,去年自学我好歹还五十来块,买了个普中的。
大前天上午开了节实验课,一共五个实验。

  • 流水灯
  • 外部中断
  • 数码管,定时器
  • 矩阵键盘,串口
  • 空调模拟。。。。。。。

     前天晚上都做完了,算是初步掌握了proteus简单操作吧。本想用DS18B20测温,百度搜了加热元器件无果,就用灯泡指望灯丝加热,降温用一个风扇转转,做一个仿真真正能闭环控制的,但是proteus好像无法仿真出环境温度的变化。模拟不出来就模拟不出来吧,做出来的意思到了就行。
    DS18B20有点玄乎,初始化时序那边在proteus上面需要改改,不然失败了,就只显示000.60还是什么数字来着。按理说当时实物也用的普中例程里面的能运行才对。时序数值稍改了一下,能正常读值测温了。显示部分用的数码管,懒得在仿真上面费工夫再去弄LCD1602了,有得有失吧,弊端就是读DS18B20温度时,读取函数放在数码管显示测得温度和按钮设定温度之间,时间超出了视觉停留,会带点闪动。用1602就没这问题了,但玩过实物了,仿真没兴趣。矩阵键盘仿真图里面放了,但没有使用到,用了两个带外部中断的按钮,实现增温减温的功能,代替了矩阵键盘,仿真原理图里面没有删去,没啥大碍。大灯泡和风扇都用了个继电器。风扇没用PWM波去驱动,图省事,接电就转。想想了,好像也没啥了。
    总的来说,难度一般,没有队里去年51任务最后一个难度大,要求做个万年历带温度,密码锁,串口上位机能修改时间,设定闹铃时间,闹铃关还是开等等。
TIM图片20200611110112.png

    批注 2020-06-11 111340.png

   对了,上面忘了提及了,左边是检测温度,右边是设定温度。

   用的多文件,proteus7版本的,keil4写的。都是老版本莫得问题的话,应该都能打开吧。用惯了keil5,再看看4真的简陋,喵的,而且结合32的CubeMX,更香。习惯了32的变量类型方式,uint8_t就是uchar,依此类推,或者详见typedef.h文件。

   代码里面有些部分可能没用到,但问题不大,工程是几个实验慢慢添补的。没记错的话,定时器那边计数还是给交通灯实验三开着的没关。

   如果是我同学看到了这个,起码把原理图位置改改,代码函数变量改改,别照搬。我还要写实验报告呢,课上我这实验也演示过了,雷同可不好哦。

   做完算是分享吧,如果该文件有什么问题,可以私信我

单片机源程序如下:
  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)                                //当温度值为负数
  153.           {
  154.                 DisplayData[0] = 0x40;           //   -
  155.                 //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
  156.                 temp=temp-1;
  157.                 temp=~temp;
  158.                 tp=temp;
  159.                 temp=tp*0.0625*100+0.5;       
  160.                 //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  161.                 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  162.                 //算加上0.5,还是在小数点后面。

  163.           }
  164.         else
  165.           {                       
  166.                 DisplayData[0] = 0x00;
  167.                 tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
  168.                 //如果温度是正的那么,那么正数的原码就是补码它本身
  169.                 temp=tp*0.0625*100+0.5;       
  170.                 //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  171.                 //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  172.                 //算加上0.5,还是在小数点后面。
  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. }
复制代码

所有资料51hei提供下载:
06085.zip (117.08 KB, 下载次数: 55)

评分

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

查看全部评分

回复

使用道具 举报

ID:744425 发表于 2020-6-14 23:28 | 显示全部楼层
你好,我想问一下,你会用DAC0832控制直流电机吗?接线是这样的 capture_20200614210622659.jpg
回复

使用道具 举报

ID:421451 发表于 2020-12-11 14:58 | 显示全部楼层
算术平均数 发表于 2020-6-14 23:28
你好,我想问一下,你会用DAC0832控制直流电机吗?接线是这样的

没做过这个仿真。不是课设的话,我都不用这软件的。。。。。。当初学的时候入手一个开发板实物。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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