📄 modbusm16.lst
字号:
_main:
i --> R20
02B8 940E0190 CALL _varInit
(0085) init_devices();
02BA 940E021B CALL _init_devices
(0086)
(0087) //重新采样
(0088) CLI();
02BC 94F8 BCLR 7
(0089) SEI();
02BD 9478 BSET 7
(0090)
(0091) for(i=0;i<400;i++)
02BE 2744 CLR R20
02BF 2755 CLR R21
02C0 5F4F SUBI R20,0xFF
02C1 4F5F SBCI R21,0xFF
02C2 3940 CPI R20,0x90
02C3 E0E1 LDI R30,1
02C4 075E CPC R21,R30
02C5 F3D4 BLT 0x02C0
02C6 C004 RJMP 0x02CB
(0092) {
(0093)
(0094) }
(0095)
(0096) while(1)
(0097) {
(0098) WDR(); //this prevents a timout on enabling
02C7 95A8 WDR
(0099)
(0100) timeProc();
02C8 DF97 RCALL _timeProc
(0101) checkComm0Modbus();
02C9 940E048A CALL _checkComm0Modbus
02CB CFFB RJMP 0x02C7
(0102)
(0103) }
(0104) }
02CC 9508 RET
_crc16:
uchCRCLo --> R20
uchCRCHi --> R22
uIndex --> Y+0
usDataLen --> R18
puchMsg --> R16
02CD 940E064A CALL push_gset2
02CF 9724 SBIW R28,4
FILE: E:\我的网页\mcuc\download\M16-23板程序模板\新建文件夹\modbus16.c
(0001) #include "main.h"
(0002)
(0003) //字地址 0 - 255
(0004) //位地址 0 - 255
(0005)
(0006) /* CRC 高位字节值表 */
(0007) const uint8 auchCRCHi[] = {
(0008) 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
(0009) 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
(0010) 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
(0011) 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
(0012) 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
(0013) 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
(0014) 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
(0015) 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
(0016) 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
(0017) 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
(0018) 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
(0019) 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
(0020) 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
(0021) 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
(0022) 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
(0023) 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
(0024) 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
(0025) 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
(0026) 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
(0027) 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
(0028) 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
(0029) 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
(0030) 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
(0031) 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
(0032) 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
(0033) 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
(0034) } ;
(0035) /* CRC低位字节值表*/
(0036) const uint8 auchCRCLo[] = {
(0037) 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
(0038) 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
(0039) 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
(0040) 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
(0041) 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
(0042) 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
(0043) 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
(0044) 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
(0045) 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
(0046) 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
(0047) 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
(0048) 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
(0049) 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
(0050) 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
(0051) 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
(0052) 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
(0053) 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
(0054) 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
(0055) 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
(0056) 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
(0057) 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
(0058) 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
(0059) 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
(0060) 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
(0061) 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
(0062) 0x43, 0x83, 0x41, 0x81, 0x80, 0x40
(0063) } ;
(0064)
(0065) uint8 testCoil; //用于测试 位地址1
(0066) uint16 testRegister; //用于测试 字地址0
(0067)
(0068) uint8 localAddr = 1; //地址
(0069) uint8 sendCount; //发送字节个数
(0070) uint8 receCount; //接收字节个数
(0071) uint8 sendPosi; //发送位置
(0072) uint8 sendBuf[32],receBuf[32]; //发送,接收缓冲区
(0073) uint8 checkoutError; //校验结果
(0074) uint8 receTimeOut; //接收超时
(0075)
(0076) uint16 crc16(uint8 *puchMsg, uint16 usDataLen)
(0077) {
(0078) uint8 uchCRCHi = 0xFF ; /* 高CRC字节初始化 */
02D0 EF6F LDI R22,0xFF
(0079) uint8 uchCRCLo = 0xFF ; /* 低CRC 字节初始化 */
02D1 EF4F LDI R20,0xFF
02D2 C02F RJMP 0x0302
(0080) uint32 uIndex ; /* CRC循环中的索引 */
(0081) while (usDataLen--) /* 传输消息缓冲区 */
(0082) {
(0083) uIndex = uchCRCHi ^ *puchMsg++ ; /* 计算CRC */
02D3 01F8 MOVW R30,R16
02D4 9021 LD R2,Z+
02D5 018F MOVW R16,R30
02D6 2433 CLR R3
02D7 2E46 MOV R4,R22
02D8 2455 CLR R5
02D9 2442 EOR R4,R2
02DA 2453 EOR R5,R3
02DB 0112 MOVW R2,R4
02DC 2444 CLR R4
02DD FC37 SBRC R3,7
02DE 9440 COM R4
02DF 2455 CLR R5
02E0 FC47 SBRC R4,7
02E1 9450 COM R5
02E2 01FE MOVW R30,R28
02E3 8220 STD R2,0+Z
02E4 8231 STD R3,1+Z
02E5 8242 STD R4,2+Z
02E6 8253 STD R5,3+Z
(0084) uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;
02E7 ED8C LDI R24,0xDC
02E8 E090 LDI R25,0
02E9 93AF PUSH R26
02EA 93BF PUSH R27
02EB 81A0 LDD R26,0+Z
02EC 81B1 LDD R27,1+Z
02ED 01FD MOVW R30,R26
02EE 91BF POP R27
02EF 91AF POP R26
02F0 0FE8 ADD R30,R24
02F1 1FF9 ADC R31,R25
02F2 91E4 LPM R30,0(Z)
02F3 2F64 MOV R22,R20
02F4 276E EOR R22,R30
(0085) uchCRCLo = auchCRCLo[uIndex] ;
02F5 ED8C LDI R24,0xDC
02F6 E091 LDI R25,1
02F7 01FE MOVW R30,R28
02F8 93AF PUSH R26
02F9 93BF PUSH R27
02FA 81A0 LDD R26,0+Z
02FB 81B1 LDD R27,1+Z
02FC 01FD MOVW R30,R26
02FD 91BF POP R27
02FE 91AF POP R26
02FF 0FE8 ADD R30,R24
0300 1FF9 ADC R31,R25
0301 9144 LPM R20,0(Z)
0302 0119 MOVW R2,R18
0303 5021 SUBI R18,1
0304 4030 SBCI R19,0
0305 2022 TST R2
0306 F009 BEQ 0x0308
0307 CFCB RJMP 0x02D3
0308 2033 TST R3
0309 F009 BEQ 0x030B
030A CFC8 RJMP 0x02D3
(0086) }
(0087) return (uchCRCHi << 8 | uchCRCLo) ;
030B 2F04 MOV R16,R20
030C 2F16 MOV R17,R22
030D 9624 ADIW R28,4
030E 940E0627 CALL pop_gset2
0310 9508 RET
(0088) }//uint16 crc16(uint8 *puchMsg, uint16 usDataLen)
(0089)
(0090) //开始发送
(0091) void beginSend(void)
(0092) {
(0093) sendEnable(); //设为发送
_beginSend:
0311 9AC7 SBI P18,7
(0094)
(0095) sendPosi = 0;
0312 2422 CLR R2
0313 922000B1 STS _sendPosi,R2
(0096) if(sendCount > 1)
0315 E081 LDI R24,1
0316 902000B3 LDS R2,_sendCount
0318 1582 CP R24,R2
0319 F420 BCC 0x031E
(0097) sendCount--;
031A 2D82 MOV R24,R2
031B 5081 SUBI R24,1
031C 938000B3 STS _sendCount,R24
(0098) UDR = sendBuf[0];
031E 90200091 LDS R2,_sendBuf
0320 B82C OUT P0C,R2
(0099) }//void beginSend(void)
0321 9508 RET
_readCoil:
result --> Y+1
crcData --> R22
byteCount --> R20
k --> R22
exit --> Y+4
addr --> Y+3
bitCount --> R10
position --> R12
tempData --> Y+0
tempAddr --> Y+2
i --> R14
0322 940E0656 CALL push_gset5
0324 9725 SBIW R28,5
(0100)
(0101)
(0102) //读线圈状态
(0103) void readCoil(void)
(0104) {
(0105) uint8 addr;
(0106) uint8 tempAddr;
(0107) uint8 byteCount;
(0108) uint8 bitCount;
(0109) uint16 crcData;
(0110) uint8 position;
(0111) uint8 i,k;
(0112) uint8 result;
(0113) uint16 tempData;
(0114) uint8 exit = 0;
0325 2400 CLR R0
0326 820C STD R0,4+Y
(0115)
(0116) //addr = (receBuf[2]<<8) + receBuf[3];
(0117) //tempAddr = addr & 0xfff;
(0118) addr = receBuf[3];
0327 90200074 LDS R2,_receBuf+3
0329 822B STD R2,3+Y
(0119) tempAddr = addr;
032A 2C02 MOV R0,R2
032B 820A STD R0,2+Y
(0120)
(0121) //bitCount = (receBuf[4]<<8) + receBuf[5]; //读取的位个数
(0122) bitCount = receBuf[5];
032C 90A00076 LDS R10,0x76
(0123)
(0124) byteCount = bitCount / 8; //字节个数
032E E018 LDI R17,0x8
032F 2D0A MOV R16,R10
0330 940E0605 CALL div8u
0332 2F40 MOV R20,R16
(0125) if(bitCount%8 != 0)
0333 E018 LDI R17,0x8
0334 2D0A MOV R16,R10
0335 940E0603 CALL mod8u
0337 2300 TST R16
0338 F009 BEQ 0x033A
(0126) byteCount++;
0339 9543 INC R20
(0127)
(0128) for(k=0;k<byteCount;k++)
033A 2766 CLR R22
033B C037 RJMP 0x0373
(0129) {//字节位置
(0130) position = k + 3;
033C 2F86 MOV R24,R22
033D 5F8D SUBI R24,0xFD
033E 2EC8 MOV R12,R24
(0131) sendBuf[position] = 0;
033F E981 LDI R24,0x91
0340 E090 LDI R25,0
0341 2DEC MOV R30,R12
0342 27FF CLR R31
0343 0FE8 ADD R30,R24
0344 1FF9 ADC R31,R25
0345 2422 CLR R2
0346 8220 STD R2,0+Z
(0132) for(i=0;i<8;i++)
0347 24EE CLR R14
0348 C022 RJMP 0x036B
(0133) {
(0134) getCoilVal(tempAddr,&tempData);
0349 019E MOVW R18,R28
034A 810A LDD R16,2+Y
034B 2711 CLR R17
034C D21F RCALL _getCoilVal
(0135)
(0136) sendBuf[position] |= tempData << i;
034D E981 LDI R24,0x91
034E E090 LDI R25,0
034F 2C2C MOV R2,R12
0350 2433 CLR R3
0351 0E28 ADD R2,R24
0352 1E39 ADC R3,R25
0353 2D2E MOV R18,R14
0354 2733 CLR R19
0355 8108 LDD R16,0+Y
0356 8119 LDD R17,1+Y
0357 940E065A CALL lsl16
0359 01F1 MOVW R30,R2
035A 8040 LDD R4,0+Z
035B 2455 CLR R5
035C 2A40 OR R4,R16
035D 2A51 OR R5,R17
035E 8240 STD R4,0+Z
(0137) tempAddr++;
035F 800A LDD R0,2+Y
0360 9403 INC R0
0361 820A STD R0,2+Y
(0138) if(tempAddr >= addr+bitCount)
0362 802B LDD R2,3+Y
0363 0C2A ADD R2,R10
0364 1402 CP R0,R2
0365 F020 BCS 0x036A
(0139) { //读完
(0140) exit = 1;
0366 2400 CLR R0
0367 9403 INC R0
0368 820C STD R0,4+Y
(0141) break;
0369 C004 RJMP 0x036E
036A 94E3 INC R14
036B 2D8E MOV R24,R14
036C 3088 CPI R24,0x8
036D F2D8 BCS 0x0349
(0142) }
(0143) }
(0144) if(exit == 1)
036E 818C LDD R24,4+Y
036F 3081 CPI R24,1
0370 F409 BNE 0x0372
(0145) break;
0371 C004 RJMP 0x0376
0372 9563 INC R22
0373 1764 CP R22,R20
0374 F408 BCC 0x0376
0375 CFC6 RJMP 0x033C
(0146) }
(0147)
(0148) sendBuf[0] = localAddr;
0376 90200060 LDS R2,0x60
0378 92200091 STS _sendBuf,R2
(0149) sendBuf[1] = 0x01;
037A E081 LDI R24,1
037B 93800092 STS _sendBuf+1,R24
(0150) sendBuf[2] = byteCount;
037D 93400093 STS _sendBuf+2,R20
(0151) byteCount += 3;
037F 5F4D SUBI R20,0xFD
(0152) crcData = crc16(sendBuf,byteCount);
0380 2F24 MOV R18,R20
0381 2733 CLR R19
0382 E901 LDI R16,0x91
0383 E010 LDI R17,0
0384 DF48 RCALL _crc16
0385 01B8 MOVW R22,R16
(0153) sendBuf[byteCount] = crcData >> 8;
0386 E981 LDI R24,0x91
0387 E090 LDI R25,0
0388 2FE4 MOV R30,R20
0389 27FF CLR R31
038A 0FE8 ADD R30,R24
038B 1FF9 ADC R31,R25
038C 011B MOVW R2,R22
038D 2C23 MOV R2,R3
038E 2433 CLR R3
038F 8220 STD R2,0+Z
(0154) byteCount++;
0390 9543 INC R20
(0155) sendBuf[byteCount] = crcData & 0xff;
0391 2FE4 MOV R30,R20
0392 27FF CLR R31
0393 0FE8 ADD R30,R24
0394 1FF9 ADC R31,R25
0395 01CB MOVW R24,R22
0396 7090 ANDI R25,0
0397 8380 STD R24,0+Z
(0156) sendCount = byteCount + 1;
0398 2F84 MOV R24,R20
0399 5F8F SUBI R24,0xFF
039A 938000B3 STS _sendCount,R24
(0157)
(0158) beginSend();
039C DF74 RCALL _beginSend
(0159) }//void readCoil(void)
039D 9625 ADIW R28,5
039E 940E0630 CALL pop_gset5
03A0 9508 RET
_readRegisters:
finsh --> Y+1
result --> Y+1
readCount --> R20
addr --> R20
crcData --> R20
byteCount --> R10
tempAddr --> R12
tempData --> Y+0
i --> R22
03A1 940E0652 CALL push_gset4
03A3 9722 SBIW R28,2
(0160)
(0161) //读寄存器
(0162) void readRegisters(void)
(0163) {
(0164) uint8 addr;
(0165) uint8 tempAddr;
(0166) uint16 result;
(0167) uint16 crcData;
(0168) uint8 readCount;
(0169) uint8 byteCount;
(0170) uint8 finsh; //1完成 0出错
(0171) uint16 i;
(0172) uint16 tempData = 0;
03A4 2422 CLR R2
03A5 2433 CLR R3
03A6 8228 STD R2,0+Y
03A7 8239 STD R3,1+Y
(0173)
(0174) //addr = (receBuf[2]<<8) + receBuf[3];
(0175) //tempAddr = addr & 0xfff;
(0176) addr = receBuf[3];
03A8 91400074 LDS R20,_receBuf+3
(0177) tempAddr = addr;
03AA 2EC4 MOV R12,R20
(0178)
(0179) //readCount = (receBuf[4]<<8) + receBuf[5]; //要读的个数
(0180) readCount = receBuf[5];
03AB 91400076 LDS R20,0x76
(0181)
(0182) byteCount = readCount * 2;
03AD E082 LDI R24,2
03AE 9F84 MUL R24,R20
03AF 2CA0 MOV R10,R0
(0183)
(0184) for(i=0;i<byteCount;i+=2,tempAddr++)
03B0 2766 CLR R22
03B1 2777 CLR R23
03B2 C01A RJMP 0x03CD
(0185) {
(0186) getRegisterVal(tempAddr,&tempData);
03B3 019E MOVW R18,R28
03B4 2D0C MOV R16,R12
03B5 2711 CLR R17
03B6 D1FF RCALL _getRegisterVal
(0187) sendBuf[i+3] = tempData >> 8;
03B7 E981 LDI R24,0x91
03B8 E090 LDI R25,0
03B9 01FB MOVW R30,R22
03BA 9633 ADIW R30,3
03BB 0FE8 ADD R30,R24
03BC 1FF9 ADC R31,R25
03BD 8028 LDD R2,0+Y
03BE 8039 LDD R3,1+Y
03BF 2C23 MOV R2,R3
03C0 2433 CLR R3
03C1 8220 STD R2,0+Z
(0188) sendBuf[i+4] = tempData & 0xff;
03C2 01FB MOVW R30,R22
03C3 9634 ADIW R30,4
03C4 0FE8 ADD R30,R24
03C5 1FF9 ADC R31,R25
03C6 8188 LDD R24,0+Y
03C7 8199 LDD R25,1+Y
03C8 7090 ANDI R25,0
03C9 8380 STD R24,0+Z
03CA 5F6E SUBI R22,0xFE
03CB 4F7F SBCI R23,0xFF
03CC 94C3 INC R12
03CD 2C2A MOV R2,R10
03CE 2433 CLR R3
03CF 1562 CP R22,R2
03D0 0573 CPC R23,R3
03D1 F308 BCS 0x03B3
(0189) }
(0190)
(0191) sendBuf[0] = localAddr;
03D2 90200060 LDS R2,0x60
03D4 92200091 STS _sendBuf,R2
(0192) sendBuf[1] = 3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -