找回密码
 立即注册

QQ登录

只需一步,快速开始

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

蓝桥杯ct107 51单片机的温度控制器程序设计

[复制链接]
ID:977536 发表于 2021-11-4 09:22 | 显示全部楼层 |阅读模式
基于51单片机的温度控制器设计
功能较为完善

单片机源程序如下:
  1. #include "reg52.h"
  2. #include "ct107.h"
  3. #include "iic.h"
  4. #include "EEPROM.H"
  5. #include "18b20.h"
  6. #include "i2c.h"

  7. bit flag_get,keyflag;                           //定义采集温度标志位和按键标志位
  8. sbit PWM=P3^4;                                           //定义脉冲端口

  9. sbit LED1=P0^0;
  10. sbit LED2=P0^1;
  11. sbit LED3=P0^2;
  12. sbit LED4=P0^3;
  13. sbit LED5=P0^4;
  14. sbit LED6=P0^5;
  15. sbit LED7=P0^6;
  16. sbit LED8=P0^7;

  17. unsigned char code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};   //数码管段选“0~9”
  18. unsigned char code smg_we[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};                           //数码管位选
  19. unsigned char UpT,DoT,NowT;                        //上限温度,下限温度,目前温度
  20. unsigned int temp;                                        //定义中间变量
  21. unsigned char dat[8];                                //定义显示数组
  22. unsigned int Ad_data;

  23. void key();                                                        //按键函数
  24. void diswork();                                                //显示处理函数
  25. void Write_byte(unsigned char add,unsigned char dat);                 //向EEPROM写一个字节
  26. unsigned char read_byte(unsigned char add);                                         //从EEPROM读一个字节
  27. unsigned int ReadTemperature(void);                                                         //读当前温度
  28. void deplay_50us(unsigned char t);                                                         //50us延时函数
  29. void work();                                                                                                 //判断采用何种措施函数
  30. void Ad_read(void);           //电压读取

  31. main()                                                                                                                 //主函数
  32. {
  33.         ct107_init();                                                                                         //初始化板(关蜂鸣器,继电器,LED等)
  34.         TMOD=0X12;                                                                                                 //定义定时器1为16位,定时器0为8位重载定时器
  35.         TH1=(65536-2000)/256;                                                                         //定时2ms
  36.         TL1=(65536-2000)%256;
  37.         TH0=256-100;                                                                                         //定时0.1ms
  38.         TL0=256-100;
  39.         TR1=1;                                                                                                         //开定时器T1
  40.         ET1=1;                                                                                                         //开定时器T1中断
  41.         TR0=1;                                                                                                         //开定时器T0
  42.         EA=1;                                                                                                         //开总中断

  43.         while(1)
  44.         {
  45.             
  46.                  key();
  47.                  
  48.         
  49.                 if(flag_get==1)                       //定时读取当前温度
  50.             {
  51.                  Ad_read();
  52.                
  53.                                 
  54.                   temp=ReadTemperature();                                
  55.                   NowT=temp>>4;                                   //读温度整数部分
  56.                   flag_get=0;
  57.                   }
  58.                 UpT=read_byte(0x00);                //从EEPROM读出上限温度
  59.                 DoT=read_byte(0x01);                //从EEPROM读出下限温度
  60.                         
  61.                         
  62.                         
  63.                 work();
  64.                 diswork();
  65.         }
  66.         


  67.         }        


  68. /*--------------------------------------------------------------------------
  69.                                                 判断采用何种措施函数
  70. -------------------------------------------------------------------------*/
  71. void work()
  72. {
  73.         if(NowT>UpT)                                   //当目前温度高于上限温度是开T0中断,产生1KHz占空比为30%的方波
  74.         {
  75.          ET0=1;        
  76.                
  77.                
  78.                        LED1=0;
  79.                 LED2=1;
  80.                 LED3=1;
  81.                 LED4=1;
  82.                 LED5=1;
  83.                 LED6=1;
  84.                 LED7=1;
  85.                 LED8=1;
  86.           P2|=Y4C;         
  87.     P2&=0x1f;
  88.       
  89.         }
  90.         else
  91.                 if(NowT>DoT)                           //温度在上下限之间时,关中断,P3^4口保持高电平
  92.                 {
  93.                 ET0=0;
  94.                 PWM=1;        
  95.                         
  96.                         
  97.                                   LED1=1;
  98.                 LED2=0;
  99.                 LED3=1;
  100.                 LED4=1;
  101.                 LED5=1;
  102.                 LED6=1;
  103.                 LED7=1;
  104.                 LED8=1;
  105.           P2|=Y4C;         
  106.     P2&=0x1f;
  107.                 }
  108.         if(NowT<DoT)                                   //温度低于下限温度时开继电器,关蜂鸣器避免干扰
  109.         {
  110.         P2&=0x1f;
  111.         BUZZ=0;
  112.         RELAY=1;
  113.         P2|=Y5C;         
  114.         P2&=0x1f;
  115.                
  116.                             LED1=1;
  117.                 LED2=1;
  118.                 LED3=0;
  119.                 LED4=1;
  120.                 LED5=1;
  121.                 LED6=1;
  122.                 LED7=1;
  123.                 LED8=1;
  124.           P2|=Y4C;         
  125.     P2&=0x1f;
  126.         }
  127.         else
  128.         {
  129.         P2&=0x1f;
  130.         BUZZ=0;
  131.         RELAY=0;
  132.         P2|=Y5C;         
  133.         P2&=0x1f;
  134.         }
  135. }



  136. /*-------------------------------------------------------------------------------
  137.                                                         按键扫描函数
  138. -------------------------------------------------------------------------------*/
  139. void key()
  140. {
  141.         if((P3&0x0f)!=0x0f)
  142.         {        
  143.         if(!keyflag)
  144.         {
  145.                 deplay_50us(200);
  146.                 if((P3&0x0f)!=0x0f)
  147.                 {
  148.                         keyflag=1;
  149.                         switch(P3&0x0f)
  150.                         {
  151.                                 case 0x07:if(UpT<99)UpT++;break;
  152.                                 case 0x0b:if(DoT<UpT-1)DoT++;break;
  153.                                 case 0x0d:if(UpT-1>DoT)UpT--;break;
  154.                                 case 0x0e:if(DoT>0)DoT--;break;
  155.                                 default:break;
  156.                         }
  157.                    if(UpT<=DoT|UpT>99|DoT<0)                  //保护程序,一旦存储数据出错可以使数据回到设定值,使系统稳定
  158.                    {
  159.                    UpT=30;
  160.                    DoT=0;
  161.                    }
  162.                    Write_byte(0x00,UpT);                          //将数据写入EEPROM
  163.                    deplay_50us(18);
  164.                    Write_byte(0x01,DoT);
  165.                    deplay_50us(18);
  166.                 }
  167.         }
  168.         }
  169.         else
  170.         keyflag=0;                        
  171. }
  172. /*----------------------------------------------
  173.                         显示数据处理函数
  174. ----------------------------------------------*/

  175. void diswork()
  176. {
  177.         dat[0]=UpT/10;
  178.         dat[1]=UpT%10;
  179.         dat[2]=DoT/10;
  180.         dat[3]=DoT%10;
  181.         dat[4]=Ad_data/10;
  182.         dat[5]=Ad_data%10;
  183.         dat[6]=NowT/10;
  184.         dat[7]=NowT%10;

  185. }



  186. /*----------------------------------------
  187.                 写入内存一个字节
  188. -----------------------------------------*/
  189. void Write_byte(unsigned char add,unsigned char dat)
  190. {
  191.         ET1=0;
  192.         init_iic();                                   //可以不初始化,函数已有严格的时序控制
  193.         Start();                        //起始信号
  194.         Send(AddWr);                //器件地址
  195.         Ack();                                //应答
  196.         Send(add);                        //存放地址
  197.         Ack();
  198.         Send(dat);                        //存放数据
  199.         Ack();
  200.         Stop();                                //停止信号
  201.         ET1=1;
  202. }
  203. /*-----------------------------------------
  204.                 读内存一个字节
  205. -----------------------------------------*/
  206. unsigned char read_byte(unsigned char add)
  207. {
  208.         unsigned char rdat;
  209.         ET1=0;
  210.         init_iic();                                   //可以不初始化,函数已有严格的时序控制
  211.         Start();                        //起始信号
  212.         Send(AddWr);                //发送写器件地址
  213.         Ack();
  214.         Send(add);                        
  215.         Ack();
  216.         Start();                        //起始信号
  217.         Send(AddRd);            //读器件地址
  218.         Ack();
  219.         rdat=Read();                        //读数据
  220.         NoAck();                        //好像是告诉器件接收完毕
  221.         Stop();                                //停止信号
  222.         ET1=1;
  223.         return rdat;
  224. }
  225. /*------------------------------------------------------
  226.                          读取温度                                    
  227. -------------------------------------------------------*/
  228. unsigned int ReadTemperature(void)
  229. {
  230. unsigned char a=0;
  231. unsigned int b=0;
  232. unsigned int t=0;
  233. Init_DS18B20();
  234. WriteOneChar(0xCC); // 跳过读序号列号的操作
  235. WriteOneChar(0x44); // 启动温度转换
  236. delay(50);
  237. Init_DS18B20();
  238. EA=0;
  239. WriteOneChar(0xCC); //跳过读序号列号的操作
  240. WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  241. a=ReadOneChar();   //低位
  242. b=ReadOneChar();   //高位
  243. b<<=8;
  244. t=a+b;
  245. EA=1;
  246. return(t);

  247. }
  248. /*----------------------------------------------------------
  249.                 定时器0中断,产生1Khz占空比为30%的方波
  250. ----------------------------------------------------------*/
  251. void tm0_isr() interrupt 1
  252. {
  253.         static j;
  254.         if(j<3)
  255.         PWM=1;
  256.         else
  257.         PWM=0;
  258.         j++;
  259.         if(j==10)
  260.         {
  261.         j=0;
  262.         }
  263. }

  264. /*-----------------------------------------------------------
  265.                    定时器中断                                   
  266. ------------------------------------------------------------*/
  267. void tm1_isr() interrupt 3                        //定时扫描数码管和温度
  268. {
  269.         static i,k;
  270.         unsigned char com[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};           //用于控制数码管的亮灭
  271.         TH1=(65536-1800)/256;
  272.         TL1=(65536-1800)%256;
  273.         
  274.         if(i==4)
  275.         {
  276.         P2&=0x1f;
  277.         P0=0xff;
  278.         P2=Y7C;
  279.         P2&=0x1f;
  280.         P0=smg_we[i]&com[i];
  281.         P2=Y6C;
  282.         P2&=0x1f;
  283.         P0=smg_du[dat[i]]+0x80;
  284.         P2=Y7C;
  285.         P2&=0x1f;
  286.         i++;
  287.         }
  288.         else
  289.         {
  290.         P2&=0x1f;
  291.         P0=0xff;
  292.         P2=Y7C;
  293.         P2&=0x1f;
  294.         P0=smg_we[i]&com[i];
  295.         P2=Y6C;
  296.         P2&=0x1f;
  297.         P0=smg_du[dat[i]];
  298.         P2=Y7C;
  299.         P2&=0x1f;
  300.         i++;
  301.         }        
  302.         if(i==8)
  303.         {
  304.         i=0;
  305.         k++;
  306.                 if(k==25)
  307.                 {
  308.                 k=0;
  309.                 flag_get=1;//标志位有效
  310.                 }
  311.         }
  312. }
  313. /*-----------------------------------------------------------
  314.                                 大约50us的延时函数
  315. -----------------------------------------------------------*/
  316. void deplay_50us(unsigned char t)
  317. {
  318.         unsigned char j;
  319.         for(;t>0;t--)
  320.                 for(j=19;j>0;j--);
  321. }

  322. void Ad_read(void)
  323. {
  324.   
  325.   Ad_data=adc_pcf8591(0);
  326.   Ad_data=Ad_data*50/256;
  327. }
复制代码

Keil代码下载:
温度.zip (91.34 KB, 下载次数: 12)

评分

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

查看全部评分

回复

使用道具 举报

ID:983338 发表于 2021-11-24 12:34 | 显示全部楼层
很棒的学习资料
回复

使用道具 举报

ID:986694 发表于 2021-12-1 10:00 | 显示全部楼层
你好楼主,我用你的代码在Keil 5上运行仿真错误好多,
对了,板子是51的
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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