汇川AC801以及汇川AM500 基于485的Moudbus通讯

[复制链接]
查看463 | 回复0 | 2025-1-2 08:17:41 | 显示全部楼层 |阅读模式
>
以下是以永鹏的直流电阻仪器为例子,进行功能的说明。

1,A801的设置

如何在AC801中添加基于485的modbus通讯,A801有一个485的接口(资料来源于官网的《AC801智能机械可编程控制器用户手册》):

接下来说明如何在软件里面添加设备:

在Device中添加Modbus Master,作为基于485的modbus主站。之后双击Modbus Master,进行通讯格式的设置:

之后再点击Network Configuration,在右边窗口添加COM1(RS485)下的Modbus设备,这样就可以添加Modbus从站。

之后根据被连接设备的协议,进行设备的通讯设置,双击modbus_protocol:
首先进行站号的设置:

然后进行写入和读取寄存器的设置:

永鹏直流电阻仪器读电阻数据的地址是02,03;锁定量程05,设置档位07,电阻下限08,09;电阻上限10,11;
这里有个没想明白的地址,读取电阻的地址是02,03;设置的时候是03单个寄存器,竟然也可以获取到正确的数据?有点摸不着头脑。
最后再将获取的数据和变量连接起来:

AC801的连接就说明完成了。
二,AM500的设置
之后进行AM500的说明,以下是AM500在软件中建立连接的说明(资料来源官网的《中型PLC编程软件使用手册》):

这里的串口通信格式修改成和被连接设备一样的通信格式。

这里进行寄存器的设置是使用%MW的寄存器进行数据的发送与接收,%MW300是输入发送的数据的字节数目,一旦输入数值,就会马上以%MW301为起始地址的%MW300设置的字节数据进行发送;%MW0是回传的数据的字节长度,回传的数据显示在以%MW1为起始地址的数据中,但是每次回采数据后,需要将%MW0清零,不然会一直在%MW1后持续添加数据。

这里无法像AC801自己读写程序,需要在程序里面对%MW0,对%MW300的数据进行处理。

以下是对%MW0,%MW300数据连接的变量:

    VAR_GLOBAL
    END_VAR
    VAR_GLOBAL PERSISTENT RETAIN
      w_Read        AT %MW0      :  WORD                                  ;//串口反馈的字节长度,需要及时清零,不然会一直在以MW1开始的地址进行累积
      w_Read_Bit      AT %MW1      :  ARRAY [0..19] OF WORD                          ;//串口反馈的数据
      
      w_Write        AT %MW300    :  WORD                                  ;//写入串口的字节,输入字节长度,才会写入数据
      w_Write_Bit      AT %MW301    :  ARRAY [0..19] OF WORD                          ;//以MV301为起始地址,写入串口的信息
    END_VAR

    接下来对电阻仪器初始化进行设置的功能块,设置锁定以及设置档位:

    设置锁定量程的发送数据是例如设置电阻锁定量程 01 10 00 05 00 01 02 00 01 67 c5;01是站号,10是写数据,00 05是锁定量程的地址05,00 01是代表锁定量程是仅有一个地址,02是发送两个字节,00 01是发送的数据,67 c5的Modbus协议的CRC校验码(推荐网址:http://www.ip33.com/crc.html)

    设置档位的发送数据是 01 10 00 07 00 01 02 00 03 e7 e6;01是站号,10是写数据,00 05是锁定量程的地址05,00 01是代表锁定量程是仅有一个地址,02是发送两个字节,00 03是设定档位3(档位0 0.001k欧姆 档位1 0.0001k欧姆 档位2 0.01欧姆 档位3 0.001欧姆  档位4 0.0001欧姆 档位5 0.01m欧姆)e7 e6的Modbus协议的CRC校验码。

    以下是设置初始化的代码:
      //自由协议读取485讯息功能块
      //设置档位 设置上下限 锁定
      FUNCTION_BLOCK FB_Serial_SetPar
      VAR_INPUT
        b_Start              :  BOOL              ;//进行读取
      END_VAR
      VAR_OUTPUT
        b_Busy              :  BOOL              ;//On:正在读取中
        b_Done              :  BOOL              ;//On:执行完成
        
        b_Error_UnConnect        :  BOOL              ;//没有连接上直流电阻仪器
      END_VAR
      VAR
        ui_Loop              :  UINT              ;//读取的流程
        Ton_Delay_unKeep        :  ARRAY[0..5] OF TON        ;//读取信息的时间间隔
        w_Level              :  WORD              ;//档位0 0.001k欧姆 档位1 0.0001k欧姆 档位2 0.01欧姆 档位3 0.001欧姆  档位4 0.0001欧姆 档位5 0.01m欧姆
        
        r_TRIG_Start          :  R_TRIG              ;//启动运行触发上升沿
        
      END_VAR
      以上是变量的设置,以下是程序:
        //清除读取寄存器标志延时
        Ton_Delay_unKeep[0](IN:=Serial.w_Read=0,
                  PT:=T#100MS);
        //等待回传数据延时
        Ton_Delay_unKeep[1](IN:=ui_Loop=400,
                  PT:=T#500MS);
        //写入设置档位2延时
        Ton_Delay_unKeep[2](IN:=ui_Loop=1200,
                  PT:=T#500MS);
                  
        //写入锁定档位延时
        Ton_Delay_unKeep[3](IN:=ui_Loop=2200,
                  PT:=T#500MS);
                  
        //写入锁定档位延时
        Ton_Delay_unKeep[4](IN:=ui_Loop=3200,
                  PT:=T#500MS);
                  
        r_TRIG_Start(CLK:=b_Start);

        CASE  ui_Loop  OF
          0://判定读取是否有开启
            IF  r_TRIG_Start.Q
              THEN
                b_Done R= TRUE;
                b_Busy S= TRUE;
                b_Error_UnConnect R= TRUE; 
                IF  NOT b_Done        AND
                  b_Busy          AND
                  NOT b_Error_UnConnect
                  THEN
                    ui_Loop := 100;
                END_IF
            END_IF
          100://开始设置
            Serial.w_Write_Bit[0]:=16#0301;//01代表串口站号1 03代表读取多个寄存器
            Serial.w_Write_Bit[1]:=16#0200;//0002代表读取的起始地址,02 03是电阻的读取地址
            Serial.w_Write_Bit[2]:=16#0200;//0002代表读取的个数,则读取02 03两个寄存器
            Serial.w_Write_Bit[3]:=16#CB65;//CB65是01 03 00 02 00 02的CRC16 Modbus校验码
            IF  Serial.w_Write_Bit[0]=16#0301      AND
              Serial.w_Write_Bit[1]=16#0200      AND
              Serial.w_Write_Bit[2]=16#0200      AND
              Serial.w_Write_Bit[3]=16#CB65
              THEN
                ui_Loop := 200;
            END_IF
          200://将读取的寄存器清零 并且延时
            Serial.w_Read:= 0;
            Serial.w_Read_Bit[0]:= 0;
            Serial.w_Read_Bit[1]:= 0;
            Serial.w_Read_Bit[2]:= 0;
            Serial.w_Read_Bit[3]:= 0;
            Serial.w_Read_Bit[4]:= 0;
            Serial.w_Read_Bit[5]:= 0;
            Serial.w_Read_Bit[6]:= 0;
            Serial.w_Read_Bit[7]:= 0;
            Serial.w_Read_Bit[8]:= 0;
            Serial.w_Read_Bit[9]:= 0;
            IF  Serial.w_Read=0    AND
              Serial.w_Read_Bit[0]=0  AND
              Serial.w_Read_Bit[1]=0  AND
              Serial.w_Read_Bit[2]=0  AND
              Serial.w_Read_Bit[3]=0  AND
              Serial.w_Read_Bit[4]=0  AND
              Serial.w_Read_Bit[5]=0  AND
              Serial.w_Read_Bit[6]=0  AND
              Serial.w_Read_Bit[7]=0  AND
              Serial.w_Read_Bit[8]=0  AND
              Serial.w_Read_Bit[9]=0  AND
              Ton_Delay_unKeep[0].Q
              THEN
                ui_Loop := 300;
            END_IF
          300://写入寄存器值赋8,开始读取
            Serial.w_Write:= 8;
            ui_Loop := 400;
          400://等待反馈数据延时
            IF  Ton_Delay_unKeep[1].Q
              THEN
                ui_Loop := 500;
            END_IF
          500://判断读取数据的首个寄存器是否等于16#0301
            IF  Serial.w_Read_Bit[0]=16#0301
              THEN
                ui_Loop := 2000;
              ELSE
                b_Error_UnConnect S= TRUE;
                b_Busy R= TRUE;
                IF  b_Error_UnConnect  AND
                  NOT b_Busy
                  THEN
                    ui_Loop := 0;
                END_IF
            END_IF

          2000://锁定档位
            Serial.w_Write_Bit[0]:=16#1001;//01代表串口站号1 10代表写寄存器
            Serial.w_Write_Bit[1]:=16#0500;//0007代表锁定量程的地址
            Serial.w_Write_Bit[2]:=16#0100;//0001代表写入一个寄存器地址到0005
            Serial.w_Write_Bit[3]:=16#0002;//低位02代表写入两个字节 高位00和下面的低位都是写入05的值
            Serial.w_Write_Bit[4]:=16#6701;//低位01代表锁定档位 高位67和下面的低位都是CRC校验码
            Serial.w_Write_Bit[5]:=16#00C5;//低位C5是CRC校验码
            IF  Serial.w_Write_Bit[0]=16#1001      AND
              Serial.w_Write_Bit[1]=16#0500      AND
              Serial.w_Write_Bit[2]=16#0100      AND
              Serial.w_Write_Bit[3]=16#0002      AND
              Serial.w_Write_Bit[4]=16#6701      AND
              Serial.w_Write_Bit[5]=16#00C5
              THEN
                ui_Loop := 2100;
            END_IF
          2100://写入锁定档位
            Serial.w_Write:= 11;
            ui_Loop := 2200;
          2200://写入锁定档位延时
            IF  Ton_Delay_unKeep[3].Q
              THEN
                ui_Loop := 2300;
            END_IF
          2300://清除读取标志
            Serial.w_Read:= 0;
            Serial.w_Read_Bit[0]:= 0;
            Serial.w_Read_Bit[1]:= 0;
            Serial.w_Read_Bit[2]:= 0;
            Serial.w_Read_Bit[3]:= 0;
            Serial.w_Read_Bit[4]:= 0;
            Serial.w_Read_Bit[5]:= 0;
            Serial.w_Read_Bit[6]:= 0;
            Serial.w_Read_Bit[7]:= 0;
            Serial.w_Read_Bit[8]:= 0;
            Serial.w_Read_Bit[9]:= 0;
            IF  Serial.w_Read=0    AND
              Serial.w_Read_Bit[0]=0  AND
              Serial.w_Read_Bit[1]=0  AND
              Serial.w_Read_Bit[2]=0  AND
              Serial.w_Read_Bit[3]=0  AND
              Serial.w_Read_Bit[4]=0  AND
              Serial.w_Read_Bit[5]=0  AND
              Serial.w_Read_Bit[6]=0  AND
              Serial.w_Read_Bit[7]=0  AND
              Serial.w_Read_Bit[8]=0  AND
              Serial.w_Read_Bit[9]=0  AND
              Ton_Delay_unKeep[0].Q
              THEN
                ui_Loop := 1000;
            END_IF
          1000://设置档03
            Serial.w_Write_Bit[0]:=16#1001;//01代表串口站号1 10代表写寄存器
            Serial.w_Write_Bit[1]:=16#0700;//0007代表档位的地址
            Serial.w_Write_Bit[2]:=16#0100;//0001代表写入一个寄存器地址到0007
            Serial.w_Write_Bit[3]:=16#0002;//低位02代表写入两个字节 高位00和下面的低位都是写入07的值
            Serial.w_Write_Bit[4]:=16#E703;//低位03代表档位2 高位E7和下面的低位都是CRC校验码
            Serial.w_Write_Bit[5]:=16#00E6;//低位E6是CRC校验码
            
            IF  Serial.w_Write_Bit[0]=16#1001      AND
              Serial.w_Write_Bit[1]=16#0700      AND
              Serial.w_Write_Bit[2]=16#0100      AND
              Serial.w_Write_Bit[3]=16#0002      AND
              Serial.w_Write_Bit[4]=16#E703      AND
              Serial.w_Write_Bit[5]=16#00E6
              THEN
                ui_Loop := 1100;
            END_IF
          1100://写入设置档位2
            Serial.w_Write:= 11;
            ui_Loop := 1200;
          1200://写入设置档位2延时
            IF  Ton_Delay_unKeep[2].Q
              THEN
                ui_Loop := 1300;
            END_IF
          1300://清除读取标志
            Serial.w_Read:= 0;
            Serial.w_Read_Bit[0]:= 0;
            Serial.w_Read_Bit[1]:= 0;
            Serial.w_Read_Bit[2]:= 0;
            Serial.w_Read_Bit[3]:= 0;
            Serial.w_Read_Bit[4]:= 0;
            Serial.w_Read_Bit[5]:= 0;
            Serial.w_Read_Bit[6]:= 0;
            Serial.w_Read_Bit[7]:= 0;
            Serial.w_Read_Bit[8]:= 0;
            Serial.w_Read_Bit[9]:= 0;
            IF  Serial.w_Read=0    AND
              Serial.w_Read_Bit[0]=0  AND
              Serial.w_Read_Bit[1]=0  AND
              Serial.w_Read_Bit[2]=0  AND
              Serial.w_Read_Bit[3]=0  AND
              Serial.w_Read_Bit[4]=0  AND
              Serial.w_Read_Bit[5]=0  AND
              Serial.w_Read_Bit[6]=0  AND
              Serial.w_Read_Bit[7]=0  AND
              Serial.w_Read_Bit[8]=0  AND
              Serial.w_Read_Bit[9]=0  AND
              Ton_Delay_unKeep[0].Q
              THEN
                ui_Loop := 4000;
            END_IF
          3000://设置档03
            Serial.w_Write_Bit[0]:=16#1001;//01代表串口站号1 10代表写寄存器
            Serial.w_Write_Bit[1]:=16#0800;//0007代表档位的地址
            Serial.w_Write_Bit[2]:=16#0200;//0001代表写入一个寄存器地址到0007
            Serial.w_Write_Bit[3]:=16#0004;//低位02代表写入两个字节 高位00和下面的低位都是写入07的值
            Serial.w_Write_Bit[4]:=16#0300;//低位03代表档位2 高位E7和下面的低位都是CRC校验码
            Serial.w_Write_Bit[5]:=16#00E8;//低位E6是CRC校验码
            
            IF  Serial.w_Write_Bit[0]=16#1001      AND
              Serial.w_Write_Bit[1]=16#0800      AND
              Serial.w_Write_Bit[2]=16#0200      AND
              Serial.w_Write_Bit[3]=16#0004      AND
              Serial.w_Write_Bit[4]=16#0300      AND
              Serial.w_Write_Bit[5]=16#00E8
              THEN
                ui_Loop := 3100;
            END_IF
          3100://写入设置档位2
            Serial.w_Write:= 11;
            ui_Loop := 3200;
          3200://写入设置档位2延时
            IF  Ton_Delay_unKeep[4].Q
              THEN
                ui_Loop := 3300;
            END_IF
          3300://清除读取标志
            Serial.w_Read:= 0;
            Serial.w_Read_Bit[0]:= 0;
            Serial.w_Read_Bit[1]:= 0;
            Serial.w_Read_Bit[2]:= 0;
            Serial.w_Read_Bit[3]:= 0;
            Serial.w_Read_Bit[4]:= 0;
            Serial.w_Read_Bit[5]:= 0;
            Serial.w_Read_Bit[6]:= 0;
            Serial.w_Read_Bit[7]:= 0;
            Serial.w_Read_Bit[8]:= 0;
            Serial.w_Read_Bit[9]:= 0;
            IF  Serial.w_Read=0    AND
              Serial.w_Read_Bit[0]=0  AND
              Serial.w_Read_Bit[1]=0  AND
              Serial.w_Read_Bit[2]=0  AND
              Serial.w_Read_Bit[3]=0  AND
              Serial.w_Read_Bit[4]=0  AND
              Serial.w_Read_Bit[5]=0  AND
              Serial.w_Read_Bit[6]=0  AND
              Serial.w_Read_Bit[7]=0  AND
              Serial.w_Read_Bit[8]=0  AND
              Serial.w_Read_Bit[9]=0  AND
              Ton_Delay_unKeep[0].Q
              THEN
                ui_Loop := 4000;
            END_IF
            
          4000://
            b_Busy R= TRUE;
            b_Done S= TRUE;
            ui_Loop := 0;
        END_CASE
        接下来是电阻的不断读取设置:
        读取电阻的发送数据是01 03 00 02 00 02 65 cb;01是站号,03是读多个寄存器,00 02是电阻的起始地址02,00 02是代表连续的两个地址即02,03,65 cb的Modbus协议的CRC校验码。所以对于前面AC801读取起始地址是03能获得正确的电阻数据,实在是奇怪,需要学习的还有很多。

        以下是读取电阻的代码:

          //自由协议读取485讯息功能块
          //读取电阻
          FUNCTION_BLOCK FB_Serial_ReadOhm
          VAR_INPUT
            b_Start              :  BOOL              ;//进行读取
            b_Reset              :  BOOL              ;//对读取的寄存器进行复位
          END_VAR
          VAR_OUTPUT
            b_Busy              :  BOOL              ;//On:正在读取中
            b_ResetDone            :  BOOL              ;//重置完成
            
            w_Level              :  WORD              ;//档位0 0.001k欧姆 档位1 0.0001k欧姆 档位2 0.01欧姆 档位3 0.001欧姆  档位4 0.0001欧姆 档位5 0.01m欧姆
            dw_ShowOhm            :  DWORD              ;//电子显示屏显示的数值 不包含小数点
          END_VAR
          VAR
            ui_Loop              :  UINT              ;//读取的流程
            Ton_Delay_unKeep        :  TON                ;//读取信息的时间间隔
            
            
            Rtrg_Reset            :  R_TRIG              ;//复位回采寄存器信号
          END_VAR

          以上是变量,以下是功能块代码:
            Ton_Delay_unKeep(IN:=Serial.w_Read=0,
                    PT:=T#100MS);

            Rtrg_Reset(  CLK:=b_Reset);

            CASE  ui_Loop  OF
              0://判定读取是否有开启
                //进行电阻信号的读取
                IF  b_Start      AND
                  NOT b_Reset
                  THEN
                    b_Busy S= TRUE;
                    IF  b_Busy
                      THEN
                        ui_Loop := 100;
                    END_IF
                END_IF
                //当不进行电阻信号的读取以及不进行复位回采的寄存器标志时候
                //停止运行
                IF  NOT b_Start    AND
                  NOT b_Reset
                  THEN
                    b_Busy R= TRUE;
                END_IF
                //进行回采信号的重置
                IF  Rtrg_Reset.Q
                  THEN
                    ui_Loop := 1000;
                END_IF
              100://开始设置
                b_ResetDone R= TRUE;
                Serial.w_Write_Bit[0]:=16#0301;//01代表串口站号1 03代表读取多个寄存器
                Serial.w_Write_Bit[1]:=16#0200;//0002代表读取的起始地址,02 03是电阻的读取地址
                Serial.w_Write_Bit[2]:=16#0200;//0002代表读取的个数,则读取02 03两个寄存器
                Serial.w_Write_Bit[3]:=16#CB65;//CB65是01 03 00 02 00 02的CRC16 Modbus校验码
                IF  Serial.w_Write_Bit[0]=16#0301      AND
                  Serial.w_Write_Bit[1]=16#0200      AND
                  Serial.w_Write_Bit[2]=16#0200      AND
                  Serial.w_Write_Bit[3]=16#CB65
                  THEN
                    ui_Loop := 200;
                END_IF
              200://将读取的寄存器清零 并且延时
                Serial.w_Read:= 0;
                IF  Serial.w_Read=0    AND
                  Ton_Delay_unKeep.Q
                  THEN
                    ui_Loop := 300;
                END_IF
              300://写入寄存器值赋8,开始读取
                Serial.w_Write:= 8;
                ui_Loop := 400;
              400://处理数据
                //回采数据第一个字节应该是16#0103,则01代表串口站号1 03代表读取多个寄存器
                //回采数据第二个字节地位是字节的长度,高位是数组的档位
                //档位0 0.001k欧姆 档位1 0.0001k欧姆 档位2 0.01欧姆 档位3 0.001欧姆  档位4 0.0001欧姆 档位5 0.01m欧姆
                w_Level:=SWAP16(Serial.w_Read_Bit[1]AND(16#FF00));
                //回采数据第三个字节以及第四个字节的低位是当前的显示值
                dw_ShowOhm:=WORD_TO_DWORD(Serial.w_Read_Bit[2])+WORD_TO_DWORD(Serial.w_Read_Bit[3]AND(16#00FF));
                ui_Loop := 0;
              1000://重置前进行信号的处理
                b_ResetDone R= TRUE;
                IF  NOT b_ResetDone
                  THEN
                    ui_Loop := 1100;
                END_IF
              1100://开始复位重置
                Serial.w_Read:= 0;
                Serial.w_Read_Bit[0]:= 0;
                Serial.w_Read_Bit[1]:= 0;
                Serial.w_Read_Bit[2]:= 0;
                Serial.w_Read_Bit[3]:= 0;
                Serial.w_Read_Bit[4]:= 0;
                Serial.w_Read_Bit[5]:= 0;
                Serial.w_Read_Bit[6]:= 0;
                Serial.w_Read_Bit[7]:= 0;
                Serial.w_Read_Bit[8]:= 0;
                Serial.w_Read_Bit[9]:= 0;
                IF  Serial.w_Read=0    AND
                  Serial.w_Read_Bit[0]=0  AND
                  Serial.w_Read_Bit[1]=0  AND
                  Serial.w_Read_Bit[2]=0  AND
                  Serial.w_Read_Bit[3]=0  AND
                  Serial.w_Read_Bit[4]=0  AND
                  Serial.w_Read_Bit[5]=0  AND
                  Serial.w_Read_Bit[6]=0  AND
                  Serial.w_Read_Bit[7]=0  AND
                  Serial.w_Read_Bit[8]=0  AND
                  Serial.w_Read_Bit[9]=0  AND
                  Ton_Delay_unKeep.Q
                  THEN
                    ui_Loop := 1200;
                END_IF
              1200://重置完成
                b_ResetDone S= TRUE;
                ui_Loop := 0;
            END_CASE


            免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

            本帖子中包含更多资源

            您需要 登录 才可以下载或查看,没有账号?注册哦

            x
            您需要登录后才可以回帖 登录 | 注册哦

            本版积分规则