找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12175|回复: 18
收起左侧

基于单片机+VB的温度曲线上位机程序设计教程与源码

  [复制链接]
ID:245512 发表于 2017-11-8 22:30 | 显示全部楼层 |阅读模式
资料包内容:
0.png

基于VB6.0的上位机程序设计
内部培训资料(不得转载)
随着嵌入式系统在电子领域应用的不断深入,可视化的单片机控制与检测系统越来越成为单片机技术的应用热点。广泛应用到工业自动化生产、交通、医疗、教育和各种自动控制等领域,如心电监护、全方位视频跟踪监视。在这些复杂的数字系统中,计算机被称为上位机,通过上位机和相关的软件实现传感信号的检测和对外部设备的控制。利用计算机实现可视化的控制系统包括上位机程序设计、接口设计和单片机系统设计。
单片机相比较计算机而言又叫下位机,是直接对检测对象测量和控制的系统,有时也把接口与下位机设计在在一个系统中统称接口电路。基于计算机基础的上位机程序可以提高复杂的单片机控制系统的人机交互功能。
本项目设计的内容是一个简单的温度检测系统,上位机程序用来检测和显示单片机系统发送的数据,下位机是一个简单的温度检测系统,通过USB接口虚拟一个串口传输数据,上位机程序实时显示温度,并通过曲线的形式描绘出温度的变化过程。上位机程序VB6.0设计,程序执行后,上位机程序要定时向下位机即单片机系统发送指令,下位机在接到命令后就开始发送温度信息。上位机显示的温度曲线要能准确的表示当时的温度,误差不能超过5%,能过显示的温度范围在20摄氏度到80摄氏度之间。上位机程序两次接收的温度数据间隔控制在在1秒钟左右,能够显示的温度曲线的总时间在2分钟左右。
3.1 VB简单认识
VB是Visual Basic的简称,是由美国微软公司于1991年开发的一种可视化的、面向对象和采用事件驱动方式的结构化高级程序设计语言,可用于开发 Windows 环境下的各类应用程序。今天我们以VB6.0为基础,简单的认识VB,然后我们就可以利用VB这个强大的开发工具去开发我们需要的各类程序。
3.1.1VB6.0基本操作
在Visual Basic安装成功之后,安装程序自动在【开始】菜单中建立Visual Basic 6.0的程序组和程序项。单击【开始】按扭,指向【所有程序】选项,再指向【Microsoft Visual Basic 6.0中文版】程序组,单击【Microsoft Visual Basic 6.0中文版】选项即可启动Visual Basic6.0中文版。
在VB6.0启动后,屏幕上将出现如图3-1所示的启动界面,在启动界面中会出现一个【新建工程】对话框。
图3-1 VB6.0启动界面
    一、创建工程
在VB6.0启动界面中的【新建工程】对话框中选择一个合适的工程类型,然后单击【打开】按钮,就可以新建一个工程,新工程打开后的用户界面如图3-2所示。
图3-2 VB6.0的用户界面
    二、放置控件和设置控件属性
在用户界面的左侧是VB6.0的【工具箱】,在【工具箱】中有我们常用的各类控件,在设计窗体时我们可以直接从工具箱中选择控件,然后在中间的【对象窗口】中按住鼠标左键拖出一个矩形后,相应的控件就放置到了用户的编辑窗口中,对于控件的各个属性,我们可以通过VB界面右面的【属性窗口】设置各个控件的各种属性,放置并调整好控件的各个属性的【对象窗口】如图3-3所示。
图3-3 添加控件后的对象窗口
    三、添加代码
双击【对象窗口】的空白处或者某个控件,就会出现【代码窗口】,代码窗口如图3-4所示。
图3-4 代码窗口
在代码窗口中为各个事件添加相应的代码,在程序运行的时候一旦某个事件发生,就会执行相应的代码段,这里以Form_Load()事件为例,简单的设计一个实例程序。Form_Load()事件是在程序启动时调用的,这里我们添加如下代码:
Private Sub Form_Load()
    Form1.Caption = "示例程序"   '设置窗体的标题为“示例程序”
    Text1.Text = "文本框"        '设置文本框的文本为“文本框”
    Command1.Caption = "按钮"   '设置按钮的标题为“按钮”
    Combo1.Text = "下拉列表框"  '设置下拉列表框的文本为“下拉列表框”
End Sub
   五、程序运行
添加好代码后,我们可以通过单击工具栏上的【启动】按钮,或者单击菜单栏的【运行启动】菜单项,也可以直接按F5键运行程序,程序运行时的界面如图3-5所示。
图3-5 程序运行界面
3.2上位机程序设计
上位机程序设计不但要求界面简单,而且操作人性化,本项目上位机程序运行后的界面如图6-1-6所示。界面包括串口设置选择窗口,串口控制按键、温度显示窗口等。
3-6 上位机程序运行界面
3.2.1新建工程并添加控件
根据前面介绍,先建立一个【标准EXE】工程。然后添加MSComm控件。过程如下:
(1)单击【工程→部件】菜单项,打开部件对话框,如图3-7所示,选中【控件】选项卡里面的【Microsoft Comm Control 6.0】控件列表项,单击【确定】按钮。
           
          图3-7  添加MSComm控件            3-8  添加控件后的工具箱
添加过MSComm控件后,就可以看到在工具箱中增加了一个像电话的图标,如图3-8右下角的电话图标就是VB串口通信所用的标准控件(MSComm控件)。
(2)单击【MSComm】控件,并在窗体Form1上拖出一个矩形,如图3-9所示,这时MSComm控件就被添加到了该工程中。
图3-9  添加MSComm控件
3.2.2添加其他控件设置属性
在VB的编辑窗口中依次添加下列控件:一个下拉列表框,一个按钮,一个定时器,一个图片框和30个静态文本框,所有的属性设置如表3-1所示。添加完控件后的VB编辑界面如图3-9所示。
表3-1  控件属性表
控件类别
控件名称
控件属性
Caption
Top
Left
Height
Width
MSComm
MSComm_Temp


120
9700




按钮
Comm_open
打开串口
240
7200
375
1350
定时器
Timer1


240
10400




下拉列表
Combo_Com


240
4500
300
2200
图片框
Templine


1150
1000
6500
9250
静态文本框
Lable1
温度曲线图
720
4800
375
1800
Lable2
串口号
240
3240
255
850
Lable3
温度(C)
960
360
255
730
Lable4
80
1350
720
150
200
Lable5
70
2350
720
150
200
Lable6
60
3350
720
150
200
Lable7
50
4350
720
150
200
Lable8
40
5350
720
150
200
Lable9
30
6350
720
150
200
Lable10
20
7350
720
150
200
Lable11
时间(S)
7680
10300
255
800
Lable12
0
7680
1000
195
195
Lable13
5
7680
1500
195
195
Lable14
10
7680
2000
195
195
Lable15
15
7680
2500
195
195
Lable16
20
7680
3000
195
195
Lable17
25
7680
3500
195
195
Lable18
30
7680
4000
195
195
Lable19
35
7680
4500
195
195
Lable20
40
7680
5000
195
195
Lable21
45
7680
5500
195
195
Lable22
50
7680
6000
195
195
Lable23
55
7680
6500
195
195
Lable24
60
7680
7000
195
195
Lable25
65
7680
7500
195
195
Lable26
70
7680
8000
195
195
Lable27
75
7680
8500
195
195
Lable28
80
7680
9000
195
195
Lable29
85
7680
9500
195
195
Lable30
90
7680
10000
195
195
3.2.3添加代码
                   为各个事件处理函数添加代码如下:

  1. Dim flag_com_open As Boolean            '定义COM端口的打开标识
  2. Dim time_temp As Integer                 '定义记录时间的变量
  3. Dim temp_bufx, temp_bufy As Integer       '定义两个存放坐标的变量

  4. Private Sub Combo_Com_Click()
  5.     On Error Resume Next
  6.     x = Combo_Com.Text                '获取选择的列表项的文本
  7.     m = Len(x)                         '获取列表项的长度
  8.     n = Val(Right$(x, m - 3))              '获取列表项里的端口号
  9.     MSComm_Temp.CommPort = n      '设置MScomm控件的端口号为选择的端口号
  10. End Sub

  11. Private Sub Comm_open_Click()
  12.     If (flag_com_open = False) Then
  13.        Comm_open.Caption = "关闭端口"   '根据flag_com_open的值设置按钮Comm_open的Caption的值
  14.        flag_com_open = True
  15.        If MSComm_Temp.PortOpen = False Then
  16.            MSComm_Temp.PortOpen = True
  17.        End If
  18.        Timer1.Enabled = True              '打开端口后使Timer1有效并开始计时
  19.     Else
  20.        Comm_open.Caption = "打开端口"
  21.        MSComm_Temp.PortOpen = False
  22.        flag_com_open = False
  23.        Timer1.Enabled = False              '关闭端口后使Timer1无效
  24.     End If
  25. End Sub

  26. Private Sub Form_Load()
  27.     Dim i As Integer
  28.     Timer1.Enabled = False                 '设置定时器Timer1无效
  29.     Timer1.Interval = 1000                  '设定定时器的触发时间是1000ms
  30.     temp_bufx = 0
  31.     temp_bufy = 5500
  32.     Templine.AutoRedraw = True
  33.     Templine.DrawStyle = 2                 '将划线的格式改为虚线格式
  34.     For i = 250 To 6250 Step 500             '依次画出温度的各条基准线
  35.         Templine.Line (0, i)-(9250, i)
  36.     Next i
  37.     Templine.DrawStyle = 0                 '将划线的格式改为实线格式
  38.     For i = 1 To 16                         '依次为下拉列表框添加列表项
  39.         Combo_Com.AddItem "COM" & i
  40.     Next i
  41.     MSComm_Temp.Settings = "9600,N,8,1"   '波特率是9600,无校验,8为数据位,
  42.                                          1位停止位
  43.     MSComm_Temp.OutBufferSize = 0        '设置发送缓冲区的大小,以字符为单位
  44.     MSComm_Temp.InBufferSize = 0         '设置接收缓冲区的大小,以字符为单位
  45.     MSComm_Temp.InputMode = comInputModeText    '以文本方式接收
  46.     MSComm_Temp.RThreshold = 4  '设置产生oncomm事件的字符数,以字符为单位
  47.     MSComm_Temp.SThreshold = 1
  48.     MSComm_Temp.InputLen = 0 '设置从接收缓冲区读取的字符数,为0表示全部读取
  49.     MSComm_Temp.InBufferCount = 0        '清空接收缓冲区
  50. End Sub

  51. Private Sub MSComm_Temp_OnComm()
  52.     Dim a As String
  53.     Dim temp As Integer
  54.     If MSComm_Temp.CommEvent = comEvReceive Then
  55.         a = MSComm_Temp.Input            '读取缓冲区内的数据
  56.         For i = 1 To 4
  57.             temp = temp * 10 + Val(Mid(a, i, 1)) '分析数据,得到传输的数据值
  58.         Next i
  59.         Templine.Line (temp_bufx, temp_bufy)-(time_temp * 50, 8250 - temp), vbRed
  60. '根据得到的数据值和当前的时间以及原有的数据画出一条直线
  61.         temp_bufx = time_temp * 50          '存储当前数据,以方便下次使用
  62.         temp_bufy = 8250 - temp
  63.         time_temp = time_temp + 1           '时间值增加1
  64.     End If
  65. End Sub

  66. Private Sub Timer1_Timer()                   'Timer1中断处理函数
  67.     MSComm_Temp.Output = Chr(&H30)  '向下位机发送一个数据,用于和下位机通信
  68. End Sub
复制代码

3.3 单片机电路
下位机电路中数码管和DS18B20与单片机的连接图,如图3-10所示。
图3-10 实验板上数码管和DS18B20与单片机的连接图
3.4单片机程序设计
/********该程序主要是利用DS18B20采集温度,然后通过数码管显示温度*************/
/*当程序收到上位机发送的命令之后,该程序会将当时的温度值通过串口发送给上位机*/

  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit DQ = P1^0;                            //定义DS18B20的信号线端口
  5. uchar i,j;
  6. uchar dis_buffer[4];//定义数据缓冲数组
  7. uchar bit_ser[]={0xfe,0xfd,0xfb,0xf7}; //定义数码管片选数组
  8. uchar seven_seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
  9.                                                                                                                                  //定义数码管段选数组
  10. /****************************延时函数*********************************/
  11. void delay(uint x)
  12. {
  13.               while(x)  
  14.               x--;
  15. }
  16. /*************************DS18B20初始化函数***************************/
  17. void Init_DS18B20(void)
  18. {
  19.               unsigned char x=0;
  20.               DQ = 1;         //DQ复位
  21.               delay(8);       //稍做延时
  22.               DQ = 0;                      //单片机将DQ拉低
  23.               delay(80);                 //精确延时 大于 480us
  24.               DQ = 1;                    //拉高总线
  25.               delay(14);
  26.               x=DQ;                        //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  27.               delay(20);
  28. }
  29. /***************************从18B20中读一个字节************************/
  30. uchar ReadOneChar(void)
  31. {
  32.               uchar i=0;
  33.               uchar dat = 0;
  34.               for (i=8;i>0;i--)
  35.               {
  36.                               DQ = 0;               // 给脉冲信号
  37.                               dat>>=1;
  38.                               DQ = 1;               // 给脉冲信号
  39.                               if(DQ)
  40.                                dat|=0x80;
  41.                               delay(8);
  42.               }
  43.               return(dat);
  44. }
  45. /***************************向18B20中写一个字节************************/
  46. Write_OneChar(uchar dat)
  47. {
  48.               uchar i=0;
  49.               for (i=8; i>0; i--)
  50.               {
  51.                             DQ = 0;                //给脉冲信号
  52.                             DQ = dat & 0x01;
  53.                             delay(5);
  54.                             DQ = 1;                //给脉冲信号
  55.                             dat >>= 1;
  56.               }
  57.               delay(4);
  58. }
  59. /**************************从18B20中读取一个字节***********************/
  60. int Read_Temperature(void)
  61. {
  62.               uchar i = 0,t = 0,a,b;
  63.               int temp;
  64.               Init_DS18B20();
  65.               Write_OneChar(0xcc);               // 跳过读序号列号的操作
  66.               Write_OneChar(0x44);               // 启动温度转换
  67.               Init_DS18B20();
  68.               Write_OneChar(0xcc);               //跳过读序号列号的操作
  69.               Write_OneChar(0xbe);               //读取温度寄存器等(共可读9个寄存器)前两个就是温度
  70.               i = ReadOneChar();                 //读取温度值低位
  71.               t = ReadOneChar();                 //读取温度值高位
  72.               a = i & 0x0f;
  73.               b = t;
  74.               i = i >> 4;             //低位右移4位,舍弃小数部分
  75.               t = t << 4;             //高位左移4位,舍弃符号位
  76.               t = t | i;
  77.               temp = (t + a * 0.0625) * 100; //得到一个比实际温度扩到100倍的值,主要是为了更好的显示和传输         
  78.               return(temp);                                          //返回温度值
  79. }

  80. /***************************初始化定时器0******************************/
  81. void timer0_init(void)                                          //
  82. {
  83.               TMOD = 0x21; //由于串口通信需要使用定时器1,因此TMOD的值是0x21
  84.               TL0 = (65536-5000) % 256;
  85.               TH0 = (65536-5000) / 256;
  86.               EA = 1;
  87.               ET0 = 1;
  88.               TR0 = 1;
  89. }
  90. /*************************发送数据的函数********************************/
  91. void txd_data(char send_data)            
  92. {
  93.               SBUF = send_data; //将需要发送的数据放入发送缓冲区
  94.               while(!TI);                              //等待发送数据
  95.               TI = 0;
  96. }
  97. /********************T0中断处理函数,主要用于显示当前温度***************/
  98. void timer0_isr(void) interrupt 1
  99. {
  100.               int temp;
  101.               TR0 = 0;
  102.               TL0 = (65536-5000) % 256;
  103.               TH0 = (65536-5000) / 256;
  104.               TR0 = 1;
  105.               switch(i)
  106.               {
  107.                             case 0:
  108.                                           P2 = bit_ser[0];
  109.                                           P0 = seven_seg[dis_buffer[0]];                                                      
  110.                                           break;
  111.                             case 1:
  112.                                           P2 = bit_ser[1];
  113.                                           P0 =seven_seg[dis_buffer[1]] & 0x7f;
  114.                                           break;
  115.                             case 2:
  116.                                           P2 = bit_ser[2];
  117.                                           P0 =seven_seg[dis_buffer[2]];
  118.                                           break;
  119.                             case 3:
  120.                                           P2 = bit_ser[3];
  121.                                           P0 =seven_seg[dis_buffer[3]];
  122.                                           break;
  123.               }
  124.               i++;
  125.               if(i >= 4)
  126.               {
  127.                             i = 0;
  128.                             j++;
  129.                             if(j >= 10)              //如果到200ms就会读取一次温度,并将温度值放入显示缓冲区
  130.                             {
  131.                                           j = 0;
  132.                                           temp = Read_Temperature();
  133.                                           dis_buffer[0] = temp / 1000;
  134.                                              dis_buffer[1] = temp % 1000 / 100;
  135.                                           dis_buffer[2] = temp % 100 / 10;
  136.                                           dis_buffer[3] = temp % 10;
  137.                             }
  138.               }
  139. }

  140. /***************************串口通信初始化函数***************************/
  141. void uart_init(void)
  142. {
  143.               SCON = 0x50;         //方式1,充许接收
  144.               TMOD = 0x21;         //T1方式2定时,T0方式是1         
  145.               TH1 = 0xFd;          //波特率9600,Fosc=11.0592MHz
  146.               TL1 = 0xFd;
  147.               TR1 = 1;
  148.               ES = 1;                         // 打开串口中断
  149. }
  150. /**************************串口中断处理函数*****************************/
  151. void uart() interrupt 4                                          
  152. {
  153. ……………………

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

3.5联机调试
第一步,首先用USB线连接实验板和计算机,通过软件向实验板中烧录编写的程序,并且让实验板加电启动,然后通过系统的设备管理器查看实验板与计算机通信的端口号,如图3-11所示。
图3-11  设备管理器
第二步,启动上位机程序,根据实验板和计算机之间的通信端口,选择合适的端口号,如图3-12所示。
图3-11 选择端口号
然后单击【打开端口】按钮,即可实现实验板和计算机之间的串口通信,计算机程序会根据实验板传输的温度数据画出各个时刻的温度曲线,如图3-13所示,其中开始的一段为室温下的温度曲线,中间凸起的部分曲线是加热后产生的曲线。
图3-13 温度曲线图
思考题:
1.修改上位机和单片机程序,使之能通过上位机进行温度上下限的设置。
2.修改上下位机的程序,使之能够显示零摄氏度下的图形。


全部资料(源码)51hei下载地址:
基于VB的上位机程序设计.zip (453.63 KB, 下载次数: 289)

评分

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

查看全部评分

回复

使用道具 举报

ID:1 发表于 2017-11-9 03:52 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

ID:47652 发表于 2017-11-12 10:01 | 显示全部楼层
值得收藏谢分享
回复

使用道具 举报

ID:89841 发表于 2018-5-18 14:00 | 显示全部楼层
                 学习
回复

使用道具 举报

ID:433501 发表于 2018-11-26 15:44 | 显示全部楼层
优秀,谢了
回复

使用道具 举报

ID:230470 发表于 2018-12-7 11:54 | 显示全部楼层
不错不错的东西
回复

使用道具 举报

ID:264054 发表于 2018-12-19 21:20 | 显示全部楼层
这个好, 学习一下
回复

使用道具 举报

ID:354681 发表于 2019-1-2 17:53 | 显示全部楼层
大兄弟,很给力
回复

使用道具 举报

ID:460976 发表于 2019-1-3 14:53 | 显示全部楼层
受教了,学习学习
回复

使用道具 举报

ID:535998 发表于 2019-5-13 14:16 | 显示全部楼层
感谢楼主分享,正是我需要的!
回复

使用道具 举报

ID:477794 发表于 2019-5-31 13:39 | 显示全部楼层
好资料,正需要
回复

使用道具 举报

ID:56665 发表于 2019-5-31 14:29 | 显示全部楼层
谢谢分享!
回复

使用道具 举报

ID:555681 发表于 2019-6-5 15:32 | 显示全部楼层
学习了  能不能用其他办法处理图像  
回复

使用道具 举报

ID:522147 发表于 2019-7-25 13:32 | 显示全部楼层

值得收藏谢分享
回复

使用道具 举报

ID:5564 发表于 2019-7-25 17:16 | 显示全部楼层
下载来看看,应该有用
回复

使用道具 举报

ID:264054 发表于 2019-9-20 22:09 | 显示全部楼层
学习一下,谢谢啊
回复

使用道具 举报

ID:758637 发表于 2020-5-22 19:47 | 显示全部楼层
正好需要,非常感谢!!!
回复

使用道具 举报

ID:282431 发表于 2020-5-22 22:26 | 显示全部楼层
好资料,正需要学习
回复

使用道具 举报

ID:1044148 发表于 2022-9-7 16:53 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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