找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6419|回复: 3
打印 上一主题 下一主题
收起左侧

单片机MAX6675 K型热电偶温度(可调上限下限)控制直流电机(正反转)L298驱动

  [复制链接]
跳转到指定楼层
楼主
基于AT89C52设计的温度调节控制直流电机,可以通过4*4按键设定经过MAX6675驱动的K型热电偶转化的温度上限与下限,高于上限电机正转,低于下限电机反转,处于正常温度电机停止转动。文件包含具体论文说明,理论与原理描述。

带proteus仿真工程文件,附件里面可以下载.
整个温度控制直流电机正反转系统的仿真原理图:


51单片机源程序:
  1. #include <reg51.h>
  2. #include <Intrins.h>
  3. #include <LCD1602.H>
  4. #include <math.H>

  5. #define C02_write 0xa0 //c02写地址
  6. #define C02_read  0xa1 //c02读地址
  7. #define uchar unsigned char
  8. #define uint unsigned int

  9. sbit MAX6675_CS=P1^2;    //MAX6675冷端温度补偿,将K型热电偶信号转为数字信号
  10. sbit MAX6675_SCK=P1^1;
  11. sbit MAX6675_SO=P1^0;
  12. sbit normal=P2^3;        //LED灯表示温度正常,过高,过低
  13. sbit upper=P2^4;
  14. sbit lower=P2^5;
  15. sbit direction=P2^6;   
  16. sbit stop=P2^7;
  17. sbit SCL=P1^3;    //EEPROM,256byte
  18. sbit SDA=P1^4;
  19. sbit beep=P1^7;   //蜂鸣器
  20. bit ack,flag=0,flag1=0;

  21. uint  tz;
  22. int sth=0,stl=0,t_zhi=0;
  23. uchar data temp1[]={'+','1','2','0','0',0},temp2[]={'-' ,'1','0','0','0',0};
  24. uchar data temp[7];
  25. char code keytab[]={0xEE,0xDE,0xBE,0x7E,0xED,0xDD,0xBD,0x7D,0xEB,0xDB,0xBB,0x7B,0xE7,0xD7,0xB7,0x77};
  26. unsigned char code str1[]={"STH      STL"}; //system temperature high,low
  27. unsigned char code str2[]={"PARAMTER STEUP"};
  28. unsigned char code str3[]={"              "};
  29. unsigned int testD2;
  30. unsigned char data disdata[5];
  31. void delay0(uchar x)    // 延时函数
  32. {
  33.    uchar i;
  34.    while(x--)
  35.    {
  36.      for (i=0; i<13; i++);
  37.    }
  38. }
  39. void delayms(uchar i)
  40. {
  41.         uchar j;
  42.         for(; i>0; i--)
  43.         for(j=124; j>0; j--);
  44. }

  45. void longdelay(uchar i)
  46. {
  47.         uint  j;
  48.         for(;i>0;i--)
  49.         for(j=10000;j>0;j--);
  50. }

  51. void keysound()   //按键声音函数
  52. {
  53.   uchar i;
  54.   for (i=0;i<180;i++)
  55.   {
  56.     delay0(5);
  57.     beep=!beep;   //BEEP取反
  58.   }
  59. }

  60. void I2C_start(void)  //I2C开始信号
  61. {
  62.         SDA=1;        SCL=1;
  63.         _nop_();        _nop_();        _nop_();        _nop_();        _nop_();
  64.         SDA=0;
  65.         _nop_();        _nop_();        _nop_();        _nop_();        _nop_();
  66.         SCL=0;        _nop_();        _nop_();
  67. }

  68. void I2C_stop(void) //I2C结束
  69. {
  70.         SDA=0;        SCL=1;
  71.         _nop_();        _nop_();        _nop_();        _nop_();        _nop_();
  72.         SDA=1;
  73.         _nop_();        _nop_();        _nop_();        _nop_();        _nop_();
  74.         SCL=0;
  75.         _nop_();        _nop_();
  76. }
  77. void I2C_no_ackownledge(void) //发送noack信号
  78. {
  79.         SDA=1;
  80.         _nop_();        _nop_();
  81.         SCL=1;
  82.         _nop_();        _nop_();        _nop_();        _nop_();        _nop_();
  83.         SCL=0;
  84.         _nop_();        _nop_();        _nop_();
  85. }

  86. void I2C_sendB(uchar byte)//发送一字节数据
  87. {
  88.         uchar counter;
  89.         for(counter=0;counter<8;counter++)
  90.         {
  91.                 if(byte&0x80)        SDA=1;
  92.                 else        SDA=0;
  93.                 _nop_();
  94.                 SCL=1;
  95.                 _nop_();        _nop_();        _nop_();        _nop_();        _nop_();
  96.                 SCL=0;
  97.                 _nop_();        _nop_();
  98.                 byte<<=1;
  99.         }
  100.         _nop_();        _nop_();
  101.         SDA=1;
  102.         _nop_();        _nop_();        _nop_();
  103.         SCL=1;
  104.         _nop_();        _nop_();        _nop_();
  105.         if(SDA==0)        ack=1;
  106.         else         ack=0;
  107.         SCL=0;
  108.         _nop_();        _nop_();
  109. }
  110.         
  111. uchar I2C_receiveB(void) //接收一字节数据
  112. {
  113.         uchar temp;
  114.         uchar counter;
  115.         temp=0;
  116.         SDA=1;
  117.         _nop_();        _nop_();
  118.         for(counter=0;counter<8;counter++)
  119.         {
  120.                  _nop_(); _nop_(); _nop_();
  121.                  _nop_(); _nop_();
  122.                  SCL=1;
  123.                  _nop_();
  124.                  _nop_();
  125.                  if(SDA==1)        temp=(temp<<1)|0x01;
  126.                  else        temp=temp<<1;
  127.                  _nop_(); _nop_();
  128.             SCL=0;
  129.                  _nop_(); _nop_(); _nop_();
  130.         }
  131.         _nop_();        _nop_();
  132.         return(temp);
  133. }

  134. bit I2C_send_string(uchar *string,uchar no,uchar address)  //发送8位温度
  135. {
  136.         uchar counter;
  137.         for(counter=0;counter<no;counter++)
  138.         {
  139.                 I2C_start();
  140.                 I2C_sendB(C02_write);
  141.                 if(ack==0) return(0);
  142.                 I2C_sendB(address+counter);
  143.                 if(ack==0) return(0);
  144.                 I2C_sendB(string[counter]);
  145.                 I2C_stop();
  146.                 delayms(20);               
  147.         }
  148.         return(1);
  149. }

  150. bit I2C_receive_string(uchar *string,uchar no,uchar address) //接收8位温度
  151. {
  152.         uchar counter;
  153.         for(counter=0;counter<no;counter++)
  154.         {
  155.                 I2C_start();
  156.                 I2C_sendB(C02_write);
  157.                 if(ack==0) return(0);
  158.                 I2C_sendB(address+counter);
  159.                 if(ack==0) return(0);
  160.                 I2C_start();
  161.                 I2C_sendB(C02_read);
  162.                 if(ack==0) return(0);
  163.                 *(string+counter)=I2C_receiveB();
  164.                 I2C_no_ackownledge();
  165.                 I2C_stop();
  166.         }
  167. }

  168. //温度值读取程序
  169. unsigned int ReadMAX6675()  //从MAX6675读取温度
  170. {
  171. unsigned char count;
  172. unsigned int Value;
  173. MAX6675_CS=0;    //置低,使能MAX6675
  174. MAX6675_SCK=0;
  175. Value=0;
  176. _nop_() ;_nop_();_nop_();_nop_();
  177. for(count=0;count<16;count++)  //获取16位MSB
  178. {
  179.   Value=Value<<1;  //左移
  180.   MAX6675_SCK=1;   //sck置高
  181.   _nop_() ;_nop_();_nop_();_nop_();
  182.   if(MAX6675_SO==1)  //取当前值
  183.      Value|=0x01;
  184.      MAX6675_SCK=0;
  185. }
  186. MAX6675_CS=1;  //关闭MAX6675
  187. return Value;
  188. }

  189. unsigned int GetCurrentTemp(unsigned int CurrentValue)  //获取当前温度
  190. {
  191.   unsigned int TempValue;
  192.   TempValue=CurrentValue;
  193.   if(TempValue&0x8000)  //D15=1;标识位错
  194.   return 0;
  195.   if(TempValue&0x0004)  //D2=1;热电偶开路
  196.   return 1;
  197. }

  198. void tempdisp()         //温度值显示
  199. { unsigned char i;
  200.   unsigned int TempValue;
  201.   unsigned int testD2;
  202.   int xiaoshu;
  203.   TempValue=ReadMAX6675();
  204.   testD2=GetCurrentTemp(TempValue);
  205.   TempValue=ReadMAX6675();
  206.   TempValue&=0x7ff8;   //取D14位到D3的值
  207.   TempValue>>=3;       //转换温度值
  208.   xiaoshu= (TempValue*1023.75/4095)*10-327;
  209.   t_zhi=xiaoshu/10;
  210.   disdata[0]=xiaoshu/10000+0x30; //千位数
  211.   xiaoshu=xiaoshu%10000;
  212.   disdata[1]=xiaoshu/1000+0x30; //百位数
  213.   xiaoshu=xiaoshu%1000;
  214.   disdata[2]=xiaoshu/100+0x30;  //十位数
  215.   xiaoshu=xiaoshu%100;
  216.   disdata[3]=xiaoshu/10+0x30;   //个位数
  217.   xiaoshu=xiaoshu%10;
  218.   disdata[4]=xiaoshu/1+0x30;    //十分位
  219.   LCD_set_position(68);
  220.   for(i=0;i<4;i++)
  221.   LCD_write_data(disdata[i]);  //显示千百十个位
  222.   LCD_write_data('.');         //显示小数点   
  223.   LCD_write_data(disdata[4]);  //显示十分位
  224.   LCD_write_data(0xDF);        //显示dot
  225.   LCD_write_data(0x43);        //显示C
  226.   if(t_zhi>sth){ normal=0; upper=1;lower=0;stop=1;direction=1;}        //高于上限
  227.   else if(t_zhi<stl){ normal=0; upper=0;lower=1;stop=1;direction=0;}   //低于下限
  228.   else { normal=1; upper=0;lower=0;stop=0;direction=0;}                //正常
  229. }

  230. //返回-1表示没有检测到按键按下
  231. char getkey(void)
  232. { unsigned char  scancode,tmpcode, key_zhi=0;
  233.   P3 = 0xf0;                                                // 发全0行扫描码
  234.   if ((P3&0xf0)!=0xf0)                                        // 若有键按下
  235.         { delayms(5);                                        // 延时去抖动
  236.           if ((P3&0xf0)!=0xf0)                                // 延时后再判断一次,去除抖动影响
  237.                 { scancode = 0xfe;
  238.                   while((scancode&0x10)!=0)                // 逐行扫描
  239.                   { P3 = scancode;                        // 输出行扫描码
  240.                     if ((P3&0xf0)!=0xf0)                // 本行有键按下
  241.                         { tmpcode = P3;           // 返回特征字节码
  242.                           while((P3&0xf0)!=0xf0);
  243.                           key_zhi=0;
  244.                      while(tmpcode!=keytab[key_zhi])
  245.                       key_zhi++;
  246.                           return( key_zhi++);
  247.                         }
  248.                      else scancode = (scancode<<1)|0x01;// 行扫描码左移一位
  249.                   }
  250.            }
  251. }
  252.   return(-1);                                        // 无键按下,返回值为0         
  253. }

  254. void timer0() interrupt 1 using 0
  255. {
  256.         TR0=0;
  257.         TH0=(65536-10000)/256;
  258.         TL0=(65536-10000)%256;
  259.         TR0=1;
  260.         tz++;
  261. }

  262. void main()
  263. {
  264.         uchar kcode,count1=3,count2=12,i;
  265.   normal=0;
  266.   upper=0;
  267.   lower=0;
  268.   TMOD=0X01;
  269.   TH0=(65536-10000)/256;
  270.   TL0=(65536-10000)%256;
  271.   ET0=1;
  272.   TR0=0;
  273.   LCD_initial();
  274.   LCD_cls();
  275.   LCD_set_position(0);
  276.   LCD_prints(str1);
  277.   LCD_set_position(3);

  278.   I2C_receive_string(temp1,5,0x00);
  279.   I2C_receive_string(temp2,4,0x10);
  280.   //change_data();
  281.   LCD_prints(temp1);           //显示上限
  282.   LCD_set_position(12);
  283.   LCD_prints(temp2);           //显示上限
  284.   sth=0;stl=0;
  285.   for(i=1;i<5;i++)
  286.   sth=sth*10+temp1[i]-'0';
  287.   for(i=1;i<4;i++)
  288.   stl=stl*10+temp2[i]-'0';

  289.   MAX6675_CS=1; //复位MAX6675
  290.   while(1)
  291.   {
  292.                 if(flag==0)
  293.     {
  294.            tempdisp();
  295.     }
  296.     kcode=getkey();
  297.     if(kcode==12&&flag==0)
  298.     {
  299.                  flag=1;sth=0;stl=0;
  300.            keysound();
  301.            LCD_set_position(0x41);
  302.      LCD_prints(str2);
  303.      LCD_set_position(count1);
  304.                  LCD_write_instruction(0x0f);         //光标闪烁
  305.           }  
  306.     if(flag)
  307.            {
  308.                          if(kcode>=0&&kcode<=9)
  309.        {
  310.                      if(flag1==0&&count1!=3)           //设置上限温度
  311.                      {
  312.                                         LCD_set_position(count1);
  313.                       sth=sth*10+kcode;
  314.                       LCD_write_data(kcode+0x30);
  315.                             keysound();
  316.           temp1[count1-3]=kcode+0x30;
  317.           count1++;
  318.           if(count1==8)
  319.           {
  320.            flag1=1;count1=12,count2=12;
  321.           }
  322.                       LCD_set_position(count1);
  323.                      }
  324.                      if(flag1==1&&count2!=12)          //设置下限温度
  325.          {
  326.                                         LCD_set_position(count2);
  327.                      

  328. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


下载:
7-温度控制直流电机.zip (845.7 KB, 下载次数: 226)

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏9 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:89286 发表于 2017-4-7 21:43 | 只看该作者
thanks for sharing
回复

使用道具 举报

板凳
ID:235856 发表于 2017-10-14 11:26 | 只看该作者
想下载,可以运行吗
回复

使用道具 举报

地板
ID:357980 发表于 2018-6-25 13:32 | 只看该作者
谢谢楼主
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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