找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机检测电动机温度并控制电动的启停,LCD1602显示数据,按键输入设定温度

[复制链接]
跳转到指定楼层
楼主
这是我做去年做的设计,51单片机检测电动机温度并控制电动的启停同时蜂鸣器报警,LCD1602显示数据,按键输入设定温度.DS18B20测定温度。附件包含protues仿真图与单片机源码

选用51系列单片机或其他型号的单片机,设计步进电机温度监控电路。
一、设计DS18B20温度检测电路,当温度超过每个设定值的时候,可自动停止步进电机电机转动(可实现温度自动控制);
二、根据需要将温度值显示在数码管上(本次设计个人采用LCD1602显示屏),显示相应的输入参数;
三,可通过按键改变温度设定值。


本设计的整体思路是:首先利用温度传感器DS18B20检测环境温度并直接输出数字温度信号给单片机AT89C52进行处理,在LCD1602显示屏上显示当前环境温度值与设定温度值。其中设定温度值只能为三位整数加两位小数形式,最高设定温度为655摄氏度。检测到的当前环境温度可精确到小数点后两位。通过十三个按键改变预设温度值,其中十一个键设定温度,另两个确认与取消设定温度值。防误触碰系统,当不知情误碰按键的情况下,系统自动显示按键值在若干秒后没有得到确定命令时自动回归显示设定值。在触发温度报警后电机停转、峰鸣报警,其余各部件正常工作,必须等电机温度下降低于40摄氏度且低于设定温度电机自动开始工作。系统结构框图如图一所示:

图一 系统构成框图

2.2 方案选择

本设计要实现直流电机的温度控制,使电机能根据环境温度的变化自动启停与报警,需要比较高的温度变化分辨率以及稳定可靠的换挡停机控制部件。

2.3 温度传感器的选择

采用数字式的集成温度传感器DS18B20作为温度检测的核心元件,由其检测并直接输出数字温度信号给单片机进行处理。
原理图如图六:

图六 原理图

3.6 PCB图

PCB图如图七:
图七 PCB图



5 系统调试仿真

程序中温度的设定值为60℃,即当温度大于或等于60℃时,电机自动停机。可通过按键改变设定值。

5.1 电机正常工作

在Proteus软件中调节温度传感器温度到37℃,电机正常工作。下图分别为LCD1602,温度传感器,电机仿真图。
分别如图九、图十:

图九 LCD1602

         

图十 温度传感器与电机


5.2 电机停止工作

在Proteus软件中调节温度传感器温度到61℃,电机停止工作。下图分别为1602,温度传感器,电机仿真图。
分别如图十一、图十二:

图十一 LCD1602

        

图十二 温度传感器与电动机

5.3 按键改变设定温

按键改变设定值如图十三、图十四:

               

图十三 默认设定温度                              图十四 按键改变设定温度



6总结

,本人首次学习、采用分层编程思想,在c51语言的编写上大大的减少了程序的复杂性,为今后的编程打下了坚实的基础。通过对各种传感器、芯片、元件的使用,我了解了传感器的基本理论知识,更深入的了解单片机的开发应用和PC编程控制,同时也让我明白各种芯片元件、传感器的出厂数据对于我们编写程序有着不可忽略的作用。总的来说,这次学习为我们以后从事单片机软硬件产品的设计开发、PC软件开发打下了良好的基础,树立独立从事产品研发的信心,同时也培养了我们认真的做事态度与动手实践的能力。学以致用,用以温学,这个过程就是经验知识与动手能力的双重收获过程。
本设计的重点、难点是:
(1) 要掌握温度传感器的原理、结构、应用;LCD1602的原理、结构、应用。
(2) 考虑从非电量信号到电量信号的电路实现原理以及与单片机的接口;
(3) 熟悉c51编程的技术,实现单片机对温度的调节控制;
(4) 整体电路的仿真调试。
本次设计优点:采用的单片机AT89C52 性价比高;热敏电阻温度传感器转化温度的方法非常简洁且精度高、测试范围较广;LCD1602显示简洁明了。’
实物图如图十五:


图十五 实物图

单片机源程序:
  1. /*********************************************************************
  2. **********************************************************************
  3. 实验任务: 驱动DS18B20检测温度值并显示在LCD1602上。按键输入设置温度,显示
  4.           在LCD1602上控制电机运行,检测温度超过设定值,电机停止运行。电机
  5.                   停止运行后当电机温度下降到50摄氏度以下,电机重新运行。               
  6. 实现现象:程序执行后LCD1602上面一排显示温度值,格式类似于:"ACT T:031.28℃"
  7.          (表示实际温度)在LCD1602下面一排显示设定温度值,
  8.                   格式类似于:"Seted T:055.29℃"(表示设定好的温度值)
  9.                               "STING T:55.02℃" (表示正在设定的温度值)
  10.                    如果输入错误或超出量程LCD1602下面一排显示"set  error"后显示上一次设定的
  11.                    有效值
  12. 注意事项:温度输入范围(0~~655℃)初始报警温度60度                                                                                          
  13. **********************************************************************/

  14. /*
  15. **********************************************************************
  16. *                         本地宏定义
  17. **********************************************************************
  18. */
  19. #include "ds18b20.h"                //温度采集程序
  20. #include "lcd1602.h"                 //液晶屏程序
  21. #define moto        P1                // 矩阵按键接在P1端口
  22. sbit qxkey=P3^0        ;// 独立按键 取消键
  23. sbit move=P1^0        ;// 电动机
  24. sbit k1=P1^1;         //        按键值
  25. sbit k2=P1^2;           //**
  26. sbit k3=P1^3;           //**
  27. sbit k4=P1^4;           //**
  28. sbit k5=P1^5;           //**
  29. sbit k6=P1^6;           //**
  30. sbit k7=P1^7;           //**

  31. /*
  32. **********************************************************************
  33. *                         本地全局变量
  34. **********************************************************************
  35. */
  36. unsigned int zcsj=0;                //暂存输入设定值整数部分
  37. unsigned int zcxs=0;                //暂存输入设定值小数部分
  38. unsigned char zc;                        //一位输入设定值暂存
  39. unsigned char xsd=0;           //判断是否有小数点xsd
  40. unsigned char i=8;                        //输入显示x位置坐标值
  41. unsigned char j=0;                        //输入整数数字位数值
  42. unsigned char xsdw=0;                //输入小数数字位数
  43. unsigned int chssj=6000;        //初始温度设定值100度
  44. unsigned int tdisp;                        //实际温度值
  45. unsigned char  cs=0;                //整个程序循环次数,目的当有键值输入但没有确认或取消
  46.                                                           // 在程序执行20次以后自动恢复原来的设定值
  47. unsigned char key = 0;                 // 实时获取的扫描键值
  48. unsigned char h = 0;                 //按键行值
  49. unsigned char l = 0;                 //按键列值
  50. /*
  51. **********************************************************************
  52. *                         函数原型声明
  53. **********************************************************************
  54. */
  55. void TempDisplayTest(void);           //温度传感器显示函数
  56. void delay1ms(void);                   //延时1ms
  57. void delay1s(void) ;                   //延时1s
  58. void keypanduan(void);                   //判断按键值
  59. void baojin(void);                                //温度超过设定值蜂鸣器工作
  60. void delay100us(void);
  61. /*********************************************************************
  62. * 函 数 名       : main
  63. * 函数功能                 : 主函数
  64. * 参数列表       : 无
  65. * 函数输出             : 无
  66. *********************************************************************/
  67. void main(void)
  68. {
  69.    
  70.         Lcd1602Init();
  71.         move=1;
  72.         Lcd1602ShowStr(0, 0, "ACT T:");
  73.         Lcd1602ShowStr(0, 1, "Seted T:");
  74.         Lcd1602ShowTempU16(8, 1, chssj);
  75.         while (1)
  76.         {
  77.         uchar key = 0;                          // 实时获取的扫描键值
  78.         uchar h = 0;                        // 行键值
  79.         uchar l = 0;                        //列键值
  80.         while (1)
  81.         {
  82.          TempDisplayTest();
  83.          keypanduan();
  84.          cs++;
  85.         if(chssj<tdisp){move=0;baojin();}//电动机控制程序
  86.     else if(tdisp<4000)move=1;
  87.         }
  88.         }
  89. }




  90. void TempDisplayTest(void)
  91. {
  92.         extern Ds18b20ReadByte();                 //声明变量
  93.         u16 temp = 0;                                         // 用来暂存12位的AD值
  94.         u8 tmh = 0 ;
  95.         u8 tml = 0;                        // 用来暂存2个8位的AD值
  96.         u16 tDisp = 0;                                        // 用来存储乘以100倍后的温度值
  97.         double t = 0;                                        // 用来存储转换后以摄氏度为单位的温度值

  98.         Ds18b20TempConvertCmd();                // 先写入转换命令
  99.         Ds18b20TempReadCmd();                        // 然后等待转换完后发送读取温度命令
  100.         tml = Ds18b20ReadByte();                // 读取温度值共16位,先读低字节
  101.         tmh = Ds18b20ReadByte();                // 再读高字节

  102.         temp = tml | (tmh << 8);                // 默认是12位分辨率,前面4个S位是符号位
  103.         
  104.         // 正温度时符号位为0,下面代码计算没有考虑负温度情况,因为我们实验是在
  105.         // 室温下做的,如果要考虑到负温度的情况,代码中要先判断S位,若S位为1则
  106.         // 必须点去掉S的1再计算,计算后的值加负号即可。
  107.         t = temp * 0.0625;
  108.         tDisp = (u16)(t * 100);                        // 为方便显示将温度值乘以100后强转为u16

  109.         // 调用LCD1602的显示函数来显示乘以100倍后的温度值
  110.         tdisp=tDisp;
  111.         Lcd1602ShowTempU16(6, 0, tDisp);

  112. }
  113. /*********************************************************************
  114. * 函 数 名       : keypanduan
  115. * 函数功能                 : 输入报警设置温度
  116. * 参数列表       : 无
  117. * 函数输出             : 无
  118. *********************************************************************/
  119. void keypanduan(void)
  120. {
  121.                       key = 0;
  122.                         h=0;
  123.                         l=0;                        
  124.         if(qxkey==0){              //独立按键取消程序
  125.                          Lcd1602ShowStr(0, 1, "Seted T:");
  126.             Lcd1602ShowTempU16(8, 1, chssj);
  127.                 j=0;i=8;xsdw=0;xsd=0;zcsj=0;zcxs=0;cs=0; }
  128.     if(cs==20){                                                                           //输入等待程序
  129.                                  Lcd1602ShowStr(0, 1, "Seted T:");
  130.                      Lcd1602ShowTempU16(8, 1, chssj);
  131.                      j=0;i=8;xsdw=0;xsd=0;zcsj=0;zcxs=0;cs=0;}
  132.         //判断按键值程序
  133.     k1=1;k2=1;k3=1;k4=0;k5=0;k6=0;k7=0;// P1.1-1.3输出高电平,P1.4-P1.7输出低电平
  134.         if (k1!=1||k2!=1||k3!=1)        // 读取KEY_PORT看是否有按键按下
  135.         {
  136.                 delay100us();                // 延时消抖
  137.                 if (k1!=1||k2!=1||k3!=1)                // 确认确实有按键按下
  138.                 {        
  139.                         Lcd1602ShowStr(i, 1, "         ");
  140.                         // 先确定按键发生在第几列
  141.                          l=k3*8+k2*4+k1*2;
  142.                         switch (l)
  143.                         {
  144.                                 case 0x0c :        key = 1;         break;
  145.                                 case 0x0a :        key = 2;        break;
  146.                                 case 0x06 : key = 3;        break;
  147.                                 default          :                         break;
  148.                         }

  149.                         // 再确定按键发生在第几行
  150.                    k1=0;k2=0;k3=0;k4=1;k5=1;k6=1;k7=1;
  151.                         if(k4==1)h=k7*8+k6*4+k5*2+1;
  152.                         if(k4==0)h=k7*8+k6*4+k5*2;
  153.                           switch (h)
  154.                         {
  155.                                 case 7:        key = key + 0;        break;
  156.                                 case 11:        key = key + 3;        break;
  157.                                 case 13:         key = key + 6;        break;
  158.                                 case 14:  key = key + 9;        break;
  159.                         }
  160.                 if (key != 0&&key!=12)                // 有按键按下
  161.                 {
  162.                   zc=key; Lcd1602ShowStr(0, 1, "STING T:");
  163.                   if(key==10)zc=0;
  164.                   if(key==11){xsd++;zc=0;Lcd1602ShowStr(i, 1, ".");Lcd1602ShowshujuU16(i+1, 1,zc);}
  165.           else Lcd1602ShowshujuU16(i, 1,zc );i++;
  166.                   if(key!=11&&key!=12&&xsd==0){zcsj=zcsj*10+zc;j++;}
  167.                   if(key!=11&&key!=12&&xsd!=0){zcxs=zcxs*10+zc;j++;xsdw++;}
  168.                   }
  169.                   //判断输入值为多少,是否有效        
  170.                 if(((xsd==0&&j<4&&zcsj<656)||(xsd==1&&j<6&&xsdw<3)))//确认输出设定值
  171.                 {                                 
  172.                   if(key==12&&(zcsj!=0||zcxs!=0)){
  173.                             if(xsdw==1) zcsj=zcsj*100+zcxs*10;
  174.                                 else        zcsj=zcsj*100+zcxs;
  175.                                                    Lcd1602ShowStr(0, 1, "Seted T:");
  176.                                    Lcd1602ShowTempU16(8, 1, zcsj);
  177.                                    chssj=zcsj;
  178.                                                    j=0;i=8;xsdw=0;xsd=0;zcsj=0;zcxs=0;cs=0;}
  179.                    else if(key==12&&zcsj==0&&zcxs==0){Lcd1602ShowTempU16(8, 1, chssj);}
  180.                                                     }
  181.                  else {Lcd1602ShowStr(0, 1, "  set  error  ");
  182.                            delay1s();
  183.                            Lcd1602ShowStr(0, 1, "             ");
  184.                            Lcd1602ShowStr(0, 1, "Seted T:");
  185.                             Lcd1602ShowTempU16(8, 1, chssj);
  186.                            j=0;i=8;xsdw=0;xsd=0;zcsj=0;cs=0;}
  187.             }
  188.         }         
  189.         
  190. }
  191. /*********************************************************************
  192. * 函 数 名       :
  193. * 函数功能                 : 以下函数为延时函数
  194. * 参数列表       : 无
  195. * 函数输出             : 无
  196. *********************************************************************/
  197. void delay100us(void)   //误差 0us
  198. {
  199.     unsigned char a,b;
  200.     for(b=71;b>0;b--)
  201.         for(a=2;a>0;a--);
  202. }

  203. void delay1ms(void)   //误差 0us
  204. {
  205.     unsigned char a,b,c;
  206.     for(c=1;c>0;c--)
  207.         for(b=124;b>0;b--)
  208.             for(a=2;a>0;a--);}
  209. void delay1s(void)   //误差 0us
  210. {
  211.     unsigned char a,b,c;
  212.     for(c=167;c>0;c--)
  213.         for(b=171;b>0;b--)
  214.             for(a=16;a>0;a--);
  215.     _nop_();  //if Keil,require use intrins.h
  216. }
  217. /*********************************************************************
  218. * 函 数 名       : baojin
  219. * 函数功能                 : 峰鸣器工作
  220. * 参数列表       : 无
  221. * 函数输出             : 无
  222. *********************************************************************/
  223. void baojin(void)
  224. {
  225. uint a;
  226. for(a=0;a<150;a++){k5 = 1;delay100us();k5 = 0;delay100us();}
  227. }
复制代码


全部资料51hei下载地址:
课设原理图及说明书.zip (7.21 MB, 下载次数: 88)
课设程序.zip (67.9 KB, 下载次数: 94)
PCB_NEW-PCB_20180627001603.pdf (18.82 KB, 下载次数: 33)
说明书.pdf (1.07 MB, 下载次数: 45)

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:494382 发表于 2019-3-20 14:54 | 只看该作者
就是直接可以控制电机启停吗?不用加继电器吗?
回复

使用道具 举报

板凳
ID:710428 发表于 2020-3-18 20:16 | 只看该作者
cactus_lee 发表于 2019-3-20 14:54
就是直接可以控制电机启停吗?不用加继电器吗?

是的
回复

使用道具 举报

地板
ID:633070 发表于 2020-5-17 13:07 | 只看该作者
有dns吗
回复

使用道具 举报

5#
ID:457709 发表于 2020-5-20 16:17 | 只看该作者
很有用的资料,给楼主一个赞
回复

使用道具 举报

6#
ID:995584 发表于 2021-12-23 01:01 | 只看该作者
这个的程序的头文件在第2个压缩包里面
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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