找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2350|回复: 0
收起左侧

基于51单片机的温控系统

[复制链接]
ID:317514 发表于 2018-10-4 15:13 | 显示全部楼层 |阅读模式
自己弄的51单片机,通过温度来调控直流电机的转速

单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5. #define MAIN_Fosc        11059200UL        //宏定义主时钟HZ
  6. /*自定义类型名*/
  7. typedef unsigned char INT8U;
  8. typedef unsigned int INT16U;

  9. sbit dj=P1^0; //电机接口
  10. sbit DS  = P2^2;   //DS18B20单总线

  11. sbit key_s1=P3^0;//设置温度键
  12. sbit key_s2=P3^1;//温度加
  13. sbit key_s3=P3^2;//温度减

  14. sbit DU=P2^6;//段选开关
  15. sbit WE=P2^7;//位选开关

  16. //uchar l,h;

  17. /*共阴极数码管段选码*/
  18. uchar code table[]={
  19. //0                1         2     3     4     5     6     7     8
  20. 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
  21. //9     A     B           C         D           E         F                -         .          关显示
  22. 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00 };

  23. /*数码管位选码*/
  24. uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
  25. //数码管位码

  26. uchar shang,xia;//对比温度暂存变量
  27. uchar dang;//挡位
  28. uchar flag;
  29. uchar d1,d2,d3,d4;//显示数据暂存变量
  30. uint wen;//温度变量

  31. /*毫秒延时函数*/
  32. void Delay_Ms(INT16U ms)
  33. {
  34.      INT16U i;
  35.          do{
  36.               i = MAIN_Fosc / 96000;
  37.                   while(--i);   //96T per loop
  38.      }while(--ms);
  39. }
  40. /*us延时函数*/
  41. void Delay_us(uchar us)
  42. {
  43.         while(us--);
  44. }
  45. /*单总线初始化时序*/
  46. bit ds_init()
  47. {
  48.         bit i;
  49.         DS = 1;
  50.         _nop_();
  51.         DS = 0;
  52.         Delay_us(75); //拉低总线499.45us 挂接在总线上的18B20将会全部被复位
  53.         DS = 1; //释放总线
  54.         Delay_us(4); //延时37.95us 等待18B20发回存在信号
  55.         i = DS;
  56.         Delay_us(20); //141.95us
  57.         DS = 1;
  58.         _nop_();
  59.         return (i);
  60. }
  61. /*写一个字节*/
  62. void write_byte(uchar dat)
  63. {
  64.         uchar i;
  65.         for(i=0;i<8;i++)
  66.         {
  67.                 DS = 0;
  68.                 _nop_();//产生些时序
  69.                 DS = dat & 0x01;
  70.                 Delay_us(10);//76.95us
  71.                 DS = 1; //释放总线准备下一次数据写入
  72.                 _nop_();
  73.                 dat >>= 1;
  74.         }
  75. }
  76. /*读一个字节函数*/
  77. uchar read_byte()
  78. {
  79.         uchar i, j, dat;
  80.         for(i=0;i<8;i++)
  81.         {
  82.                 DS = 0;
  83.                 _nop_();//产生读时序
  84.                 DS = 1;
  85.                 _nop_();//释放总线
  86.                 j = DS;
  87.                 Delay_us(10);//76.95us
  88.                 DS = 1;
  89.                 _nop_();
  90.                 dat = (j<<7)|(dat>>1);       
  91.         }
  92.         return (dat);
  93. }

  94. void Display(INT16U Value)                        //注意由于需要显示的数大于一个字节所有形参需为int型
  95. {       
  96. //------------------------------
  97.         DU = 0;                                                        //关闭段选
  98.         P0 = table[Value/100];                //数码管显示百位
  99.         DU = 1;                                                        //打开段选
  100.         DU = 0;                                                        //关闭段选

  101.         WE = 0;                                                //关闭位选
  102.         P0 = T_COM[0];                                   //第一位数码管
  103.         WE = 1;                                                //打开位选
  104.         WE = 0;                                                //关闭位选
  105.         Delay_Ms(3);
  106. //-------------------------------
  107.         DU = 0;
  108.         P0 = table[Value%100/10]|0x80; //显示十位
  109.         DU = 1;
  110.         DU = 0;

  111.         WE = 0;
  112.         P0 = T_COM[1];                          //第二位数码管
  113.         WE = 1;
  114.         WE = 0;
  115.         Delay_Ms(3);
  116. //-------------------------------
  117.         DU = 0;
  118.         P0 = table[Value%10];                //显示个位
  119.         DU = 1;
  120.         DU = 0;

  121.         WE = 0;
  122.         P0 = T_COM[2];                                //第三位数码管
  123.         WE = 1;
  124.         WE = 0;
  125.         Delay_Ms(3);
  126. }

  127. void display()
  128. {
  129.         DU = 0;                                                        //关闭段选
  130.         P0 = table[d1];                //数码管显示百位
  131.         DU = 1;                                                        //打开段选
  132.         DU = 0;                                                        //关闭段选

  133.         WE = 0;                                                //关闭位选
  134.         P0 = T_COM[4];                                   //第一位数码管
  135.         WE = 1;                                                //打开位选
  136.         WE = 0;                                                //关闭位选
  137.         Delay_Ms(3);
  138. //-------------------------------
  139.         DU = 0;
  140.         P0 = table[d2]; //显示十位
  141.         DU = 1;
  142.         DU = 0;

  143.         WE = 0;
  144.         P0 = T_COM[5];                          //第二位数码管
  145.         WE = 1;
  146.         WE = 0;
  147.         Delay_Ms(3);
  148. //-------------------------------
  149.         DU = 0;
  150.         P0 = table[d3];                //显示个位
  151.         DU = 1;
  152.         DU = 0;

  153.         WE = 0;
  154.         P0 = T_COM[6];                                //第三位数码管
  155.         WE = 1;
  156.         WE = 0;
  157.         Delay_Ms(3);
  158.         //-------------------------------
  159.         DU = 0;
  160.         P0 = table[d4];                //显示个位
  161.         DU = 1;
  162.         DU = 0;

  163.         WE = 0;
  164.         P0 = T_COM[7];                                //第三位数码管
  165.         WE = 1;
  166.         WE = 0;
  167.         Delay_Ms(3);
  168. }

  169. /*自动按键扫描函数*/
  170. void key_scan()
  171. {
  172.         if(key_s1==0)
  173.         {
  174.                 Delay_Ms(5);//延时消抖
  175.                 if(key_s1==0)
  176.                 {
  177.                         flag=1;//进入设置状态
  178.                 }
  179.                 while(!key_s1);//松手检测
  180.         }
  181.         while(flag==1)//设置上限 flag=1
  182.         {
  183.                 dj=0;
  184.                 d1=17,d2=shang/10,d3=shang%10,d4=17;
  185.                 display();
  186.                 Display(wen) ;
  187.                 if(key_s1==0)//设置下限         flag=2
  188.                 {
  189.                         Delay_Ms(5);
  190.                         if(key_s1==0)
  191.                         {
  192.                                 flag=2;
  193.                         }
  194.                         while(!key_s1);
  195.                 }
  196.                 if(key_s2==0) //加
  197.                 {
  198.                         Delay_Ms(5);
  199.                         if(key_s2==0)
  200.                         {
  201.                                 shang+=1;
  202.                                 if(shang>=34)
  203.                                         shang=34;
  204.                         }
  205.                         while(!key_s2);
  206.                 }
  207.                 if(key_s3==0)//减
  208.                 {
  209.                         Delay_Ms(5);
  210.                         if(key_s3==0)
  211.                         {
  212.                                 shang-=1;
  213.                                 if(shang<=28)
  214.                                         shang=28;
  215.                         }
  216.                         while(!key_s3);
  217.                 }
  218.         }
  219.         while(flag==2)
  220.         {
  221.                 dj=0;
  222.                 d1=17,d2=xia/10,d3=xia%10,d4=17;
  223.                 display();
  224.                 Display(wen) ;
  225.                 if(key_s1==0)
  226.             {
  227.                     Delay_Ms(5);//延时消抖
  228.                         if(key_s1==0)
  229.                         {
  230.                                 flag=0;//退出设置状态
  231.                         }
  232.                         while(!key_s1);//松手检测
  233.                 }
  234.                 if(key_s2==0) //加
  235.                 {
  236.                         Delay_Ms(5);
  237.                         if(key_s2==0)
  238.                         {
  239.                                 xia+=1;
  240.                                 if(xia>=30)
  241.                                         xia=30;
  242.                         }
  243.                         while(!key_s2);
  244.                 }
  245.                 if(key_s3==0)//减
  246.                 {
  247.                         Delay_Ms(5);
  248.                         if(key_s3==0)
  249.                         {
  250.                                 xia-=1;
  251.                                 if(xia<=23)
  252.                                         xia=23;
  253.                         }
  254.                         while(!key_s3);
  255.                 }
  256.          }
  257. }
  258. void zi_dong()//自动温控函数
  259. {
  260.         uchar a;
  261.         d1=dang,d2=17,d3=17,d4=17;
  262.         display();
  263.         key_scan();
  264.         Display(wen) ;
  265.         if((wen/10)<xia)
  266.         {
  267.                 dj=0;
  268.                 dang=0;
  269.                 display();
  270.         }
  271.         if((wen/10)>=xia&&(wen/10)<shang)
  272.         {
  273.                 dang=1;
  274.                 for(a=0;a<3;a++)
  275.                 {
  276.                         dj=0;
  277.                         display();
  278.                         Display(wen) ;
  279.                         key_scan();
  280.                 } //PWM通过延时得到
  281.                 for(a=0;a<6;a++)
  282.                 {
  283.                         dj=1;
  284.                         display();
  285.                         Display(wen) ;
  286.                         key_scan();
  287.                 }
  288.         }
  289.         if((wen/10)>=shang)
  290.         {
  291.                 dj=1;
  292.                 dang=2;
  293.                 display();
  294.                 Display(wen) ;
  295.         }
  296. }
  297.        
  298. void main()
  299. {
  300.         uchar a,j,L,M;
  301.     ds_init();//初始化DS18B20
  302.         write_byte(0xcc);//发送跳跃ROM指令
  303.         write_byte(0x4e);//写暂存器指令
  304.         write_byte(0x7f);
  305.         write_byte(0xf7);
  306.         write_byte(0x1f);//配置工作在9位模式下
  307.         ds_init();//初始化DS18B20
  308.         write_byte(0xcc);//发送跳跃ROM指令
  309.         write_byte(0x48);
  310.         dj=0;
  311.         dang=0;
  312.         shang=29;
  313.         xia=27;//初始上下
  314.         while(1)
  315.         {
  316.                 display();
  317.                 ds_init();//初始化DS18B20
  318.                 write_byte(0xcc);//发送跳跃ROM指令
  319.                 write_byte(0x44);//发送温度转换指令
  320.                 ds_init();//初始化DS18B20
  321.                 write_byte(0xcc);//发送跳跃ROM指令
  322.                 write_byte(0xbe);//读取DS18B20暂存器值
  323.                 L = read_byte();
  324.                 M = read_byte();
  325.                 wen= M;
  326.                 wen<<= 8;
  327.                 wen|= L;                                               
  328.                 wen = wen* 0.0625 * 10 + 0.5;
  329.                 Display(wen);
  330.                 zi_dong();
  331.         }
  332. }
复制代码

所有资料51hei提供下载:
温控风扇.zip (35.57 KB, 下载次数: 20)

评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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