找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机测温系统设计报告 含上位机与下位机程序与实物制作

[复制链接]
跳转到指定楼层
楼主
ID:232645 发表于 2017-9-12 18:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机接口设计报告
——测温系统设计

姓名安洁
学号201*815
班级试1504班     
时间2017/6/29 ~ 2017/7/8  

目录
一、 设计内容与要求
二、 设计方案
三、 方案实现
3.1系统的软件设计
1、 主程序
2、 AD转换程序
3、 温度显示程序
4、 步进电机控制程序
5、 中断系统程序
3.2系统的硬件设计
1、 时钟电路
2、 复位电路
3、 AD转换
4、 步进电机
5、 数码显示
6、 串口通信
7、 完整原理图
四、 系统调试
1、功能子程序的调试
2、程序流程的调试
3、程序的通调
五、 结论
参考文献
附录

1、设计内容与要求

1、通过按键设置温度上、下限,基准温度20℃,AD信号的0V~5V对应-20℃~70℃。

2、读入A/D转换数据,若数据<=下限,则显示温度、温度调节范围并显示L,并使步进电机正转,若数据>上限,则显示温度、温度调节范围并显示H,并使步进电机反转,下限<若数据<=上限,则显示温度、温度调节范围并显示C,步进电机不转动。

3、本机地址为08H,当接到上位机发的08H(P1.0口接开关,高电平发送)时,则回发08H,且本机P1.4口输出高电平,上位机接受后P1.3口输出高电平。

当接到上位机发的AAH(P1.1口接开关,高电平发送)时,则将当前温度发给上位机,且本机P1.5口输出高电平,上位机数码管显示温度。

当收到上位机发的55H(P1.2口接开关,高电平发送)时,下位机修改设定上、下限,且本机P1.6口输出高电平,数码管全部显示0。

当收到上位机发送的信号不是上面三个时,本机P1.7口输出高电平,数码管全部显示0。

2、设计方案

本设计采用AT89C51单片机实现。单片机软件编程的自由度大,可通过编程实现各种各样的算术算法和逻辑控制,而且体积小,硬件实现简单,安装方便,可以与PC机进行通信。

本设计利用单片机最小系统和ADC0809芯片、电位计设计温度采集系统。并设计一个人机接口电路:键盘采用独立式按键(功能是调节温度的上下限),同时设计了步进电机控制电路,显示器采用共阴极LED显示。系统的总体设计方案框图如图1所示:

图1

按照系统设计功能的要求,系统主要由单片机、ADC0809芯片、电位器、步进电机、LED数码显示管和PC机等组成,如图2所示:

图2

系统的硬件电路主要由复位电路、显示电路、AD转换电路、步进电路控制电路、晶振电路组成,系统总体结构方框图如图3所示:

图3

3、方案实现3.1系统的软件设计

本系统的软件设计主要可分为主程序,AD转换程序,温度显示程序,步进电机控制程序,中断系统程序等几个模块。

1、主程序

⑴功能

主程序的主要功能是负责读取当前温度,并进行判断,从而实时显示温度并根据判断结果控制步进电机的工作。

⑵程序流程图

如图4所示:

图4

2、AD转换程序

⑴功能

AD转换程序分为AD采样程序和采样温度转换程序两部分。其中,AD采样程序的功能是启动AD转换并在100μs的延时后得到AD采样值;采样温度转换程序的功能是得到16次AD采样值,然后取平均值,得到平均AD采样值,并通过公式将平均AD采样值转换为实际温度。

⑵程序流程图

如图5所示:

图5

3、温度显示程序

⑴功能

温度显示程序分为数码管温度显示程序和显示数据刷新程序。数码管温度显示程序的功能是将数码管需要显示的温度与温度上下限进行比较,并送入相应的段码,让数码管显示温度的正负(若为正显示0,若为负显示负号)、当前温度、温度状态(L、C、H)以及温度上下限的范围;显示数据刷新程序的功能是利用定时器T0,定时1ms,每隔1ms从右到左依次点亮数码管,并进行循环,数码管能够进行动态、平稳的显示。

⑵程序流程图

如图6所示:

图6

4、步进电机控制程序

⑴功能

步进电机控制程序的功能是通过判断步进电机工作方式控制位,控制步进电机的正转以及反转。

⑵程序流程图

如图7所示:

图7

5、中断系统程序

⑴功能

中断系统程序分为温度上下限设定程序和串口通信程序。温度上下设定程序的功能是通过两个外部中断程序,采用下降沿触发方式并设置两个按键来设定上下限;串口通信程序的功能是通过串口中断,并选择串行口方式2的工作方式,进行数据的接受和发送。

⑵程序流程图

如图8所示:

图8

3.2系统的硬件设计

本系统的硬件设计主要可分为时钟电路、复位电路、AD转换、步进电机、数码显示及串口通信等几个模块。

1、时钟电路

如图9:

图9

2、复位电路

如图10:

图10

3、AD转换

如图11:

图11

4、步进电机

如图12:

图12

5、数码显示

如图13:

图13

6、串口通信

如图14:

图14

7、完整原理图

如图15:

图15

4、系统调试

系统的软件调试借助于Lab6000通用微控制器实验系统。在进行系统软件的连续调试之前要先进行软件的初调,就是要使各个子程序模块运行正确,程序的运行流程正确。软件调试主要分以下几个步骤进行:

1、功能子程序的调试

功能子程序的调试包括AD转换、温度显示以及步进电机控制等子程序的调试。在调试功能子程序时,许多参数都是未知的,要根据其所需的条件,给出假定的数据,使其运行,如果能完成预定的处理功能或与手工计算的结果相符,就说明该子程序己调试通过。调试时由小到大,由里到外。例如,调试温度显示子程序时,先调通其需要的AD转换子程序和参数处理子程序,然后将它们连起来进行通调。通调时,也是假定一些数据、参数和初始条件,然后运行程序。当运算结果与手工计算的结果相同时,该算法子程序则调试完成,反之,就要进行相应的修改。其它子程序的调试同理。

2、程序流程的调试

程序流程的调试主要是查看程序运行的步骤是否正确,在某时刻程序运行所处的位置是否正确,是否能正确运行各个中断服务程序。在调试过程中,在各个中断服务子程序设置断点,然后运行程序,查看程序是否能运行到所有的断点,若所有断点都能运行到,则程序流程基本正确。

3、程序的通调

在完成整个程序流程的调试后,运行程序,进行程序的通调,通过器件的现象来判断程序的正确性。若不正确则设置断点检查错误。

如图16为上位机调试实物图:

图16

如图17为下位机调试实物图:

图17

5、结论

本次测温系统设计主要由AT89C51和ADC0809来实现功能。因此需要通过查阅资料来了解这些器件的基本结构,主要功能和注意事项等等。

整个设计从确定题目,到寻找相关资料,再到选择合适的器件,接着对电路图的绘制,程序的编写,最终调试。一步步走过来,一点点的进步,花了大量的时间和精力,而成果也是喜人的。

通过这次设计,不仅锻炼自己分析问题、处理问题的能力,还提高了自己的动手能力。在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单片机更是如此,程序只有在经常的写与读的过程中才能提高,这是我在这次课程设计中的最大收获。但同时也发现了自己的不足,特别是在程序的编写方面,有些细节部分没有考虑到,比如开始没有考虑到双机通信时独立运行的问题,这样编出的程序运行起来效率会大大降低,没有实用性,但在不断的改进中,最终解决了这个问题;但在上位机实现对下位机的温度调控这一设计中,没有设计好,未能实现远距离温度控制,自己程序方面还有待加强。

总的来说,自己从此课程设计收获了很多,一个设计的完成需要团队间的密切合作,而且需要提升自己的自学能力,脚踏实地。通过这次设计,相信自己在未来的学习和生活中会继续努力,提升自己的知识水平,不断完善自我。

参考文献

[1]《单片机原理与应用设计》第二版.张毅刚主编.电子工业出版社

[2]《Altium Designer电路设计标准教程》程晓鸽编著.科学出版社

附录

上位机程序

  1. #include<reg51.h>
  2. #include<math.h>
  3. #define uchar unsigned char
  4. #define LEDLen 6
  5. uchar send,p,t,Pos;
  6. char receive;
  7. sbit P1_0=P1^0;                                                                                                         //P1.0口为高电平,发送0x08
  8. sbit P1_1=P1^1;                                                                                                         //P1.1口为高电平,发送0xaa
  9. sbit P1_2=P1^2;                                                                                                         //P1.2口为高电平,发送0x55
  10. Uchar code LEDMAP[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};                                                                                                                                                                                                                                                //共阴极数码管段码表
  11. xdata unsigned char OUTBIT _at_ 0x8002;                                  //位选线地址
  12. xdata unsigned char OUTSEG _at_ 0x8004;                                //段选线地址
  13. uchar LEDBuf[LEDLen];                        //显示缓存
  14. void DisplayLED();                                                                                 //数码管显示函数
  15. void main()
  16. {
  17.   EA=1;
  18.   ET0=1;
  19.   TMOD=0x21;
  20.   TH1=0xfa;                                                                                                               //波特率2400
  21.   TL1=0xfa;
  22.   TR1=1;
  23.   TR0=1;                                                                                        //定时器T0开启
  24.   TH0=0xfe;                                                                                     //定时器T1赋初值,1ms
  25.   TL0=0x0c;
  26.   IP=0;                                                                                        //设置各个中断均为低优先级
  27.   SCON=0x50;
  28.   PCON=0x00;
  29.   P1=0xf7;
  30.   while(1)
  31.   {
  32.     if(P1_0==1)
  33.       send=0x08;
  34.     if(P1_1==1)
  35.       send=0xaa;
  36.     if(P1_2==1)
  37.       send=0x55;
  38.     SBUF=send;
  39.     while(TI==0);
  40.     TI=0;
  41.     while(RI==0);
  42.     RI=0;
  43.     receive=SBUF;
  44.     if(receive==0x08)
  45.       P1=0x0f;
  46.     if(receive!=0x08)
  47.     {
  48.       P1=0x07;
  49.       DisplayLED();
  50.      }
  51.    }
  52. }
  53. void timer0() interrupt 1
  54. {
  55.   TH0=0xfe;
  56.   TL0=0x0c;
  57.   if(t==0)
  58.     Pos=0x20;
  59.   OUTBIT=0;                                                                                                                                         //关所有数码管
  60.   OUTSEG=LEDBuf[t];                                                                                                                                 //送段码
  61.   OUTBIT=Pos;                                                                                                                                       //选中一位数码管
  62.   Pos>>=1;                                                                                                                                           //显示下一位
  63.   t++;
  64.   if(t==6)
  65.     t=0;
  66. }
  67. void DisplayLED()                                                                                                                       //数码管温度显示函数
  68. {
  69.   if(receive<0)
  70.     LEDBuf[0]=0x40;                                                                        //温度低于零摄氏度高位显示负号
  71.   if(receive>=0)
  72.     LEDBuf[0]=LEDMAP[0];                   //温度高于零摄氏度高位显示零
  73.   if(receive<0)
  74.     receive=-receive;
  75.   LEDBuf[1]=LEDMAP[receive/10];                                                                                      //数码管显示温度
  76.   LEDBuf[2]=LEDMAP[receive%10];
  77.   LEDBuf[3]=0x3f;
  78.   LEDBuf[4]=0x3f;
  79.   LEDBuf[5]=0x3f;
  80. }
复制代码


下位机程序:
  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define out P1                                        //步进电机脉冲控制输出口
  4. #define LEDLen 6
  5. #define LowTemp (-20)                    // A/D 0
  6. #define HighTemp  70                    // A/D 255
  7. xdata unsigned char OUTBIT _at_ 0x8002;    //位选线地址
  8. xdata unsigned char OUTSEG _at_ 0x8004;   //段选线地址
  9. xdata unsigned char ADPort _at_ 0x9000;     //AD转化地址
  10. uchar code LEDMAP[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};  
  11. //共阴极数码管段码表
  12. Uchar code turns[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};                                                                                                                                                                                                    //步进电机正转相序表
  13. uchar code turnd[]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01};                                                                                                                                                                                                    //步进电机反转相序表
  14. uchar LEDBuf[LEDLen];                                                                //显示缓存
  15. signed char CurTemp;                                                                               //定义当前温度
  16. signed char r;                                                                                     //数码管显示温度
  17. char send;
  18. uchar receive,t,p,Pos;
  19. signed char tl,th,tw;
  20. signed char tb=20;                                                     //初始化标准温度为20摄氏度
  21. uchar m=0;                                               //初始化设置温上线按键次数为0
  22. uchar n=0;                                               //初始化设置温下线按键次数为0
  23. uchar mode;                                              //步进电机正反转工作方式控制位
  24. void DisplayLED();                                       //数码管显示函数
  25. unsigned char ReadAD();                                                //A/D采样程序
  26. void ReadTemp();                                         //采样温度读取
  27. void Motorcontrol();                                                   //步进电机控制程序
  28. void Delay(uchar CNT)
  29. {
  30.   uchar i;
  31.   while(CNT--!=0)
  32.     for(i=100;i!=0;i--);
  33. }
  34. void main()
  35. {
  36.   EA=1;
  37.   ES=1;                                                           //总中断允许
  38.   EX0=1;                                                            //外部中断0允许
  39.   EX1=1;                                                            //外部中断1允许
  40.   ET0=1;                                                            //定时器T0中断允许
  41.   TMOD=0x21;                                          //定时器T0工作在方式1
  42.   IT0=1;                                                            //选择外中断0为跳沿触发
  43.   IT1=1;                                                            //选择外中断1为跳沿触发
  44.   TR0=1;                                                            //定时器T0开启
  45.   TR1=1;
  46.   TH0=0xfe;                                                         //定时器T0赋初值,1ms
  47.   TL0=0x0c;
  48.   TH1=0xfa;                                                         //波特率2400
  49.   TL1=0xfa;
  50.   SCON=0x50;
  51.   PCON=0x00;
  52.   IP=0;                                                             //设置各个中断均为低优先级
  53.   P1=0x00;
  54.   while(1)
  55.   {
  56.     th=tb+m;                                                        //温上线
  57.     tl=tb-n;                                                        //温下线
  58.     tw=th-tl;
  59.     ReadTemp();                                                    //读取当前温度
  60.     r=CurTemp;
  61.     if(r<=tl)                                                                     //温度低于下线温度
  62.     {
  63.       DisplayLED();
  64.       mode=1;
  65.       Motorcontrol();
  66.      }
  67.     if((r>tl)&&(r<=th))
  68.       DisplayLED();
  69.     if(r>th)
  70.     {
  71.       DisplayLED();
  72.       mode=2;
  73.       Motorcontrol();
  74.      }
  75.    }
  76. }
  77. void timer0() interrupt 1
  78. {
  79.   TH0=0xfe;
  80.   TL0=0x0c;
  81.   if(t==0)
  82.     Pos=0x20;
  83.   OUTBIT=0;                                                                                                             //关所有数码管
  84.   OUTSEG=LEDBuf[t];                                                                                                     //送段码
  85.   OUTBIT=Pos;                                                                                                           //选中一位数码管
  86.   Pos>>=1;                                                                                                              //显示下一位
  87.   t++;
  88.   if(t==6)
  89.     t=0;
  90. }
  91. void int0() interrupt 0                                                                                                      //外部中断0程序
  92. {
  93.   m++;                                                                                                        //温上线按键次数
  94. }
  95. void int1() interrupt 2                                                                                                      //外部中断1程序
  96. {
  97.   n++;                                                                                                         //温下线按键次数
  98. }
  99. void Port() interrupt 4
  100. {
  101.   ES=0;
  102.   if(TI==1)
  103.     TI=0;
  104.   if(RI==1)
  105.   {
  106.     receive=SBUF;
  107.     RI=0;
  108.     if(receive==0x08)
  109.     {
  110.       send=receive;
  111.       P1=0x10;
  112.      }
  113.     if(receive==0xaa)
  114.     {
  115.       send=CurTemp;
  116.       P1=0x20;
  117.      }
  118.     if(receive==0x55)
  119.     {
  120.       send=0;
  121.       P1=0x40;
  122.      }
  123.     if((receive!=0x08)&&(receive!=0xaa)&&(receive!=0x55))
  124.     {
  125.       send=0;
  126.       P1=0x80;
  127.      }
  128.    }
  129.   SBUF=send;
  130.   ES=1;
  131. }
  132. void DisplayLED()                                                               //数码管温度显示函数
  133. {
  134.   if(r<=tl)                                                                     //温度低于下线温度
  135.   {
  136.     if(r<0)
  137.       LEDBuf[0]=0x40;                                                           //温度低于零摄氏度高位显示负号
  138.     if(r>=0)
  139.       LEDBuf[0]=LEDMAP[0];     //温度高于零摄氏度高位显示零
  140.     if(r<0)
  141.       r=-r;
  142.     LEDBuf[1]=LEDMAP[r/10];    //数码管显示温度及L
  143.     LEDBuf[2]=LEDMAP[r%10];
  144.     LEDBuf[3]=0x38;
  145.     LEDBuf[4]=LEDMAP[tw/10];
  146.     LEDBuf[5]=LEDMAP[tw%10];
  147.    }
  148.   if((r>tl)&&(r<=th))
  149.     {
  150.       if(r<0)
  151.         LEDBuf[0]=0x40;                                             //温度低于零摄氏度高位显示负号
  152.       if(r>=0)
  153.         LEDBuf[0]=LEDMAP[0];   //温度高于零摄氏度高位显示零
  154.       if(r<0)
  155.         r=-r;
  156.       LEDBuf[1]=LEDMAP[r/10];                                              //数码管显示温度及C
  157.       LEDBuf[2]=LEDMAP[r%10];
  158.       LEDBuf[3]=0x39;
  159.       LEDBuf[4]=LEDMAP[tw/10];
  160.       LEDBuf[5]=LEDMAP[tw%10];
  161.      }
  162.   if(r>th)
  163.   {
  164.     LEDBuf[0]=LEDMAP[0];                                                               //数码管高位显示零
  165.     LEDBuf[1]=LEDMAP[r/10];                                                            //数码管显示温度及H
  166.     LEDBuf[2]=LEDMAP[r%10];
  167.     LEDBuf[3]=0x76;
  168.     LEDBuf[4]=LEDMAP[tw/10];
  169.     LEDBuf[5]=LEDMAP[tw%10];
  170.    }
  171. }
  172. unsigned char ReadAD()                                                                                                      //A/D采样程序
  173. {
  174.   unsigned int i;
  175.   ADPort=0;                                                                                                  //启动A/D变换
  176.   for(i=0;i<20;i++);                                                                                                       //延时100us
  177.   return(ADPort);                                                                                                         //得到A/D采样值
  178. }
  179. void ReadTemp()                                                                                                           //采样温度读取
  180. {
  181.   unsigned char i;
  182.   signed int Temp;
  183. ……………………

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


完整论文下载(word格式 可编辑):
单片机课设.doc (7.34 MB, 下载次数: 20)


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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