是关于VB程序的,编写一个上位机程序,读取甚至修改下位机的参数。通信规约为MODBUS

是关于VB程序的,编写一个上位机程序,读取甚至修改下位机的参数。通信规约为MODBUS,第1张

MSComm 作为一个串行通讯控件为程序员串口通讯编程节省了很多时间。在基于对话框的应用中加入一个MSComm控件非常简单。只需进行以下 *** 作即可:

打拦伍开“Project->Add To Project->Components and Controls->Registered Activex Controls”(工程/部件/控件),然后选择控件:Microsoft Communication Control,version 6.0(Microsoft Comm Control 6.0)插入到当前的工程中。这样就纤衡洞将类 CMSComm 的相关文件 mscomm.cpp 和 mscomm.h 一并加入到了工程中。编程时只需将控件对话毁枯中的 MSComm 控件拖至你的应用对话框中就OK了。

这个是MODBUS控腊兆慎制电磁阀的一个程序。其中还有AD采集的部分。对CRC校验用查表的方法。至于怎样把校验的结果拆分成高低位字节,再发送,看程序吧。

#include"reg51.h"

#include"intrins.h"

#define uchar unsigned char

#define uint unsigned int

#define Pressure P0

////////////////

/////////////////////

uchar addr

uchar  Pressure_updata

uchar  Pressure_lowdata

/////////////////

sbit    Dcf_open=P1^0//电磁阀开启

sbit    Dcf_close=P1^1//电磁阀关闭

bit   dr

bit   Dcf_state=1

bit   Halfsecond=0

bit   Onesecond=0

//////////////////////////////

sbit   Mydress_set=P2^5

sbit    P_uplimite =P2^6

sbit   P_lowlimite=P2^7

sbit   Stor=P3^2

sbit    myint=P3^3

sbit   ADC_wr     =P3^6

sbit   ADC_rd     =P3^7

sbit   xuantong   =P1^7

sbit   addrset=P1^2

sbit   upset=P1^3

sbit   lowset=P1^4

/////////////////////////

uchar code   Myreturnstateopen[3] ={0x01,0x01,0x00}

uchar code   Myreturnstateclose[3]={0x01,0x01,0x01}

uchar code   Myreturnopen[3] ={0x01,0x01,0x10}

uchar code   Myreturnclose[3]={0x01,0x01,0x20}

uchar receive_count=0

uchar mysend[6],aq[8]

uchar Adc_value

unsigned  long   Mycount=0

uchar jishi=0 //定时一秒计数

uint crc=0,myaw=0

uint crc16(unsigned char *puchMsg, unsigned int usDataLen)

bit  yifasong=0

void Beginsend( uchar Me )

bit check_modbus()

void Open_dcf()

void Close_dcf()

void timer0()

void uart_init(void)

void delay(uint z)

void Read_adc()

void  Tosend()

/////////

/*************延时*****************/

void delay(uint z)

{

  uchar y

while(z--)

for(y=113y>0y--)

}

/************串口初轮敬始化*****************/

void uart_init(void)   interrupt 4    using 1

{

if(RI)

     猜猜      {  

                  aq[receive_count]=SBUF

    RI=0

receive_count++

if(0==receive_count%8)

{

yifasong=0

receive_count=0

}

                       

                    RI=0

              }

}

/**************定时器0初始化**************/

void timer0()  interrupt 1    using 1

{

 TH0=0x4b

TL0=0x63

jishi++

if (0==jishi%10) {

 Halfsecond=1

aq[0]=0aq[1]=0aq[2]=0aq[3]=0aq[4]=0aq[5]=0aq[6]=0aq[7]=0receive_count=0

}

   

}  

void Read_adc()

{  

  ADC_rd=1

   ADC_wr=1

   _nop_()

    _nop_()

   _nop_()

   _nop_()

   myint=1

   P0=0xff       

ADC_wr=0

    _nop_()

   _nop_()

   _nop_()

   _nop_()

       ADC_wr=1                       

while( myint==1)   

      ADC_rd=0                   

     _nop_()

     _nop_()

     _nop_()

    _nop_()

    _nop_()

   

    Adc_value=P0                  //读出的数据赋与addate

    ADC_rd=1

}

void Open_dcf()

{

 Dcf_open=0   delay(1200)Dcf_open=1 Dcf_state=1

}

void Close_dcf()

{

 Dcf_close=0  delay(1200)Dcf_close=1Dcf_state=0

}

void Read_Pressure()  

{  

   Read_adc()  

if (Dcf_state)

   {

     if((Adc_value<Pressure_lowdata)|| (Adc_value>Pressure_updata))

         {

              delay(1200)

                    if((Adc_value<Pressure_lowdata)|| (Adc_value>Pressure_updata)) {   Close_dcf()}

           }

      else

          {                 }

    }

 

else

  {

    if((Adc_value>Pressure_lowdata)&&(Adc_value<Pressure_updata))

       {        delay(1200)

                    if((Adc_value>Pressure_lowdata)&&(Adc_value<Pressure_updata))   {  Open_dcf()}

  }

  else        

   }

}

void initialize()

{

TMOD=0x20

SCON=0x50//串口通讯方式1

TH1=0xfd//波特率9600

TL1=0xfd

TH0=0x4b

TL0=0x63

TI=0//发送中断标志位清零

RI=0//接收中断标志位清零

Mydress_set=1P_lowlimite=1P_uplimite=1xuantong=1

Mydress_set=0delay(20)addrset=1delay(20)addr=P0

delay(20)

addrset=0Mydress_set=1delay(200)P0=0xff

P_lowlimite=0delay(20)lowset=1delay(20)Pressure_lowdata=P0

delay(20)

lowset=0P_lowlimite=1P0=0xff           

 P_uplimite=0delay(20)upset=1Pressure_updata=P0delay(20)upset=0P_uplimite=1P0=0xff

 xuantong=0

}

void main(void)

{

IE=0x92

   TR0=1TR1=1

        // WDTRST=0x1E

           // WDTRST=0xE1//初始化看门狗

   

       initialize()

 

       Stor=0

for()  { // WDTRST=0x1E

            //WDTRST=0xE1//喂狗指令

 if (Halfsecond==1)  {

                    Halfsecond=0

                     Read_Pressure()

      }

      //够一秒开始转换

if(receive_count==0&&(yifasong==0))

              {   Stor=0 

  dr= check_modbus()

                       if (dr&&addr==aq[0])

                         {                     if(aq[1]==0x05)

                                                   

                                                            switch ( aq[3])

                                                              {

                                           case  0x00     :    

                                                               

                 if(!Dcf_state)      Open_dcf()

              Beginsend(0)           break

                                                             case  0x01     :                                                                

                                                             

                                                            if(Dcf_state)      Close_dcf()

                                                     

                                                          Beginsend(1)         

                                                               break

                             

                                                                 default  :            

                                          }

             

                                    else if(aq[1]==0x01)

                                                   

                      {

                 if(Dcf_state)

{   Beginsend(2)

                                                                           }

                        else  

                 

                                                                      {   Beginsend(3) 

                                                                            }

                          }

                                  else

                }

                     else

           

               }

       }    

}

void Beginsend(uchar Me )

{

uchar i

ES=0Stor=1

TI=0

mysend[0]=addr

switch(Me)

{

case 0:

       { for(i=1i<4i++)

              {

 

              mysend[i] =  Myreturnopen[i-1]

               }

i=0

}break

case 1:

{for(i=1i<4i++)

              {

 

              mysend[i] =   Myreturnclose[i-1]

               } i=0}break

case 2:

     {   for(i=1i<4i++)

              {

 

              mysend[i] = Myreturnstateopen[i-1]

               } i=0}break

case 3:

{for(i=1i<4i++)

              {

 

               mysend[i] =  Myreturnstateclose[i-1]

}i=0}break

default : }

myaw=crc16(mysend,4)

mysend[4] =myaw&0x00ff

mysend[5] =(myaw>>8)&0x00ff

for(i=0i<6i++)

      {

   

    SBUF=mysend[i]

   

while(TI!=1)

TI=0

       }

Stor=0

ES=1

yifasong=1

}

bit check_modbus()

{

uchar m,n  

 

crc=crc16(aq,6)

 m=crcn=crc>>8&0x00ff

if(aq[6]==m&&aq[7]==n)

return    1

else

return    0

}

uint crc16(uchar *puchMsg, uint usDataLen)

{

uchar uchCRCHi = 0xFF //* 高CRC字节初始化

uchar uchCRCLo = 0xFF //* 低CRC 字节初始化

unsigned long uIndex // CRC循环中的索引

while (usDataLen--) // 传输消息缓冲区

{

uIndex = uchCRCHi ^ *puchMsg++ // 计算CRC

uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex]

uchCRCLo = auchCRCLo[uIndex]

}

return (uchCRCHi  | uchCRCLo<<8)

}

/***********************CRC校验*************************/

// CRC 高位字节值表

就是 mscomm 控件 嘛

MSComm 控件

MSComm 控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能。

语法

MSComm

说明

MSComm 控件提供下列两种处理通讯的方式:

事件驱动通讯是处理串行端口交互作用的一种非常有效的方法。在许多情况下,在事饥庆件发生时需要得到通知,例如,在 Carrier Detect (CD) 或 Request To Send (RTS) 线上一个字符到达或一个变化发生时。在这些情况下,可以利用 MSComm 控件的 OnComm 事件捕获并处理这让历些通讯事件。OnComm 事件还可以检查和处理通讯错误。所有通讯事件和通讯错误的列表,参阅 CommEvent 属性。

在程序的每个关键功能之后,可以通过检查 CommEvent 属性的值来查询事件和错误。如果应用程序较小,并且是自保持的,这种方法可能是更可取的。例如,如果写一个简单的电话拨号程序,则没有必要对每接收一个字符都产生事件,因为唯一等待接收的字符是调制解调器的“确定”响应。

每个使用的 MSComm 控件对应着一个串行端口。如果应用程序需要访问多个串行端口,必须使用多个 MSComm 控件。可以在 Windows“控制面板”中改变端口地址和中断地址。

尽管 MSComm 控件有很多重要的属性,但首先必须熟悉几个属性。

属性 描述

CommPort 设置并返回通讯端口号。

Settings 以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。

PortOpen 设置并返回通讯端口的状态。也可以打开和关闭端口。

Input 从接收缓冲区返回和删除坦肢搜字符。

Output 向传输缓冲区写一个字符串。

触发事件 OnComm

多看 msdn

祝你顺利


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12412078.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存