上位机制作过程单片机51vb上位机超简单

合集下载

VB编写的简单的上位机

VB编写的简单的上位机

一个简单的用VB编写的上位机程序自己想做一个简单上位机,却发现相关的资料很少,于是在做出来之后把自己的这样一个简单程序上传,给新入门的朋友一个借鉴学习的资料。

窗口布局用到的MSComm控件的基本属性(必用)CommPort:设置或返回串口通信的串口号(COM口)设置格式是:mPort[=value],其中object为控件名,如MSComm1;value的合法值是整形的数据,例如1,2……比如mPort=1(默认值),表示我们将用COM1口进行通信COM口可以通过鼠标右击“我的电脑(计算机)”图标,在弹出的快捷菜单中选择“管理”,弹出如下图左边的对话框左键点击“设备管理器”可以看到上图右边对话框左键点击设备管理器可以看到如上图右边视图其中的就是当前连接到计算机的可用串口了Settings:以字符串的形式设置或返回串口通信参数。

设置格式:mPort[=value]其中object为控件名,如MSComm1;Value需为一字符串,由四个设置值组成其格式为:“波特率,奇偶校验,数据位,停止位”Portopen:设置或返回串口状态,若其已经打开,则返回TRUE,否则返回FALSE 设置格式:object.Portopen[=value]其中object为控件名,如MSComm1;value为一逻辑值,若为TRUE,则打开,否则关闭注意:如果串口不是打开(关闭),而对它进行关闭(打开)将会出错RThreshold:该属性为一阀值。

当接收缓冲区中字符数达到该值时,MSComm 控件设置Commevent属性为ComEvReceive,并产生OnComm事件。

用户可在OnComm事件处理程序中进行相应处理。

若Rthreshold属性设置为0,则不产生OnComm事件。

例如用户希望接收缓冲区中达到一个字符就接收一个字符,可将Rthreshold设置为1。

这样接收缓冲区中接收到一个字符,就产生一次OnComm事件。

上位机快速开发教程

上位机快速开发教程

上位机快速开发教程上位机是指运行在PC端,对下位机进行控制、监测和数据处理的软件。

在工业控制和自动化领域中,上位机起到了重要的作用。

为了满足快速开发上位机的需求,下面将介绍一个简单易用的上位机开发工具,LabVIEW。

LabVIEW是一种图形化编程语言,它使用数据流的方式来表示程序的执行。

LabVIEW可以通过拖拽模块、线缆和面板,来构建块状的程序结构,使得程序的开发和维护变得非常简单。

要快速开发一个上位机,首先需要了解LabVIEW的基本概念和操作步骤。

LabVIEW的开发环境包括一个Block Diagram和一个Front Panel。

Block Diagram是用于编写程序的地方,Front Panel是程序的用户界面。

在Block Diagram中,可以拖拽需要的模块和函数来构建程序。

LabVIEW中的模块被称为Virtual Instrument(VI),包括了输入、输出、控制和数据处理等功能。

通过将模块连接起来,可以实现复杂的功能。

在Front Panel中,可以添加用户界面的控件和显示元素。

LabVIEW提供了丰富的控件库,如按钮、滑块、图表等,可以根据实际需求选择使用。

通过将控件和显示元素与Block Diagram中的模块关联起来,可以实现用户界面和程序逻辑的交互。

除了基本的模块和控件,LabVIEW还提供了一些工具和函数来方便程序的开发。

例如,可以使用Error Handling函数来处理程序运行过程中可能出现的错误;可以使用SubVI来封装一些常用的功能,方便重复使用。

LabVIEW还支持多线程编程,可以同时执行多个任务,提高程序的效率和响应速度。

通过将程序分为多个模块,并使用Queue或Notifiers等数据结构来进行数据交互,可以实现多线程编程。

LabVIEW还支持与硬件设备的通信和控制。

通过使用相应的硬件库和函数,可以实现与传感器、执行器等设备的数据交互和控制。

总之,LabVIEW是一种非常强大且易用的上位机开发工具。

自己用VB编制的上位机(MSComm控件)

自己用VB编制的上位机(MSComm控件)

自己用VB编制的上位机(MSComm控件)本人初学者,许多地方显得粗糙笨拙,但总算是成功了,不过自我感受VB真的很简单,我大致学了两三个星期就可以了。

本文只同向我一样的初学者分享一下经验,毕竟咱不是专业的。

下面开始。

上位机可方便地实现与单片机之间进行信息传递交互,能够更加容易对机械手臂进行控制,实现操作可视化,更加直观,保存重要数据等功能。

我们利用Visual Basic 6.0(以下简称VB)来编制上位机,VB 是一种功能强大、简单易学的程序设计语言。

它不但保留了原先Basic 语言的全部功能,而且还增加了面向对象程序设计功能。

它不仅可以方便快捷地编制适用于数据处理、多媒体等方面的程序,而且利用ActiveX控件MSComm还能十分方便地开发出使用计算机串口的计算机通信程序。

本实验涉及控制六路舵机,所以需要编制上位机实现一次向下位机传输含有六个数据的数组,同时接受来自下位机的数组,并显示。

整个过程可分为如下几个过程:一:VB是面向对象的语言,首先需要绘制程序界面该上位机大致分为左边的功能部分与右边的可视化调节部分。

功能部分有端口选择,用以选择合适的端口进行串口通信,波特率选择,打开与关闭端口,动作设置等。

为了便于布局,应用frame控件建立区域,再将控件拖到frame 区域中,对于功能相同的控件来说,建立控件组的方式会使编程避免重复繁琐,例如HScrollbar控件,先向frame区域内拖入一个HScrollbar控件,再复制,粘贴到frame区域内部,则提示是否建立控件组,点击确定即可。

这样便为后续编程带来很大的方便。

调节部分运用Hscrollbar控件来粗略调节度数,设定按钮与文本框配合来精确调节输出度数。

用右列文本框实时读取舵机当前角度。

用optionbutton控件来选择hscrollbar的步进精度,这里分为0.1度与1度两个不同的选项。

由于一组optionbutton中在程序运行中只能有一个处于选中状态,根据本程序要求,每一横列的两个optionbutton为一组,这样就需要frame控件,在同一个frame区域里的optionbutton默认为一组。

上位机界面编程

上位机界面编程

首先,我们来大概的回忆一下单片机的串口通信。

8051单片机的串行接口由数据缓冲寄存器SBUF、移位寄存器、串行控制寄存器SCON组成。

8051单片机的串行接口是一个可编程的全双工通信接口,通过软件编程可以作为通用异步接收和发送器使用,也可作为同步移位寄存器,还可实现多机通信。

其帖格式有8位、10位和11位,通过T1或T2设置各种波特率。

1.1 串行口工作原理在发送和接收数据前,先对串行口进行初始化设置,要明确串行口的工作方式、波特率等。

1.发送数据发送数据,由累加器A送入发送缓冲寄存器SBUF,在发送控制器控制下组成帧结构,并自动以串行方式从TXD输出,每发送完一帧TI置位,可以通过中断方式或查询方式来了解数据的发送情况。

值得注意的是TI只能用软件复位。

2.接收数据单片机每接收完一帧数据,RI置位,通过中断或查询方式来了解数据的接收情况,然后用MOV A,SBUF指令,将接收缓冲寄存器(SBUF)的值送累加器A。

RI与TI一样,也只能用软件复位。

1.2串行口工作方式8051单片机通过编程可选择4种串行通信工作方式。

1.方式0在方式0下,串行口用作同步移位寄存器,以8位数据为1帧,先发送或接收最低位,每个机器周期发送或接收1位,其波特率为fosc/12。

串行数据由RXD端输入或输出,同步移位脉冲由TXD端送出。

方式0数据发送与接收是无起始位和停止位,先发送或接收最低位,数据格式为:—D0 D1 D2 D3 D4 D5 D6 D72.方式1在方式1下,串行口为10位通用异步接口,数据格式为:——0 D0 D1 D2 D3 D4 D5 D6 D 7 1 ——发送数据:当执行MOV SBUF,A指令,CPU将1字节的数据写入发送缓冲寄存器SBUF,数据从引脚TXD端输出,当发送完1帧数据后,TI标志置1,可用中断或查询方式来了解数据发送情况,TI只有通过软件复位。

接收数据:接收时,先使REN置1,使串行口处于允许接收状态,RI标志为0,串行口采样到RXD由1到0时,确认是起始位0,就开始接收1帧数据。

VB写上位机

VB写上位机

一.打开Visual Basic6.0并设置上位机大小打开Visual Basic6.0,在出现的界面中用鼠标单击,然后点击打开,出现图1-1,图 1-1单击最大化后,在“属性窗口”中找到“Height”、“ScaleHeight”、“ScaleWidth”、“top”、“Width”,并分别填入“9690”“8910”“9390”“360”“9480”。

二.代码编辑器的基本代码输入在界面内找到“视图”,单击,在下拉选项中选择“代码窗口”,单击后出现图1-2,此图就是代码编辑器,在这里填写上位机的代码。

接下来在图1-2中填入如下代码:Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByV al hwnd As Long, ByV al lpOperation As String, ByV al lpFile As String, ByV al lpParameters As String, ByV al lpDirectory As String, ByV al nShowCmd As Long) As LongPublic data As SinglePublic temp As SinglePublic flag As BytePrivate Sub Form_Load()Form.WindowState = 0If MSComm1.PortOpen = True Then MSComm1.PortOpen = FalseCombo1.AddItem "COM1"Combo1.AddItem "COM2"Combo1.AddItem "COM3"Combo1.AddItem "COM4"MSComm1.InBufferSize = 8MSComm1.OutBufferSize = 2MSComm1.RThreshold = 4MSComm1.SThreshold = 1MSComm1.InputLen = 0MSComm1.InputMode = comInputModeTextMSComm1.InBufferCount = 0End Sub图1-2三.建立菜单项在“工具”菜单中选择“菜单编辑器”选项,出现图1-3.1.在图1-3中的“标题框”和“名称框”分别填入“文件”、“File”,然后单击“下一个”。

C51LCD1602VB上位机实现简单通信.

C51LCD1602VB上位机实现简单通信.

设计基本原理主要功能:上位机和下位机连接好后握手,如果成功,上位机就可以发字符串让下位机的LCD显示出来,如果没有握手就不显示上位机发来的内容.下位机设计:主程序首先初始化串口和LCD,然后进入一个死循环,这个循环往LCD写dataArray这个数组中的数据,因此只要改变了这个数组中的第0-31位的内容就相当于改变了屏幕上显示的内容. 当串口发来消息的时候,执行中断号为4(串口中断)的服务子程序.这时候还不能让上位机往下位机传字符串,因此需要判断是否已经握手,判断的标志就是dispEn (display enable),如果等于0说明还没有握手,就把用户发来的数据当成是控制字control,如果是等于1说明之前已经握过手了,就把用户发来的数据放到dataArray中.最后判断控制字是否是握手,如果control等于0x00是就握手信号,然后回复0x01.然后把dispEn=1,最后把控制字control改掉(因为下一次中断可能已经不是握手信号了)上位机设计:由于已经把端口号写在vb程序中了,所以要改端口号的话要进vb的代码中把mPort = 4 中的4 改为自己需要的串行端口号.然后运行程序,打开端口,此时没有和下位机握手,所以输入数据后单击发送是没有反应的,所以需要先单击握手按钮,向传哭发送0x00,然后延时800毫秒等待回复,然后接收数据,如果回复的是0x01那就表明握手成功,如果没有回复那就是握手失败.用户点击发送信息,上位机把字符串拆分成字符来发送一次发送一个字符,每个字符发送延时30毫秒避免因为连续发送而造成的乱码.a)原理框图b)硬件电路原理图AT89C521~8:I/OP1口(P1.0~P1.7);9:复位脚(RST/Vpd);10~17:I/OP3口(P3.0=RXD,P3.1=TXD,P3.2=-INT0,P3.3=-INT1,P3.4=T0,P3.5=T1,P3.6=-WR,P3.7=-RD)主要是此引脚;18、19:晶振(18=XTAL2,19=XTAL1);20:地(Vss);21~28:I/OP2口(P2.0~P2.7);29:-PSEN;30:ALE/-PROG;31:-EA/Vpp32~39:I/OP0口(P0.7~P0.0);40:+5V电源。

基于51单片机的温度测试系统 VB上位机

基于51单片机的温度测试系统 VB上位机

简介:这是我学完51单片机的第一个作品,单片机型号为89c52,时钟芯片用的是DS1302,温度传感器用的是DS18B20,USB供电,掉电后时钟芯片继续工作,且已经设置好的温度上下限和闹钟数据不会丢失。

上位机是用VB语言写的,只是一个模型,从上位机上可以观察当前温度值以及温度上下限,以后会更加完善其功能。

下面是下位机程序和上位机程序,程序比较长,而且下位机程序的键盘部分写得有点麻烦。

下位机程序:/***************************************************************************************作者:江苏科技大学电子信息科学与技术二班吴亚迪注:此程序可以实现万年历闹钟温度测定温度超过上下限发出警报断电后时钟不停,且已设好的温度上下限和闹钟数据不会丢失****************************************************************************************/#include<reg52.h>#define uchar unsigned char#define uint unsigned intuchar code table[]="20 / / DAY- ";uchar code table1[]=" : : ";uchar code table2[]="0123456789";uchar code table3[]=" alarm clock ";sbit ds_clk=P3^6;sbit ds_io=P3^7;sbit ds_rst=P1^4;sbit lcdrs=P1^0;sbit lcdrw=P1^1;sbit lcden=P1^2;sbit scl=P3^2;sbit sda=P3^3;sbit ACC_7=ACC^7;sbit P34=P3^4;bit alarm=0;//闹钟标志位bit stop_alarm=0;//停止闹钟标志位uchar i,j;uchar th,tl; //温度上下限uint th1,th2,tl1,tl2;uchar min,hour,sec; //闹钟时分秒uint min1,min2,hour1,hour2,sec1,sec2;void delay(uint i){uint j;for(;i>0;i--)for(j=0;j<110;j++);}/***********************************************************************************************DS1302部分**************************************************************************************************/ char s,s1,s2; //时钟秒char m,m1,m2; //分char h,h1,h2; //时char day; //星期char date,date1,date2;//日期char mon,mon1,mon2; //月char year,year1,year2;//年void write_ds(uchar add,uchar date ) //向ds1302指定地址写数据{uchar i,temp;ds_rst=0;ds_clk=0;ds_rst= 1;for ( i=8; i>0; i-- ){ds_clk = 0;temp = add;ds_io= temp&0x01;add >>= 1;ds_clk = 1;}for ( i=8; i>0; i-- ){ds_clk = 0;temp = date;ds_io =temp&0x01;date >>= 1;ds_clk = 1;}ds_rst= 0;}uchar read_ds(uchar add ) //ds1302指定地址读数据{unsigned char i,temp,date1;ds_rst=0;ds_clk=0;ds_rst= 1;for ( i=8; i>0; i-- ){ds_clk = 0;temp = add;ds_io=temp&0x01;add >>= 1;ds_clk = 1;}for ( i=8; i>0; i-- ) //这里要注意{ACC_7=ds_io;ds_clk = 1;ACC>>=1;ds_clk = 0;}ds_rst=0;date1=ACC;return date1;}void init_ds() //初始化ds1302{write_ds(0x8e,0x00); //关闭写保护write_ds(0x80,0x22); //初始化秒write_ds(0x82,0x59); //分write_ds(0x84,0x23); //时write_ds(0x86,0x21); //日write_ds(0x88,0x05); //月write_ds(0x8a,0x06); //星期write_ds(0x8c,0x11); //年write_ds(0x8e,0x80); //开写保护}void read_all() //读s,m,h,date,mon,year,day{s=read_ds(0x81);s1=s/16;s2=s%16;m=read_ds(0x83);m1=m/16;m2=m%16;h=read_ds(0x85);h1=h/16;h2=h%16;date=read_ds(0x87);date1=date/16;date2=date%16;mon=read_ds(0x89);mon1=mon/16;mon2=mon%16;day=read_ds(0x8b);year=read_ds(0x8d);year1=year/16;year2=year%16;}/***********************************************************************************************1602部分**************************************************************************************************/ void write_com(uchar com) //写命令{lcdrs=0;lcden=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_date(uchar date)//写数据{lcdrs=1;lcden=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void init_1602() //初始化1602{lcdrw=0;write_com(0x01);write_com(0x38);write_com(0x0f);write_com(0x06);for(i=0;i<16;i++){write_date(table[i]);delay(10);}write_com(0x80+0x40);for(i=0;i<16;i++){write_date(table1[i]);delay(10);}write_com(0x80+0x40+0x0e);write_date(0xdf);delay(10);write_date('c');}/***********************************************************************************************EEPROM部分**************************************************************************************************/void delay1(){ ; ; }void init()//初始化总线{sda=1;delay1();scl=1;delay1();}void start()//开始函数{sda=1;delay1();scl=1;delay1();sda=0;delay1();}void stop()//停止函数{sda=0;delay1();scl=1;delay1();sda=1;delay1();}void respons()//应答{uchar i;sda=1;delay1();scl=1;while(sda==1&&i<250) i++;scl=0;delay1();}void write_byterom(uchar date)//向eeprom中写一字节数据{uchar i;for(i=0;i<8;i++){date=date<<1;scl=0;delay1();sda=CY;delay1();scl=1;delay1();}scl=0;delay1();}uchar read_byterom()//从eeprom中读一字节数据{uchar i,temp;scl=0;delay1();for(i=0;i<8;i++){scl=1;delay1();temp<<=1;temp|=sda;scl=0;delay1();}return temp;}void write_add(uchar add,uchar date)//指定地址写数据{start();write_byterom(0xa0);respons();write_byterom(add);respons();write_byterom(date);respons();stop();}uchar read_add(uchar add)//指定地址读数据{uchar temp;start();write_byterom(0xa0);respons();write_byterom(add);respons();start();write_byterom(0xa1);respons();temp=read_byterom();stop();return temp;}/***********************************************************************************************ds18b20部分**************************************************************************************************/ sbit DQ=P3^5;void delay2(uchar i){while(i--);}void init_ds18b20()//初始化ds18b20{uchar i;DQ=1;delay2(8);DQ=0;delay2(80);DQ=1;while(DQ==1&&i<255) i++;delay2(35);delay2(20);}void write_byte(uchar dat)//向ds18b20中写一字节{uchar i;for(i=0;i<8;i++){DQ=1;delay2(1);DQ=0;delay2(1);DQ=dat&0x01;delay2(5);DQ=1;dat>>=1;delay2(4);}}uchar read_byte()//从ds18b20中读一字节{uchar i,dat=0;for(i=0;i<8;i++){DQ=1;delay2(1);DQ=0;dat>>=1;DQ=1;if(DQ)dat=dat|0X80;delay2(4);}return dat;}uchar read_temp() //读温度函数{uchar a,b,c;init_ds18b20();write_byte(0xcc);write_byte(0x44);init_ds18b20();write_byte(0xcc);write_byte(0xbe);a=read_byte();b=read_byte();c=(b<<4)|(a>>4);return c;}uchar read_th()//读上限函数{uchar a,b,c;init_ds18b20();write_byte(0xcc);write_byte(0x44);init_ds18b20();write_byte(0xcc);write_byte(0xbe);a=read_byte();b=read_byte();c=read_byte();return c;}uchar read_tl()//读下限函数{uchar a,b,c;init_ds18b20();write_byte(0xcc);write_byte(0x44);init_ds18b20();write_byte(0xcc);write_byte(0xbe);a=read_byte();b=read_byte();a=read_byte();c=read_byte();return c;}/***********************************************************************************************键盘部分(P2^0~P2^3)**************************************************************************************************/void keyscan(){uchar temp,num1,num2;temp=P2;temp&=0x0f;if(temp!=0x0f) //消抖{delay(5);if(temp!=0x0f){temp=P2;temp&=0x0f;if(temp==0x0e){num1=1;write_ds(0x8e,0x00);write_ds(0x80,s|0x80);//禁止写保护while(temp==0x0e)//松手检测{temp=P2;temp&=0x0f;}while(1){temp=P2;temp&=0x0f;if(temp==0x0e){delay(5);temp=P2;temp&=0x0f;if(temp==0x0e){num1++;}}while(temp==0x0e)//松手检测{temp=P2;temp&=0x0f;}if(num1==1){write_com(0x80+0x40+0x08); write_com(0x0f);//光标闪烁temp=P2;temp&=0x0f;if(temp==0x0d){delay(5);if(temp==0x0d){while(temp==0x0d)//松手检测 {temp=P2;temp&=0x0f;}s=read_ds(0x81);s1=s/16;s2=s%16;s2+=1;if(s2==10){s1+=1;}if(s1==6) s1=0;write_com(0x80+0x40+0x07);write_date(table2[s1]);write_date(table2[s2]);write_ds(0x80,s1*16+s2);//向ds1302中写入秒 }}else if(temp==0x0b){delay(5);if(temp==0x0b){while(temp==0x0b)//松手检测{temp=P2;temp&=0x0f;}s=read_ds(0x81);//读ds1302秒s1=s/16;s2=s%16;s2-=1;if(s2==-1){s2=9;s1-=1;}if(s1==-1) s1=5;write_com(0x80+0x40+0x07);write_date(table2[s1]);write_date(table2[s2]);write_ds(0x80,s1*16+s2);}}}if(num1==2){write_com(0x80+0x40+0x05);write_com(0x0f);temp&=0x0f;if(temp==0x0d){delay(5);if(temp==0x0d){while(temp==0x0d)//松手检测{temp=P2;temp&=0x0f;}m=read_ds(0x83);//从ds1302中读分m1=m/16;m2=m%16;m2+=1;if(m2==10){m2=0;m1+=1;}if(m1==6) m1=0;write_com(0x80+0x40+0x04);write_date(table2[m1]);write_date(table2[m2]);write_ds(0x82,m1*16+m2);//向ds1302中写入分 }}else if(temp==0x0b){delay(5);if(temp==0x0b){while(temp==0x0b)//松手检测{temp=P2;temp&=0x0f;}m=read_ds(0x83);m1=m/16;m2=m%16;m2-=1;{m2=9;m1-=1;}if(m1==-1) m1=5;write_com(0x80+0x40+0x04);write_date(table2[m1]);write_date(table2[m2]);write_ds(0x82,m1*16+m2);}}}if(num1==3){write_com(0x80+0x40+0x02);write_com(0x0f);temp=P2;temp&=0x0f;if(temp==0x0d){delay(5);if(temp==0x0d){while(temp==0x0d)//松手检测{temp=P2;temp&=0x0f;}h=read_ds(0x85);//从ds1302中读时 h1=h/16;h2=h%16;h2+=1;if(h2==10){h2=0;h1+=1;}if(h2==4&&h1==2){h2=0;h1=0;}write_com(0x80+0x40+0x01);write_date(table2[h1]);write_date(table2[h2]);write_ds(0x84,h1*16+h2);//向ds1302中写入时 }}else if(temp==0x0b){delay(5);if(temp==0x0b){while(temp==0x0b)//松手检测{temp=P2;temp&=0x0f;}h=read_ds(0x85);h1=h/16;h2=h%16;h2-=1;if(h2==-1){h2=9;h1-=1;}if(h2==9&&h1==-1){h2=3;h1=2;}write_com(0x80+0x40+0x01);write_date(table2[h1]);write_date(table2[h2]);write_ds(0x84,h1*16+h2);}}}if(num1==4){write_com(0x80+0x0f);write_com(0x0f);temp=P2;temp&=0x0f;if(temp==0x0d){delay(5);if(temp==0x0d){while(temp==0x0d)//松手检测{temp=P2;temp&=0x0f;}day=read_ds(0x8b);//从ds1302中读星期day+=1;if(day==8){day=1;}write_com(0x80+0x0f);write_date(table2[day]);write_ds(0x8a,day);//向ds1302中写入星期 }}else if(temp==0x0b){delay(5);if(temp==0x0b){while(temp==0x0b)//松手检测{temp=P2;temp&=0x0f;}day=read_ds(0x8b);day-=1;if(day==0){day=7;}write_com(0x80+0x0f);write_date(table2[day]);write_ds(0x8a,day);}}}if(num1==5){write_com(0x80+0x09);write_com(0x0f);temp=P2;temp&=0x0f;if(temp==0x0d){delay(5);if(temp==0x0d){while(temp==0x0d)//松手检测{temp=P2;temp&=0x0f;}date=read_ds(0x87);//从ds1302中读日期date1=date/16;date2=date%16;date2+=1;if(date2==10){date2=0;date1+=1;}if(date2==2&&date1==3){date2=0;date1=0;}if(date1==0&&date2==0){date1=0;date2=1;}write_com(0x80+0x08);write_date(table2[date1]);write_date(table2[date2]);write_ds(0x86,date1*16+date2);//向ds1302中写入日期 }}else if(temp==0x0b){delay(5);if(temp==0x0b){while(temp==0x0b)//松手检测{temp=P2;temp&=0x0f;}date=read_ds(0x87);date1=date/16;date2=date%16;date2-=1;if(date2==-1){date2=9;date1-=1;}if(date2==9&&date1==-1){date2=1;date1=3;}if(date1==0&&date2==0){date1=3;date2=1;}write_com(0x80+0x08);write_date(table2[date1]);write_date(table2[date2]);write_ds(0x86,date1*16+date2); }}}if(num1==6){write_com(0x80+0x06);write_com(0x0f);temp=P2;temp&=0x0f;if(temp==0x0d){delay(5);if(temp==0x0d){while(temp==0x0d)//松手检测{temp=P2;temp&=0x0f;}mon=read_ds(0x89);//从ds1302中读月mon1=mon/16;mon2=mon%16;mon2+=1;if(mon2==10){mon2=0;mon1+=1;}if(mon2==3&&mon1==1){mon2=0;mon1=0;}if(mon1==0&&mon2==0){mon1=0;mon2=1;}write_com(0x80+0x05);write_date(table2[mon1]);write_date(table2[mon2]);write_ds(0x88,mon1*16+mon2);//向ds1302中写入月 }}else if(temp==0x0b){delay(5);if(temp==0x0b){while(temp==0x0b)//松手检测{temp=P2;temp&=0x0f;}mon=read_ds(0x89);mon1=mon/16;mon2=mon%16;mon2-=1;if(mon2==-1){mon2=9;mon1-=1;}if(mon2==9&&mon1==-1){mon2=2;mon1=1;}if(mon1==0&&mon2==0){mon1=1;mon2=2;}write_com(0x80+0x05);write_date(table2[mon1]);write_date(table2[mon2]);write_ds(0x88,mon1*16+mon2); }}}if(num1==7){write_com(0x80+0x03);write_com(0x0f);temp=P2;temp&=0x0f;if(temp==0x0d){delay(5);if(temp==0x0d){while(temp==0x0d)//松手检测{temp=P2;temp&=0x0f;}year=read_ds(0x8d);//从ds1302中读年year1=year/16;year2=year%16;year2+=1;if(year2==10){year2=0;year1+=1;}if(year1==9){year1=0;}write_com(0x80+0x02);write_date(table2[year1]);write_date(table2[year2]);write_ds(0x8c,year1*16+year2);//向ds1302中写入年 }}else if(temp==0x0b){delay(5);if(temp==0x0b){while(temp==0x0b)//松手检测{temp=P2;temp&=0x0f;}year=read_ds(0x8d);year1=year/16;year2=year%16;year2-=1;if(year2==-1){year2=9;year1-=1;}if(year1==-1){year1=7;}write_com(0x80+0x02);write_date(table2[year1]);write_date(table2[year2]);write_ds(0x8c,year1*16+year2); }}}if(num1==8) //修改上限{write_com(0x80+0x40+0x0d); write_com(0x0f);delay(10);write_com(0x80+0x40+0x09); write_com(0x0e);write_date('T');write_date('H');write_com(0x80+0x40+0x0d); write_com(0x0f);th=read_th();write_com(0x80+0x40+0x0b);if(th>=100){write_date('-');th=~th+1;}else write_date(' ');th1=th/10;th2=th%10;write_date(table2[th1]);write_date(table2[th2]);temp=P2;temp&=0x0f;if(temp==0x0d){delay(5);if(temp==0x0d){while(temp==0x0d)//松手检测{temp=P2;temp&=0x0f;}tl=read_tl();th=read_th();th+=1;if(th==100){th=157;}if(th==256){th=0;}init_ds18b20(); //写上下限 write_byte(0xcc);write_byte(0x4e);write_byte(th);write_byte(tl);}}else if(temp==0x0b){delay(5);if(temp==0x0b){while(temp==0x0b)//松手检测 {temp=P2;temp&=0x0f;}th=read_th();tl=read_tl();th-=1;if(th==256){th=255;}if(th==156){th=99;}init_ds18b20(); //写上下限write_byte(0xcc);write_byte(0x4e);write_byte(th);write_byte(tl);}}}if(num1==9) //修改下限{write_com(0x80+0x40+0x0d); write_com(0x0f);delay(10);write_com(0x80+0x40+0x09); write_com(0x0e);write_date('T');write_date('L');write_com(0x80+0x40+0x0d); write_com(0x0f);tl=read_tl();write_com(0x80+0x40+0x0b); if(tl>=100){write_date('-');tl=~tl+1;}else write_date(' ');tl1=tl/10;tl2=tl%10;write_date(table2[tl1]);write_date(table2[tl2]);temp=P2;temp&=0x0f;if(temp==0x0d){delay(5);if(temp==0x0d){while(temp==0x0d)//松手检测 {temp=P2;temp&=0x0f;}tl=read_tl();th=read_th();tl+=1;if(tl==100){tl=157;}if(tl==256){tl=0;}init_ds18b20(); //写上下限 write_byte(0xcc);write_byte(0x4e);write_byte(th);write_byte(tl);}}else if(temp==0x0b){delay(5);if(temp==0x0b){while(temp==0x0b)//松手检测 {temp=P2;temp&=0x0f;}th=read_th();tl=read_tl();tl-=1;if(tl==256){tl=255;}if(tl==156){tl=99;}init_ds18b20(); //写上下限write_byte(0xcc);write_byte(0x4e);write_byte(th);write_byte(tl);}}}if(num1==10){write_com(0x80+0x40+0x09); write_com(0x0e);write_date(' ');write_date(' ');write_date(' ');init_ds18b20(); //拷贝上下限write_byte(0xcc);write_byte(0x48);num1=0;write_ds(0x80,s&0x7f);write_ds(0x8e,0x80);//开启写保护 break;}}}if(temp==0x07)//闹钟设定{delay(5);if(temp==0x07){while(temp==0x07){temp=P2;temp&=0x0f;}if(alarm==1){P34=1;alarm=0;stop_alarm=1;}else{num2=1;while(1){temp=P2;temp&=0x0f;if(temp==0x07){delay(5);temp=P2;temp&=0x0f;if(temp==0x07){num2++;}}while(temp==0x07)//松手检测{temp=P2;temp&=0x0f;}if(num2==1)//按下第一次显示上次设定的时间 {write_com(0x80);for(i=0;i<16;i++){write_date(table3[i]);delay(10);}write_com(0x80+0x40+0x0c);write_date(' ');write_date(' ');write_date(' ');write_date(' ');hour=read_add(1);hour1=hour/10;hour2=hour%10;min=read_add(7);min1=min/10;min2=min%10;sec=read_add(4);sec1=sec/10;sec2=sec%10;write_com(0x80+0x40+0x01); write_date(table2[hour1]);write_date(table2[hour2]);write_com(0x80+0x40+0x04); write_date(table2[min1]);write_date(table2[min2]);write_com(0x80+0x40+0x07); write_date(table2[sec1]);write_date(table2[sec2]);}if(num2==2)//按下第二次设定秒 {write_com(0x80+0x40+0x08); write_com(0x0f);delay(100);temp=P2;temp&=0x0f;if(temp==0x0d){delay(5);if(temp==0x0d){while(temp==0x0d)//松手检测 {temp=P2;temp&=0x0f;}sec++;if(sec==60) sec=0;}}else if(temp==0x0b){delay(5);if(temp==0x0b){while(temp==0x0b)//松手检测 {temp=P2;temp&=0x0f;}sec--;if(sec==255) sec=59;}}}sec1=sec/10;sec2=sec%10;write_com(0x80+0x40+0x07); write_date(table2[sec1]);write_date(table2[sec2]);if(num2==3)//按下第三次设定分 {write_com(0x80+0x40+0x05); write_com(0x0f);delay(100);temp=P2;temp&=0x0f;if(temp==0x0d){delay(5);if(temp==0x0d){while(temp==0x0d)//松手检测 {temp=P2;temp&=0x0f;}min++;if(min==60) min=0;}}else if(temp==0x0b){delay(5);if(temp==0x0b){while(temp==0x0b)//松手检测 {temp=P2;temp&=0x0f;}min--;if(min==255) min=59;}}}min1=min/10;min2=min%10;write_com(0x80+0x40+0x04); write_date(table2[min1]);write_date(table2[min2]);if(num2==4)//按下第四次设定时 {write_com(0x80+0x40+0x02); write_com(0x0f);delay(100);temp=P2;temp&=0x0f;if(temp==0x0d){delay(5);if(temp==0x0d){while(temp==0x0d)//松手检测 {temp=P2;temp&=0x0f;}hour++;if(hour==24) hour=0;}}else if(temp==0x0b){delay(5);if(temp==0x0b){while(temp==0x0b)//松手检测{temp=P2;temp&=0x0f;}hour--;if(hour==255) hour=23;}}}hour1=hour/10;hour2=hour%10;write_com(0x80+0x40+0x01);write_date(table2[hour1]);write_date(table2[hour2]);if(num2==5) //按下第五次向eeprom中写入时分(秒省略),并退出循环 {write_add(7,min);delay(10);write_add(1,hour);write_com(0x80);for(i=0;i<16;i++){write_date(table[i]);delay(10);}write_com(0x80+0x40+0x0e);write_date(0xdf);write_date('c');break;}}}}}}}}/***********************************************************************************************主函数部分**************************************************************************************************/ void main(){uchar temp;init();init_1602();init_ds();temp=read_temp();delay(100);while(1)//循环检测{read_all();keyscan();write_com(0x80+0x40+0x01);write_date(table2[h1]);write_date(table2[h2]);write_com(0x80+0x40+0x04);write_date(table2[m1]);write_date(table2[m2]);write_com(0x80+0x40+0x07);write_date(table2[s1]);write_date(table2[s2]);write_com(0x80+0x02);write_date(table2[year1]);write_date(table2[year2]);write_com(0x80+0x05);write_date(table2[mon1]);write_date(table2[mon2]);write_com(0x80+0x08);write_date(table2[date1]);write_date(table2[date2]);write_com(0x80+0x0f);write_date(table2[day]);temp=read_temp();th=read_th();tl=read_tl();//*********************************************************************************温度上限先检测及报警write_com(0x80+0x40+0x0b);if(temp<128) //查看温度是否超过上下限{if((th>128)||(th<128&&temp>=th)||(tl<128&&temp<=tl)){P34=0;delay(1000);P34=1;}}if(temp>128) //temp>128时温度取反后加一,查看温度是否超过上下限{if((th>128&&temp>=th)||(tl>128&&temp<=tl)||(tl<128)){P34=0;delay(1000);P34=1;}write_date('-');temp=~temp+1;}else write_date(' ');write_date(table2[temp/10]);write_date(table2[temp%10]);min=read_add(7);delay(5);hour=read_add(1);delay(5);//***********************************************************************************闹钟检测及报警if((min==m1*10+m2)&&stop_alarm){}else if((min==m1*10+m2)&&(hour==h1*10+h2)&&(!stop_alarm)) //闹钟{alarm=1;}if((min!=m1*10+m2)&&stop_alarm){stop_alarm=0;}if(alarm==1){P34=0;delay(30);P34=1;delay(100);P34=0;delay(30);P34=1;delay(100);P34=0;delay(30);P34=1;delay(100);P34=0;delay(30);P34=1;delay(100);}//*************************************************************************************************** }}上位机程序(VB语言):Option ExplicitDim i%Dim buf$Private Sub Form_Load()mPort = 2MSComm1.PortOpen = TrueMSComm1.RThreshold = 1MSComm1.InBufferCount = 0MSComm1.InputMode = comInputModeTextText1.FontSize = 10End SubPrivate Sub MSComm1_OnComm() Select Case mEvent Case comEvReceivebuf = Trim(Str(Asc(MSComm1.Input))) i = i + 1If i = 1 ThenText1.Text = bufEnd IfIf i = 2 ThenText2.Text = bufEnd IfIf i = 3 Theni = 0Text3.Text = bufEnd IfEnd SelectEnd Sub上位机运行图片:。

用VB开发PC与单片机通信的上位机程序

用VB开发PC与单片机通信的上位机程序

串口通信是MCU跟PC通信经常用到的一种通信方式,做界面、写上位机程序的编程语言、编译环境有不少,诸如VB、VC++,Delphi、LABVIEW等等,不过无论黑猫还是白猫,能够抓到老鼠的就是好猫,用VB无疑是最快速最简便的,实现的功能也足够强大,足以满足我们的基本需要了。

我最近用VB写出了一个用于数据采集的串口上位机程序,实现数据的接收和实时绘图,这里和大家分享一下,让大家也体验一下单片机和PC通信的乐趣。

整个程序只需要不到30行程序,我将会给这30行程序加上最为详备的注释,这样即使你从未使用VB制作过上位机程序,也能照猫画虎的编写出属于自己的上位机程序。

一,制定设计思路首先,我们要制定一下自己的串口通讯协议,为了方便设计,通讯协议中将采用字符型数据(遵循ASCII字符集)进行传输,一共5个字节数据,下位机按照从第一字节到第五字节的顺序以1 符号位2 百位3 十位4 个位注释:1,符号符,+(2B)或—(2D),表示数据的正负2,3,4,百位,十位,和个位数字5,结束符,用大写字母A(41)表示接着,我们就要明确设计思路了,这个程序的设计将采用Microsoft Visual Basic 6.0(以下简称VB6.0)作为m,通过编译环境,运用串口通讯控件MSCom计时器控件实现以查询方式编写的串口数据的接收和实时绘图。

二,程序界面设计(1)创建一个标准EXE工程:启动VB6.0,在自动弹出的“新建工程”窗口中单击“标准EXE”图标,然后单击“打开”按钮即可创建一个标准EXE工程。

将弹出的窗体的Caption属性设置为串口通讯与实时绘图程序。

[attachment=1364699](1)添加串口通信控件MSComm:VB的串口通信控件MSComm并不会主动出现在工具箱中,当我们需要MSComm控件时,首先要把它加入工具箱中,选择“工程”菜单下的“部件...”子菜单,在弹出的“部件”对话框中,在“控件”选项卡属性中选中“Microsoft Comm Control 6.0”,单击“确定”按钮后,在工具箱中就出现了一个形似电话的图标,这就是MSComm控件,选择MSComm控件的图标,将它添加到适当位置,采用默认名称MSComm1。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
上位机制作过程单片机51vb上位机 超简单
• 1602控制
上位机用途
• 上位机是一台可以发出特定操控命令的计 算机,通过操作预先设定好的命令,将命 令传递给下位机,通过下位机来控制设备 完成各项操作(应用最多的地方如:工业、 水利、供电部门、交通等方面)。上位机 都有特定的编程,有专门的开发系统,或 以上是已经规定好任务,只能按特定的任 务进行操作。简单说上位机就是命令的下 达者,而下位机则是命令的执行者。
口。
• Private Sub Command2_Click() • 这个是点击按钮2所触发的事件代码函数入
口。
代码如下
成功和下位机通讯
谢谢观赏
比如上位机控制在工厂中的应用
首先打开vb软件
• 弹出新建工程对话框,点击标准exe
• 出现如下
设置属性窗口
• caption:标题 • font:字体大小和风格
• 新建两个按钮,改一下caption:打开串口 和发送数据如下图所示
点击左边按钮框新建一个text1,如下图所示
添加串口控件,在工程-部件中找到Microsoft comm control 6.0,如下图所示,点击打钩,并确定。
在右边控件Байду номын сангаас出现一个电话的控件,并把下图箭头所示的控 件添加到窗口中。
对代码进行编写
• 首先,双击窗口进入代码编辑框,如下图 所示:
• Private Sub Form_Load() • 这个函数是窗口运行时初始化一些控件。
• Private Sub Command1_Click() • 这个是点击按钮1所触发的事件代码函数入
相关文档
最新文档