发 帖  
张飞软硬开源基于STM32 BLDC直流无刷电机驱动器开发视频套件, 👉戳此立抢👈

[经验] T5 Modbus详解(附样例)

2019-1-29 10:45:46  3357 单片机 Modbus 液晶屏 ARM MCU
分享
0
1. 0 基于 Modbus 主机接口的 OS 方案
用户可通过 22.BIN 字库文件 0x1C000~0x1FFFF 的 16KB 空间大小来定义 Modbus 数;也可通过 T5 OS 直接访问 0xE000~0xFFFF 的 8KW 变量空间来定义 Modbus ;


定义如下表:
1.PNG

Modbus Master 指令操作对应表(注意,Modbus 的位(线圈)变量是按照 LSB 定义的,T5 平台是按照 MSB 定义)
2.PNG

备注:
1. 0xE000-0xE007 的参数为主从机通用,Modbus 通信不启用时,0xE000-0xFFFF 空间以及 UART4 可任意使用;启用 Modbus 通信时,必须按表中格式配置相关参数;
2. 串口波特率设置参数(0xE002)若被写入 0x0000 时,将恢复 UART4 默认波特率(115200bps);波特率具体可设置范围请参考 T5OS 开发指南;
3. 读/写指令等待时间设置范围为 1~9999mS,默认为 60mS;(若写入 0,则自动恢复为默认值);
4. 采用 02 模式发送 Modbus 指令时,程序检测到指定 VP 地址的变量为 0x5A 时立即发送,发送完成清零 VP 变量内容,同时令指令等待时间计时器重新开始计时;
5.单次最多可读写 90 个字,若设定读写数据长度大于上限,则会自动跳过该条无效
指令;
6.禁止将读写数据在 VP 空间的起始地址以及起始地址+数据长度大于 0xDFFF,否则将视为无效指令;

2.0 基于 Modbus 从机接口的 OS 方案
Modbus Slave 指令操作表如下:(设备地址默认为 0x5A,若设定值为 0,则自动恢复默认 ID)
3.PNG
备注:
1. 主机可读写数据变量范围为 0x0000-0xDFFF,若超出此范围,程序会将功能码最高位置 1 并返回给主机,表明通信错误;
2. 主机可读写数据长度上限为 90 个字,超出范围则通信失败。


3.0 22 号文件初始化说明
(1)首先请确保 T5 屏幕系统配置值为“上电加载 22 号文件初始化”(具体配置方法请参考<T5UID1 应用指南>,屏幕出厂默认已经配置好,用户一般无需重新配置);
(2)此版程序基本功能与 DGUS 屏的 MDOBUS 主从机基本一致,但 22 号文件的参数配置地址改为了 0x1C000~0x1FFFF,对映 T5 变量空间中的最后 8KW 地址 0xE000~0xFFFF;
(3)指令等待时间参数的设置范围与波特率以及 MODBUS 指令长度有关,默认 115200bps下,建议最小设置为 20mS;(若不设置此参数,则程序以默认值 60mS 运行)
(4)如下图所示,图 1 为 Modbus 主机模式下的 22 号文件配置参考,0x1c000 开始的 16 字节内容为接口参数;指令配置范围 0x1c010~0x1ffff,最多 1023 条指令,两条指令之间可以连续也可以间隔若干条指令地址;
图 2 为 Modbus 从机模式下的 22 号文件配置参考,仅配置 0x1c000 开始的 16 个字节即可;(主从机模式的 22 号参考文件请见附件)

4.PNG
图 1 主机参数配置
5.PNG
图 2 从机参数配置参数


4.0 参考样例
  1.     ;DWIN OS
  2.     ;T5 MODBUS V5 20181130 08:56        ;
  3.     ;R10寄存器以被Modbus程序占用,用户禁止使用
  4.         ORG 1000H
  5.           GOTO SYS_Init        ;代码的第一条指令必须是GOTO指令跳转到初始化或者主程序
  6.           GOTO T0INT                ;中断定时器0服务程序入口,必须用GOTO跳转
  7.         NOP                                ;中断定时器1服务程序入口,NOP指令表示未使用
  8.           NOP                                ;中断定时器2服务程序入口
  9.          
  10.         ORG 1080H
  11. SYS_Init:
  12. ;        CALL MODBUS_SET                        ;MODBUS参数配置,用于测试(也可用于从OS配置MODBUS)
  13.     CALL UART_Init                        ;串口初始化
  14.     CALL Constant_Init                ;常量初始化(应用程序版本号)
  15.     CALL tiMER0_Init                ;中断定时器0初始化
  16.         CALL TIMER0_Enable        ;使能中断定时器0
  17.         CALL EA_Enable                ;开定时器总中断
  18.         CONFIG 1,2,30    ;T2定时器,基准30MS
  19.      
  20.         GOTO MAIN
  21. ;中断定时器0服务程序        
  22. T0INT:
  23.         ;保护现场        
  24.         LDBR R10,7,1                        ;此为第0页的R10寄存器        
  25.         MOVRD R10,0,1
  26.         ;第7页寄存器作为Modbus状态变量空间,其他地方禁用               
  27.         IJNE R19,1,T0INT_NEXT        ;MODBUS_RW_STA=1,表示指令已发送
  28.                 INC R20,1,1                        ;MODBUS_Cnt,单位mS
  29.                 ;超时检测
  30.                 IJNE R34,0,2
  31.                 IJNE R35,0,1
  32.                         LDWR R34,60
  33.         JS R20,R34,T0INT_NEXT        ;当前指令等待时间,最大值为9999mS
  34.                 ;清零相关参数,进入下一条指令
  35.                 LDBR R18,0,4
  36.                 LDBR R30,0,16
  37. T0INT_NEXT:     
  38.         ;恢复现场
  39.         LDBR R10,0,1                ;此为第7页的R10寄存器
  40.         MOVRD R10,0,1
  41.         RETI                                ;中断返回,必须用RETI指令
  42. ;主函数        
  43. MAIN:
  44.         CALL Modbus_Master        ;主机Modbus程序
  45.         ;CALL Modbus_Slave        ;从机Modbus程序
  46.         CALL   基准定时ms
  47.         CALL   FUZHI  ;上电附初值
  48.       CALL SYS_STU
  49.       
  50.         GOTO MAIN  
  51. ;*****************应用程序


  52.       
  53. 基准定时ms:             ;每30ms增1
  54.            LDBR R20,0,50
  55.            MOVDR 37,R60,2
  56.                 LDWR R62,1   ;
  57.                 JS R60,R62,MS_RET
  58.                 LDWR R0,4000H
  59.            MOVXR R20,1,1
  60.            INC R20,1,1
  61.            MOVXR R20,0,1
  62.                 LDWR R60,0
  63.                MOVRD R60,37,2  
  64.                RET   
  65.    MS_RET:
  66.            RET  


  67.                
  68.                
  69. FUZHI:
  70.        LDWR R0,4000H
  71.        MOVXR R20,1,1
  72.        LDWR R22,10
  73.        JS R20,R22,FUZHI_RUN
  74.        LDWR R0,4000H
  75.        LDWR R20,100
  76.        MOVXR R20,0,1
  77.        LDWR R0,4001H
  78.        LDWR R20,1
  79.        MOVXR R20,0,1
  80.        RET   
  81.    
  82. FUZHI_RUN:
  83.         
  84.         LDWR R0,2000H
  85.         LDWR R2,3000H
  86.         MOVXX 14
  87.         RET


  88.   SYS_STU:
  89.           LDWR R0,0X4001
  90.           MOVXR R20,1,1
  91.           IJNE R21,1,1
  92.           CALL BILI_STU
  93.          
  94.           RET

  95. BILI_STU:
  96.            LDWR R0,3000H
  97.            MOVXR R20,1,14
  98.            LDWR R0,2000H
  99.            MOVXR R80,1,14
  100.            TESTS R20,R80,28
  101.            IJNE R0,0,1
  102.            RET
  103.            LDWR R0,0X1700
  104.            LDWR R150,0X005A
  105.            MOVXR R150,0,1
  106.            RET


  107.         
  108. ;******************************
  109. MODBUS_SET:
  110.         LDWR R0,Modbus_EN        ;MODBUS启用标记
  111.         LDWR R60,5AA5H                ;0x5AA5=启用,其他=不启用        
  112.         LDWR R62,0                ;主从机标记,0=主机,1=从机
  113.         LDWR R64,1152                ;串口波特率,115200bps
  114.         LDWR R66,0                ;串口模式,8N1
  115.         LDWR R68,5AH                ;从机设备地址
  116.         MOVXR R60,0,5
  117.         ;
  118.         LDADR MODBUS_CMD1_TAB        ;第一条指令表
  119.         MOVC R60,16
  120.         LDWR R0,Modbus_CMD1
  121.         MOVXR R60,0,8
  122.         ;
  123.         LDADR MODBUS_CMD2_TAB
  124.         MOVC R60,16
  125.         LDWR R0,Modbus_CMD1
  126.         INC R0,1,8
  127.         MOVXR R60,0,8
  128.         ;
  129.         LDADR MODBUS_CMD3_TAB
  130.         MOVC R60,16
  131.         LDWR R0,Modbus_CMD1
  132.         INC R0,1,16
  133.         MOVXR R60,0,8
  134.         RET
  135.         
  136. UART_Init:
  137.         ;UART4配置,详见<基于T5CPU的DWIN OS程序开发指南>
  138.         LDWR R0,Modbus_EN        ;Modbus启用标记
  139.         MOVXR R60,1,1
  140.         LDWR R62,5AA5H
  141.         TESTS R60,R62,2
  142.         IJNE R0,0,UART_Init_RET
  143.         ;Modbus_EN=0x5AA5,启用Modbus,从0xE002读取串口配置信息
  144.         LDBR R20,40H,1                ;串口4
  145.         LDWR R0,Modbus_UART        ;0xE002-E003为串口配置参数
  146.         MOVXR R60,1,2
  147.         LDWR R70,4
  148.         JU R62,R70,1                ;R63为串口模式设置参数,设置范围0-3
  149.             LDWR R62,0
  150.         OR R20,R63,1
  151.         LDWR R64,0
  152.         TESTS R60,R64,2
  153.         IJNE R0,0,1
  154.                         LDWR R60,1152        ;若波特率设定值为0,则恢复默认波特率
  155.         LDBR R70,0,8
  156.         MOV R60,R70,2                ;波特率设置值,单位*100bps
  157.         LDWR R72,100
  158.         SMAC R70,R72,R74
  159.         LDBR R70,0,4
  160.         LDBR R80,0,8
  161.         LDWR R84,EFH
  162.         LDWR R86,1000H                ;0xEF1000=15667200
  163.         DIV R80,R70,0
  164.         MOV R86,R21,2
  165.         COMSET R20,0
  166. UART_Init_RET:               
  167.         RET
  168.         
  169. TIMER0_Init:
  170.         ;定时参数设置
  171.         LDBR R20,100,1                ;100*10uS=1mS
  172.         MOVRD R20,46,1                ;DR46=Timer INT0 Set        
  173.         RET
  174.         
  175.         
  176. TIMER0_Enable:
  177.         ;开定时器0中断
  178.         MOVDR 45,R20,1                ;DR45=Int_Reg
  179.         LDBR R21,40H,1                ;Int_Reg.6=Timer INT0 Enable
  180.         OR R20,R21,1
  181.         MOVRD R20,45,1
  182.         RET
  183.         
  184. TIMER0_Disable:
  185.         ;关定时器0中断
  186.         MOVDR 45,R20,1
  187.         LDBR R21,BFH,1
  188.         AND R20,R21,1
  189.         MOVRD R20,45,1
  190.         RET
  191.         
  192. EA_Enable:
  193.         ;开定时器总中断
  194.         MOVDR 45,R20,1
  195.         LDBR R21,80H,1                ;Int_Reg.7=EA
  196.         OR R20,R21,1
  197.         MOVRD R20,45,1
  198.         RET
  199.         
  200. EA_Disable:
  201.         ;关定时器总中断
  202.         MOVDR 45,R20,1
  203.         LDBR R21,7FH,1
  204.         AND R20,R21,1
  205.         MOVRD R20,45,1
  206.         RET

  207. Constant_Init:
  208.         ;将版本号保存在变量空间,方便从串口读取
  209.         LDADR Version_TAB
  210.         MOVC R20,2
  211.         LDWR R0,Mdobus_Ver
  212.         MOVXR R20,0,1
  213.         RET
  214.         
  215. Modbus_Master:
  216.         LDWR R0,Modbus_EN                ;Modbus启用标记,5AA5H表示启用Modbus_Master
  217.         MOVXR R60,1,1
  218.         IJNE R60,5AH,Modbus_Master_RET
  219.         IJNE R61,A5H,Modbus_Master_RET     
  220.         LDWR R0,Modbus_Mode                ;Modbus主从机模式
  221.         MOVXR R60,1,1
  222.         IJNE R61,0,Modbus_Master_RET
  223.         ;Modbus主机
  224.         RDXLEN 4,R18                ;读串口4接收缓冲区字节长度
  225.         IJNE R18,0,Modbus_Master_Rx
  226.         ;0x00表示接收缓冲区没有数据,可以发送
  227.                 GOTO Modbus_Master_Tx
  228. Modbus_Master_Rx:
  229.         MOVDR 17,R19,1           ;DR17表示串口4接收帧超时定时器状态
  230.         IJNE R19,0,Modbus_Master_RET
  231.         ;DR17=0x00表示一帧数据接收完成
  232.         RDXDAT 4,R20,R18        ;读取串口缓冲区数据到R20开始的寄存器
  233.         DEC R18,0,2
  234.         CRCA R20,R16,R18        ;计算CRC16校验值,结果存放在R16:R17
  235.         MOV R16,R254,2
  236.         LDBR R238,0,8                ;R238-253,16个寄存器
  237.         LDWR R240,20                ;数据帧起始位置
  238.         MOV R18,R245,1                ;帧长度-校验位
  239.         ADD R238,R242,R246
  240.         MOV R253,R2,1                ;数据帧中CRC校验值存放位置
  241.         LDBR R3,18,1
  242.         LDBR R9,2,1
  243.         MOVA
  244.         CJNE R254,R18,MODBUS_MasterRx_ERR
  245.         CJNE R255,R19,MODBUS_MasterRx_ERR
  246.         ;校验正确,数据帧存放的寄存器空间为R20-R199,最长180字节
  247.         LDWR R0,MODBUS_CMD_Buff        ;当前16字节指令缓存区
  248.         LDWR R2,240
  249.         LDBR R9,16,1
  250.         MOVA 1
  251.         CJNE R241,R20,MODBUS_MasterRx_ERR
  252.         ;站号匹配
  253.         IJNE R21,1,2
  254.         ;从机响应0x01指令
  255.                         CALL MODBUS_MasterRx_CMD01
  256.             GOTO MODBUS_MasterRx_END
  257.         IJNE R21,2,2
  258.         ;从机响应0x02指令
  259.                         CALL MODBUS_MasterRx_CMD01        ;0x02指令响应内容与0x01类似,数据存储格式为LSB
  260.             GOTO MODBUS_MasterRx_END
  261.         IJNE R21,3,2
  262.         ;从机响应0x03指令
  263.                         CALL MODBUS_MasterRx_CMD03        ;0x03指令响应,数据存储格式为MSB
  264.             GOTO MODBUS_MasterRx_END
  265.         IJNE R21,4,2
  266.         ;从机响应0x04指令
  267.                         CALL MODBUS_MasterRx_CMD03        ;0x04指令响应内容与0x03类似
  268.             GOTO MODBUS_MasterRx_END
  269.         IJNE R21,7,2
  270.         ;从机响应0x07指令
  271.                         CALL MODBUS_MasterRx_CMD07
  272.             GOTO MODBUS_MasterRx_END
  273.         IJNE R21,5,1
  274.                         GOTO MODBUS_MasterRx_END
  275.         IJNE R21,6,1
  276.                         GOTO MODBUS_MasterRx_END
  277.         IJNE R21,0FH,1
  278.                         GOTO MODBUS_MasterRx_END
  279.         IJNE R21,10H,MODBUS_MasterRx_ERR      
  280. MODBUS_MasterRx_END:
  281.         ;当前指令已完成收发,下一条指令不再延时,准备直接发送
  282.         MOV R244,R60,2
  283.         LDWR R0,60
  284.         LDWR R2,MODBUS_Cnt
  285.         LDBR R9,2,1
  286.         MOVA 1
  287.         LDWR R100,FFH                ;通信成功
  288.         CALL MODBUS_STA_FeedBack
  289.         GOTO Modbus_Master_RET
  290. MODBUS_MasterRx_ERR:
  291.         LDWR R100,0                ;通信失败
  292.         CALL MODBUS_STA_FeedBack
  293.         GOTO Modbus_Master_RET
  294.         
  295. Modbus_Master_Tx:
  296.         CALL TIMER0_Disable                        ;停止定时器0中断
  297.         LDWR R0,MODBUS_STA                        ;MODBUS指令状态,0表示可以进入下一条指令,1表示正在计时
  298.         LDWR R2,60
  299.         LDBR R9,1,1
  300.         MOVA 1
  301.         IJNE R60,0,Modbus_MasterTx_NEXT
  302.         CALL Modbus_Master_CMDCheck        ;检测并依次读取有效指令
  303.         IJNE R50,0,1
  304.                 GOTO Modbus_Master_END
  305.         ;当前指令有效
  306.         LDBR R60,1,1        ;MODBUS指令状态标记置1
  307.         LDBR R61,0,1        ;MODBUS_RW_STA
  308.         LDWR R0,60
  309.         LDWR R2,MODBUS_STA
  310.         LDBR R9,2,1
  311.         MOVA 1
  312. Modbus_MasterTx_NEXT:
  313.         LDWR R0,MODBUS_CMD_Buff                ;当前16字节发送指令缓存区
  314.         LDWR R2,20
  315.         LDBR R9,16,1
  316.         MOVA 1
  317.         IJNE R27,2,Modbus_MasterTx_NEXT1
  318.         ;0x02模式,直接发送
  319.                 MOV R28,R0,2
  320.                 LDWR R60,0                ;发送完成后将VP变量内容清零
  321.                 MOVXR R60,0,1
  322.                 LDBR R60,0,16
  323.                 LDWR R0,60
  324.                 LDWR R2,MODBUS_CMD_Buff        ;将指令缓存区清零,防止重复发送本条指令
  325.                 LDBR R9,16,1
  326.                 MOVA 1
  327.                 CALL Modbus_Master_TXD
  328.                 GOTO Modbus_Master_END
  329. Modbus_MasterTx_NEXT1:
  330.         ;MODBUS_RW_STA=0表示可以发送指令,1表示已发送或正在延时
  331.         LDWR R0,MODBUS_RW_STA
  332.         LDWR R2,60
  333.         LDBR R9,1,1
  334.         MOVA 1
  335.         IJNE R60,0,1
  336.                 CALL Modbus_Master_TXD        ;执行当前指
  337. Modbus_Master_END:               
  338.         CALL TIMER0_Enable
  339. Modbus_Master_RET:
  340.     RET

  341. MODBUS_MasterRx_CMD01:
  342.         LDBR R200,0,16
  343.         MOV R22,R207,1        ;字节数,存在单数
  344.         LDWR R214,2
  345.         DIV R200,R208,0
  346.         IJNE R215,0,1
  347.                 GOTO MODBUS_MasterRx_CMD01_NEXT
  348.         ;单数字节,末位字节填0
  349.         LDBR R216,0,16
  350.         LDWR R218,23                ;首地址
  351.         MOV R206,R222,2                ;除数
  352.         ADD R216,R220,R224
  353.         MOV R214,R226,2                ;余数
  354.         ADD R224,R228,R216        ;首地址R23+除数+余数=需要填0的末位字节地址
  355.         LDWR R216,0
  356.         LDWR R0,216
  357.         MOV R222,R2,2
  358.         LDBR R9,1,1
  359.         MOVA
  360.         INC R207,0,1
  361. MODBUS_MasterRx_CMD01_NEXT:
  362.         MOV R207,R9,1        ;字数
  363.         MOV R250,R0,2        ;变量存储空间首地址
  364.         MOVXR R23,0,0
  365.         RET

  366. MODBUS_MasterRx_CMD03:
  367.         LDBR R200,0,16
  368.         MOV R22,R207,1        ;字节数
  369.         LDWR R214,2
  370.         DIV R200,R208,0         
  371.         MOV R207,R9,1        ;字数
  372.         MOV R250,R0,2        ;变量存储空间首地址
  373.         MOVXR R23,0,0
  374.         RET
  375.         
  376. MODBUS_MasterRx_CMD07:
  377. ;从机响应内容:站号 功能码 异常状态高位 异常状态低位 CRCL CRCH
  378.         MOV R250,R0,2        ;变量存储地址
  379.         MOVXR R22,0,1
  380.         RET

  381. MODBUS_STA_FeedBack:
  382.         ;总线通信状态反馈,用户读取通信状态反馈字后应清零        
  383.         LDBR R60,0,16
  384.         LDWR R0,MODBUS_SP
  385.         LDWR R2,62
  386.         LDBR R9,2,1
  387.         MOVA 1
  388.         JU R60,R62,2
  389.         ;R62:R63=0,上一刻发送的是第1022条指令(最后一条)
  390.                 LDWR R62,1022
  391.                 GOTO MODBUS_FeedBack_NEXT
  392.         DEC R62,1,1        ;上一刻发送的是第N条指令,N=0~1021
  393. MODBUS_FeedBack_NEXT:
  394.         LDWR R60,8        ;一条指令占8个字
  395.         SMAC R60,R62,R64
  396.         LDBR R60,0,4
  397.         LDWR R62,Modbus_CMD1
  398.         ADD R60,R64,R68        ;SP(Modbus_CMD1)+N*8=当前指令首地址
  399.         LDBR R60,0,12
  400.         LDWR R70,7
  401.         ADD R68,R72,R60        ;当前指令首地址+0x07=总线通信状态反馈地址
  402.         MOV R66,R0,2
  403.         MOVXR R100,0,1      
  404.         RET              
  405.         
  406. Modbus_Master_CMDCheck:
  407.         ;R50=0表示无有效指令,1表示有待发送指令
  408.         ;R20-35为当前待发送指令
  409.         LDBR R50,0,1                ;清空R50寄存器
  410.         LDBR R60,0,8
  411.         LDWR R0,MODBUS_SP        ;当前指令指针,表示第N条指令,0<=N<=1022
  412.         LDWR R2,60                ;目标寄存器地址
  413.         LDBR R9,2,1                ;交换的字节长度
  414.         MOVA 1                        ;寄存器数据交换(跨寄存器页)        
  415.         LDWR R62,8                ;每条指令占8个字
  416.         SMAC R60,R62,R64        ;SP*8为指令偏移字数
  417.         LDBR R70,0,12
  418.         LDWR R72,Modbus_CMD1        ;第一条指令的起始地址
  419.         ADD R70,R64,R74
  420.         MOV R80,R0,2                ;第N条指令的起始地址
  421.         MOVXR R20,1,8
  422.         INC R60,1,1                ;指令指针N+1
  423.         LDWR R100,1023
  424.         JU R60,R100,MM_CMDCheck_NEXT
  425.         ;第1022条指令检测完毕
  426.                 LDWR R60,0                     
  427. MM_CMDCheck_NEXT:
  428.         LDWR R0,60
  429.         LDWR R2,MODBUS_SP        ;保存下一条指令指针N
  430.         LDBR R9,2,1
  431.         MOVA 1
  432.         IJNE R20,5AH,MM_CMDCheck_RET        ;若当前指令无效,则退出,等待下一周再检测下一条指令
  433.         IJNE R23,0,1
  434.             ;读写数据长度=0,本条指令无效
  435.             GOTO MM_CMDCheck_RET
  436.         IJNE R27,1,MM_CMDCheck_NEXT1
  437.             ;0x01模式,在指定页面下执行
  438.             LDWR R0,PIC_Now        ;当前页面ID
  439.             MOVXR R200,1,1
  440.             TESTS R200,R28,2
  441.             IJNE R0,0,MM_CMDCheck_RET
  442.                         GOTO MM_CMDCheck_NEXT2
  443. MM_CMDCheck_NEXT1:
  444.         IJNE R27,2,MM_CMDCheck_NEXT2
  445.         ;0x02模式,仅在指向的变量低字节为0x5A时才执行
  446.                 MOV R28,R0,2
  447.                 MOVXR R200,1,1
  448.                 IJNE R201,5AH,MM_CMDCheck_RET         
  449. MM_CMDCheck_NEXT2:
  450.         LDWR R200,0
  451.         LDWR R202,180                ;数据长度上限,180字节=90字
  452.         MOV R23,R201,1                ;读写数据长度
  453.         JU R202,R200,MM_CMDCheck_RET
  454.         LDBR R200,0,16
  455.         MOV R30,R202,2                ;读写数据在VP空间的起始地址
  456.         MOV R23,R207,1                ;读写数据长度
  457.         ADD R200,R204,R208
  458.         LDWR R208,DFFFH                ;VP空间可读写上限
  459.         JU R208,R214,MM_CMDCheck_RET
  460.                 ;本条指令有效
  461.                 LDWR R0,20
  462.                 LDWR R2,MODBUS_CMD_Buff        ;将待发送的指令内容写入到发送缓冲区
  463.                 LDBR R9,16,1
  464.                 MOVA 1
  465.                 LDBR R50,1,1
  466. MM_CMDCheck_RET:
  467.         RET
  468.         
  469. Modbus_Master_TXD:
  470.         ;发送状态置1,表明已经发送
  471.         LDBR R60,1,1
  472.         LDWR R0,60
  473.         LDWR R2,MODBUS_RW_STA
  474.         LDBR R9,1,1
  475.         MOVA 1
  476.         ;执行指令
  477.         MOV R21,R60,2        ;ID+功能码
  478.         IJNE R22,1,2
  479.         ;0x01,读取输入线圈状态
  480.             CALL Modbus_Master_CMD01        
  481.             GOTO Modbus_MasterTXD_RET        ;发送指令后,等待从机回复再进入下一条指令      
  482.         IJNE R22,2,2
  483.         ;0x02,读取输入位变量状态
  484.             CALL Modbus_Master_CMD01        ;0x02指令除了功能码以外,其余和0x01指令内容一样
  485.             GOTO Modbus_MasterTXD_RET
  486.         IJNE R22,3,2
  487.         ;0x03,读取保持寄存器数据
  488.             CALL Modbus_Master_CMD03
  489.             GOTO Modbus_MasterTXD_RET
  490.         IJNE R22,4,2        
  491.         ;0x04,读取输入寄存器数据
  492.             CALL Modbus_Master_CMD03        ;0x04指令除功能码外和0x03指令相同
  493.             GOTO Modbus_MasterTXD_RET
  494.         IJNE R22,7,2        
  495.         ;0x07,读取异常状态
  496.             CALL Modbus_Master_CMD07
  497.             GOTO Modbus_MasterTXD_RET
  498.         IJNE R22,5,2        
  499.         ;0x05,强置单个线圈
  500.             CALL Modbus_Master_CMD05
  501.             GOTO Modbus_MasterTXD_RET
  502.         IJNE R22,6,2        
  503.         ;0x06,预置单个寄存器
  504.             CALL Modbus_Master_CMD05        ;0x06指令除功能码外和0x05指令相同
  505.             GOTO Modbus_MasterTXD_RET
  506.         IJNE R22,0FH,2      
  507.         ;0x0F,强置多个线圈
  508.             CALL Modbus_Master_CMD0F
  509.             GOTO Modbus_MasterTXD_RET
  510.         IJNE R22,10H,Modbus_MasterTXD_RET        
  511.         ;0x10,预置多个寄存器
  512.             CALL Modbus_Master_CMD10
  513. Modbus_MasterTXD_RET:   
  514.         RET
  515.         
  516. Modbus_Master_CMD01:        
  517. ;站号ID 功能码 起始地址高位 起始地址低位 总位数高位 总位数低位 CRCL CRCH
  518.         MOV R32,R62,2        ;起始地址
  519.         LDBR R40,0,8
  520.         MOV R23,R41,1        ;待读取数据长度=线圈个数/8
  521.         LDWR R42,8
  522.         SMAC R40,R42,R44 ;总位数(线圈个数)=待读取数据长度*8
  523.         MOV R46,R64,2        ;总位数
  524.         LDBR R40,6,1
  525.         CRCA R60,R66,R40 ;LSB
  526.         INC R40,0,2
  527.         COMTXD 4,R60,R40  
  528.         RET
  529.         
  530. Modbus_Master_CMD03:        
  531. ;站号ID 功能码 起始地址高位 起始地址低位 总寄存器数高位 总寄存器数低位 CRCL CRCH              
  532.         MOV R32,R62,2        ;起始地址
  533.         LDBR R40,0,16
  534.         MOV R23,R47,1        ;待读取数据长度=寄存器数*2
  535.         LDWR R54,2
  536.         DIV R40,R48,0        ;总寄存器数=待读取数据长度/2
  537.         MOV R46,R64,2        ;总寄存器数
  538.         LDBR R40,6,1
  539.         CRCA R60,R66,R40 ;LSB
  540.         INC R40,0,2
  541.         COMTXD 4,R60,R40
  542.         RET
  543.       
  544. Modbus_Master_CMD05:
  545. ;站号ID 功能码 线圈地址高位 线圈地址低位 强制状态高位 强制状态低位 CRCL CRCH
  546.         MOV R32,R62,2        ;线圈地址
  547.         MOV R30,R0,2        ;存放线圈状态的变量地址
  548.         MOVXR R64,1,1
  549.         LDBR R40,6,1
  550.         CRCA R60,R66,R40 ;LSB
  551.         INC R40,0,2
  552.         COMTXD 4,R60,R40
  553.         RET

  554. Modbus_Master_CMD07:
  555. ;站号ID 功能码 CRCL CRCH
  556.         LDBR R40,2,1
  557.         CRCA R60,R62,R40
  558.         INC R40,0,2
  559.         COMTXD 4,R60,R40
  560.         RET
  561.         
  562. Modbus_Master_CMD0F:
  563. ;站号ID 功能码 线圈地址高位 线圈地址低位 线圈数量高位 线圈数量低位 字节数 n*(线圈状态高位 线圈状态低位)  CRCL CRCH
  564.         MOV R32,R62,2        ;线圈地址
  565.         LDBR R64,0,1
  566.         MOV R23,R65,1        ;线圈数量
  567.         LDBR R40,0,16
  568.         MOV R23,R47,1
  569.         LDWR R54,16        ;1字节=16个线圈
  570.         DIV R40,R48,0
  571.         IJNE R55,0,1
  572.         ;余数为0,则字节数正确
  573.                 GOTO Modbus_MasterCMD0F_NEXT
  574.         ;余数不为0,则字节数+1
  575.         INC R47,0,1
  576. Modbus_MasterCMD0F_NEXT:
  577.         MOV R47,R66,1        ;字节数
  578.         MOV R47,R9,1
  579.         MOV R30,R0,2        ;线圈状态存放的变量地址
  580.         MOVXR R67,1,0
  581.         INC R47,0,7
  582.         CRCA R60,R58,R47 ;CRC校验值结果存放在R58:59
  583.         LDBR R40,0,16
  584.         LDWR R42,60        ;目标寄存器起始地址
  585.         MOV R67,R47,1        
  586.         INC R47,0,7        ;数据长度
  587.         ADD R40,R44,R48
  588.         LDBR R2,58,1
  589.         MOV R55,R3,1        ;CRC校验在数据帧中的位置=起始地址+数据长度
  590.         LDBR R9,2,1
  591.         MOVA
  592.         INC R47,0,2        ;数据长度+2字节校验值=数据帧长度
  593.         COMTXD 4,R60,R47
  594.         RET        
  595.       
  596. Modbus_Master_CMD10:
  597. ;站号ID 功能码 起始地址高位 起始地址低位 寄存器总数高位 寄存器总数低位 寄存器总字节数 n*(寄存器值高位 寄存器值低位) CRCL CRCH
  598.         MOV R32,R62,2        ;起始地址
  599.         LDBR R40,0,8
  600.         MOV R23,R47,1        ;字节数
  601.         LDBR R50,0,8
  602.         LDWR R56,2
  603.         DIV R40,R50,0
  604.         MOV R46,R64,2        ;寄存器总数
  605.         MOV R23,R66,1        ;寄存器总字节数
  606.         MOV R30,R0,2        ;待写入变量起始地址
  607.         MOV R65,R9,1        ;数据字长度(1-94)
  608.         MOVXR R67,1,0
  609.         INC R23,0,7
  610.         CRCA R60,R58,R23 ;CRC校验值结果存放在R58:59
  611.         LDBR R40,0,16
  612.         LDWR R42,60        ;目标寄存器起始地址
  613.         MOV R23,R47,1        ;数据长度
  614.         ADD R40,R44,R48
  615.         LDBR R2,58,1
  616.         MOV R55,R3,1        ;CRC校验在数据帧中的位置=起始地址+数据长度
  617.         LDBR R9,2,1
  618.         MOVA
  619.         INC R47,0,2        ;数据长度+2字节校验值=数据帧长度
  620.         COMTXD 4,R60,R47
  621.         RET         
  622.       
  623. Modbus_Slave:
  624.         LDWR R0,Modbus_EN                ;Modbus启用标记
  625.         MOVXR R60,1,1
  626.         LDWR R62,5AA5H
  627.         TESTS R60,R62,2
  628.         IJNE R0,0,Modbus_Slave_RET
  629.         LDWR R0,Modbus_Mode                ;Modbus主从机模式
  630.         MOVXR R60,1,1
  631.         IJNE R61,0,1
  632.         GOTO Modbus_Slave_RET
  633.         ;Modbus从机
  634.         CALL ModbusSlave_ID_Check        ;设备ID检测
  635.         RDXLEN 4,R18                ;读串口4接收缓冲区字节长度
  636.         IJNE R18,0,Modbus_Slave_Rx
  637.         ;0x00表示没有数据
  638.         GOTO Modbus_Slave_RET
  639. Modbus_Slave_Rx:
  640.         MOVDR 17,R19,1           ;DR17表示串口4接收帧超时定时器状态
  641.         IJNE R19,0,Modbus_Slave_RET
  642.         ;DR17=0x00表示一帧数据接收完成
  643.         RDXDAT 4,R20,R18        ;读取串口缓冲区数据到R20-199的寄存器空间
  644.         MOV R18,R237,1
  645.         DEC R237,0,2
  646.         CRCA R20,R16,R237        ;计算CRC16校验值,结果存放在R16:R17
  647.         MOV R16,R254,2
  648.         LDBR R238,0,8                ;R238-253,16个寄存器
  649.         LDWR R240,20                ;数据帧起始位置
  650.         MOV R237,R245,1                ;帧长度-校验位
  651.         ADD R238,R242,R246
  652.         MOV R253,R2,1                ;数据帧中CRC校验值存放位置
  653.         LDBR R3,238,1
  654.         LDBR R9,2,1
  655.         MOVA
  656.         CJNE R254,R238,Modbus_SlaveRx_ERR
  657.         CJNE R255,R239,Modbus_SlaveRx_ERR
  658.         ;校验正确
  659.         LDWR R0,Modbus_SlaveID
  660.         MOVXR R250,1,1
  661.         CJNE R20,R251,Modbus_SlaveRx_ERR
  662.         ;站号匹配
  663.         IJNE R21,03H,Modbus_SlaveRx_CMD06
  664.         ;0x03指令,读取VP变量空间
  665.             LDWR R250,90        ;单次最多读写90个字
  666.             JU R250,R24,Modbus_SlaveRx_ERR                ;R24:25存放的是寄存器总数,即字数
  667.             LDBR R240,0,16
  668.                 MOV R22,R242,2        ;VP变量起始地址
  669.                 MOV R24,R246,2        ;变量字数
  670.                 ADD R240,R244,R248
  671.                 LDWR R250,DFFFH        ;变量可读写范围:0x0000~0xDFFF
  672.                 JU R250,R254,Modbus_SlaveRx_ERR
  673.             MOV R22,R0,2        ;起始地址
  674.                 MOV R25,R9,1        ;读取字数
  675.                 MOVXR R23,1,0
  676.                 LDWR R244,2
  677.                 LDBR R240,0,4
  678.                 SMAC R244,R246,R240
  679.                 MOV R243,R22,1        ;待返回的寄存器字节数
  680.                 MOV R22,R255,1
  681.                 INC R255,0,3
  682.                 CRCA R20,R250,R255        ;校验值存放在R250:251
  683.                 LDBR R230,0,16
  684.                 LDWR R232,20
  685.                 MOV R255,R237,1
  686.                 ADD R230,R234,R238        ;CRC校验应存放的位置=数据帧首地址+帧数据长度
  687.                 LDBR R2,250,1
  688.                 MOV R245,R3,1
  689.                 LDBR R9,2,1
  690.                 MOVA
  691.                 INC R255,0,2        ;待发送数据帧总长度
  692.                 COMTXD 4,R20,R255
  693.                 GOTO Modbus_Slave_RET  
  694. Modbus_SlaveRx_CMD06:
  695.         IJNE R21,06H,Modbus_SlaveRx_CMD10
  696.         ;0x06指令,写单个VP变量
  697.             LDWR R240,DFFFH
  698.                 JU R240,R22,Modbus_SlaveRx_ERR
  699.                 MOV R22,R0,2        ;目标变量
  700.                 MOVXR R24,0,1
  701.                 COMTXD 4,R20,R18        ;原指令返回
  702.                 GOTO Modbus_Slave_RET
  703. Modbus_SlaveRx_CMD10:
  704.         IJNE R21,10H,Modbus_SlaveRx_ERR
  705.         ;0x10指令,写VP变量空间
  706.             LDWR R250,90        ;单次最多读写90个字
  707.             JU R250,R24,Modbus_SlaveRx_ERR                ;R24:25存放的是寄存器总数,即字数
  708.             LDBR R240,0,16
  709.                 MOV R22,R242,2        ;VP变量起始地址
  710.                 MOV R24,R246,2        ;变量字数
  711.                 ADD R240,R244,R248
  712.                 LDWR R250,DFFFH        ;变量可读写范围:0x0000~0xDFFF
  713.                 JU R250,R254,Modbus_SlaveRx_ERR
  714.                 MOV R22,R0,2        ;目标变量起始地址
  715.                 MOV R25,R9,1        ;写入变量字数
  716.                 MOVXR R27,0,0
  717.                 LDBR R255,6,1
  718.                 CRCA R20,R250,R255
  719.                 MOV R250,R26,2
  720.                 LDBR R18,8,1
  721.                 COMTXD 4,R20,R18
  722.                 GOTO Modbus_Slave_RET
  723. Modbus_SlaveRx_ERR:
  724.         LDBR R250,0x80,1
  725.         OR R21,R250,1                ;将功能码最高位置1,并返回给主机,表示错误信息
  726.         MOV R18,R255,1
  727.         DEC R255,0,2
  728.         CRCA R20,R250,R255
  729.         LDBR R230,0,16
  730.         LDWR R232,20
  731.         MOV R255,R237,1
  732.         ADD R230,R234,R238        ;计算校验值存放位置
  733.         LDBR R2,250,1
  734.         MOV R245,R3,1
  735.         LDBR R9,2,1
  736.         MOVA
  737.         COMTXD 4,R20,R18
  738. Modbus_Slave_RET:
  739.         RET           

  740. ModbusSlave_ID_Check:
  741.         ;若设备ID被错误地设置为0,则恢复默认值
  742.         LDWR R0,Modbus_SlaveID
  743.         MOVXR R60,1,1
  744.         LDWR R62,0
  745.         CJNE R60,R62,MSID_Check_RET
  746.         CJNE R61,R63,MSID_Check_RET
  747.         LDWR R60,5AH
  748.         MOVXR R60,0,1
  749. MSID_Check_RET:        
  750.         RET
  751.          
  752. Version_TAB:
  753.         DW 0405H        

  754. MODBUS_CMD1_TAB:
  755.         DB 5AH                ;0x5A=本条指令有效,其他表示无效
  756.         DB 04H                ;读写的MODBUS设备地址
  757.         DB 03H                ;读写的MODBUS指令
  758.         DB 20                ;读写数据长度,0x00表示本条指令无效
  759.         DW 50                ;指令等待时间,单位mS
  760.         DB 0                ;未定义
  761.         DB 0                ;指令操作模式,0x01=指定页面下执行,0x02=指定变量低字节内容为0x5A才执行(执行完自动清零),其他表示总是执行
  762.         DW 0                ;Page_ID或VP地址
  763.         DW 1400H        ;数据变量存储地址(VP)
  764.         DW 00H                ;MODBUS设备寄存器地址
  765.         DW 0                ;总线通信状态反馈
  766. MODBUS_CMD2_TAB:
  767.         DB 5AH, 01H, 03H, 20, 0, 50, 0, 0, 0, 0, 15H, 00H, 0, 00H, 0, 0
  768.         
  769. MODBUS_CMD3_TAB:
  770.         DB 5AH, 03H, 03H, 20, 0, 50, 0, 0, 0, 0, 16H, 00H, 0, 00H, 0, 0        
  771.       
  772.       
  773.       
  774. ;*****滚动显示
  775. TEMTAB1:   ;温度测量错误
  776.         DB  CEH,C2H,B6H,C8H,B2H,E2H,C1H,BFH,B4H,EDH,CEH,F3H,20H,20H,20H,20H,20H,20H,20H,20H,
  777. TEMTAB2:   ;温度过低或传感器短路
  778.         DB   CEH,C2H,B6H,C8H,B9H,FDH,B5H,CDH,BBH,F2H,B4H,ABH,B8H,D0H,C6H,F7H,B6H,CCH,C2H,B7H        
  779. TEMTAB3:   ;温度过低或传感器短路
  780.         DB   CEH,C2H,B6H,C8H,B9H,FDH,B8H,DFH,BBH,F2H,B4H,ABH,B8H,D0H,C6H,F7H,B6H,CCH,C2H,B7H      
  781. TEMTAB4:   ;超温
  782.         DB   B3H,ACH,CEH,C2H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H      
  783. TEMTAB5:   ;正在自整定
  784.         DB   D5H,FDH,D4H,DAH,D7H,D4H,D5H,FBH,B6H,A8H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H     
  785. TEMTAB6:   ;缺水
  786.         DB   C8H,B1H,CBH,AEH,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H      
  787. TEMTAB7:   ;缺水
  788.         DB   D4H,CBH,D0H,D0H,BDH,E1H,CAH,F8H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H      
  789. TEMTAB8:   ;空
  790.         DB   20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H,20H               
  791.         
复制代码


评论

高级模式
您需要登录后才可以回帖 登录 | 注册
发经验
课程
    关闭

    站长推荐 上一条 /8 下一条

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