⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modbus16.s

📁 一个16位单片机modbus通信例程
💻 S
📖 第 1 页 / 共 3 页
字号:
	.dbsym r k 22 c
	.dbsym l exit 4 c
	.dbsym l addr 3 c
	.dbsym r bitCount 10 c
	.dbsym r position 12 c
	.dbsym l tempData 0 i
	.dbsym l tempAddr 2 c
	.dbsym r i 14 c
	.dbend
	.dbfunc e readRegisters _readRegisters fV
;          finsh -> <dead>
;         result -> <dead>
;      readCount -> R20
;           addr -> R20
;        crcData -> R20,R21
;      byteCount -> R10
;       tempAddr -> R12
;       tempData -> y+0
;              i -> R22,R23
	.even
_readRegisters::
	xcall push_gset4
	sbiw R28,2
	.dbline -1
	.dbline 163
; 
; //读寄存器
; void readRegisters(void)
; {
	.dbline 172
; 	uint8 addr;
; 	uint8 tempAddr;
; 	uint16 result;
; 	uint16 crcData;
; 	uint8 readCount;
; 	uint8 byteCount;
; 	uint8  finsh;	//1完成  0出错
; 	uint16 i;
; 	uint16 tempData = 0;	
	clr R2
	clr R3
	std y+0,R2
	std y+1,R3
	.dbline 176
; 	
; 	//addr = (receBuf[2]<<8) + receBuf[3];
; 	//tempAddr = addr & 0xfff;	
; 	addr = receBuf[3];
	lds R20,_receBuf+3
	.dbline 177
; 	tempAddr = addr;
	mov R12,R20
	.dbline 180
; 
; 	//readCount = (receBuf[4]<<8) + receBuf[5];	//要读的个数
; 	readCount = receBuf[5];
	lds R20,_receBuf+5
	.dbline 182
; 
; 	byteCount = readCount * 2;
	ldi R24,2
	mul R24,R20
	mov R10,R0
	.dbline 184
; 	
; 	for(i=0;i<byteCount;i+=2,tempAddr++)
	clr R22
	clr R23
	xjmp L33
L30:
	.dbline 185
	.dbline 186
	movw R18,R28
	mov R16,R12
	clr R17
	xcall _getRegisterVal
	.dbline 187
	ldi R24,<_sendBuf
	ldi R25,>_sendBuf
	movw R30,R22
	adiw R30,3
	add R30,R24
	adc R31,R25
	ldd R2,y+0
	ldd R3,y+1
	mov R2,R3
	clr R3
	std z+0,R2
	.dbline 188
	movw R30,R22
	adiw R30,4
	add R30,R24
	adc R31,R25
	ldd R24,y+0
	ldd R25,y+1
	andi R25,0
	std z+0,R24
	.dbline 189
L31:
	.dbline 184
	subi R22,254  ; offset = 2
	sbci R23,255
	inc R12
L33:
	.dbline 184
	mov R2,R10
	clr R3
	cp R22,R2
	cpc R23,R3
	brlo L30
	.dbline 191
; 	{
; 		getRegisterVal(tempAddr,&tempData);				
; 		sendBuf[i+3] = tempData >> 8;				   		
; 		sendBuf[i+4] = tempData & 0xff;			
; 	}
; 	
; 	sendBuf[0] = localAddr;
	lds R2,_localAddr
	sts _sendBuf,R2
	.dbline 192
; 	sendBuf[1] = 3;
	ldi R24,3
	sts _sendBuf+1,R24
	.dbline 193
; 	sendBuf[2] = byteCount;
	sts _sendBuf+2,R10
	.dbline 194
; 	byteCount += 3;
	mov R24,R10
	subi R24,253    ; addi 3
	mov R10,R24
	.dbline 195
; 	crcData = crc16(sendBuf,byteCount);
	mov R18,R24
	clr R19
	ldi R16,<_sendBuf
	ldi R17,>_sendBuf
	xcall _crc16
	movw R20,R16
	.dbline 196
; 	sendBuf[byteCount] = crcData >> 8;
	ldi R24,<_sendBuf
	ldi R25,>_sendBuf
	mov R30,R10
	clr R31
	add R30,R24
	adc R31,R25
	movw R2,R20
	mov R2,R3
	clr R3
	std z+0,R2
	.dbline 197
; 	byteCount++;
	inc R10
	.dbline 198
; 	sendBuf[byteCount] = crcData & 0xff;
	mov R30,R10
	clr R31
	add R30,R24
	adc R31,R25
	movw R24,R20
	andi R25,0
	std z+0,R24
	.dbline 200
; 	
; 	sendCount = byteCount + 1;
	mov R24,R10
	subi R24,255    ; addi 1
	sts _sendCount,R24
	.dbline 201
; 	beginSend();
	xcall _beginSend
	.dbline -2
	.dbline 202
; }//void readRegisters(void)
L27:
	adiw R28,2
	xcall pop_gset4
	.dbline 0 ; func end
	ret
	.dbsym l finsh 1 c
	.dbsym l result 1 i
	.dbsym r readCount 20 c
	.dbsym r addr 20 c
	.dbsym r crcData 20 i
	.dbsym r byteCount 10 c
	.dbsym r tempAddr 12 c
	.dbsym l tempData 0 i
	.dbsym r i 22 i
	.dbend
	.dbfunc e forceSingleCoil _forceSingleCoil fV
;       tempData -> R22,R23
;       tempAddr -> R20
;           addr -> R22
;          onOff -> R10
;              i -> R20
	.even
_forceSingleCoil::
	xcall push_gset3
	.dbline -1
	.dbline 207
; 
; 
; //强制单个线圈
; void forceSingleCoil(void)
; {
	.dbline 216
; 	uint8 addr;
; 	uint8 tempAddr;
; 	uint16 tempData;
; 	uint8  onOff;
; 	uint8 i;
; 	
; 	//addr = (receBuf[2]<<8) + receBuf[3];	
; 	//tempAddr = addr & 0xfff;
; 	addr = receBuf[3];
	lds R22,_receBuf+3
	.dbline 217
; 	tempAddr = addr;
	mov R20,R22
	.dbline 220
; 
; 	//onOff = (receBuf[4]<<8) + receBuf[5];	
; 	onOff = receBuf[4];
	lds R10,_receBuf+4
	.dbline 223
; 	
; 	//if(onOff == 0xff00)
; 	if(onOff == 0xff)
	mov R24,R10
	cpi R24,255
	brne L39
	.dbline 224
; 	{	//设为ON
	.dbline 225
; 		tempData = 1;
	ldi R22,1
	ldi R23,0
	.dbline 226
; 	} 
	xjmp L40
L39:
	.dbline 228
; 	//else if(onOff == 0x0000)
; 	else if(onOff == 0x00)
	tst R10
	brne L41
	.dbline 229
; 	{	//设为OFF
	.dbline 230
; 		tempData = 0;
	clr R22
	clr R23
	.dbline 231
; 	}
L41:
L40:
	.dbline 233
; 
; 	setCoilVal(tempAddr,tempData);	
	movw R18,R22
	mov R16,R20
	clr R17
	xcall _setCoilVal
	.dbline 235
; 	
; 	for(i=0;i<receCount;i++)
	clr R20
	xjmp L46
L43:
	.dbline 236
	.dbline 237
	ldi R24,<_receBuf
	ldi R25,>_receBuf
	mov R30,R20
	clr R31
	add R30,R24
	adc R31,R25
	ldd R2,z+0
	ldi R24,<_sendBuf
	ldi R25,>_sendBuf
	mov R30,R20
	clr R31
	add R30,R24
	adc R31,R25
	std z+0,R2
	.dbline 238
L44:
	.dbline 235
	inc R20
L46:
	.dbline 235
	lds R2,_receCount
	cp R20,R2
	brlo L43
	.dbline 239
; 	{
; 		sendBuf[i] = receBuf[i];
; 	}
; 	sendCount = receCount;
	sts _sendCount,R2
	.dbline 240
; 	beginSend();	
	xcall _beginSend
	.dbline -2
	.dbline 241
; }//void forceSingleCoil(void)
L36:
	xcall pop_gset3
	.dbline 0 ; func end
	ret
	.dbsym r tempData 22 i
	.dbsym r tempAddr 20 c
	.dbsym r addr 22 c
	.dbsym r onOff 10 c
	.dbsym r i 20 c
	.dbend
	.dbfunc e presetMultipleRegisters _presetMultipleRegisters fV
;          finsh -> <dead>
;      byteCount -> R22
;        crcData -> R22,R23
;           addr -> y+0
;       setCount -> R20
;       tempData -> R14,R15
;       tempAddr -> R10
;              i -> R12
	.even
_presetMultipleRegisters::
	xcall push_gset5
	sbiw R28,1
	.dbline -1
	.dbline 246
; 
; 
; //设置多个寄存器
; void presetMultipleRegisters(void)
; {
	.dbline 258
; 	uint8 addr;
; 	uint8 tempAddr;
; 	uint8 byteCount;
; 	uint8 setCount;
; 	uint16 crcData;
; 	uint16 tempData;
; 	uint8  finsh;	//为1时完成 为0时出错
; 	uint8 i;
; 	
; 	//addr = (receBuf[2]<<8) + receBuf[3];
; 	//tempAddr = addr & 0xfff;
; 	addr = receBuf[3];
	lds R2,_receBuf+3
	std y+0,R2
	.dbline 259
; 	tempAddr = addr;
	mov R10,R2
	.dbline 262
; 
; 	//setCount = (receBuf[4]<<8) + receBuf[5];
; 	setCount = receBuf[5];
	lds R20,_receBuf+5
	.dbline 263
; 	byteCount = receBuf[6];	
	lds R22,_receBuf+6
	.dbline 265
; 	
; 	for(i=0;i<setCount;i++,tempAddr++)
	clr R12
	xjmp L54
L51:
	.dbline 266
	.dbline 267
	ldi R24,2
	mul R24,R12
	ldi R24,<_receBuf+8
	ldi R25,>_receBuf+8
	movw R30,R0
	add R30,R24
	adc R31,R25
	ldd R2,z+0
	ldi R24,<_receBuf+7
	ldi R25,>_receBuf+7
	movw R30,R0
	add R30,R24
	adc R31,R25
	ldd R3,z+0
	mov R14,R2
	mov R15,R3
	.dbline 269
	movw R18,R14
	mov R16,R10
	clr R17
	xcall _setRegisterVal
	.dbline 270
L52:
	.dbline 265
	inc R12
	inc R10
L54:
	.dbline 265
	cp R12,R20
	brlo L51
	.dbline 272
; 	{
; 		tempData = (receBuf[i*2+7]<<8) + receBuf[i*2+8];
; 	
; 		setRegisterVal(tempAddr,tempData);			
; 	}
; 	
; 	sendBuf[0] = localAddr;
	lds R2,_localAddr
	sts _sendBuf,R2
	.dbline 273
; 	sendBuf[1] = 16;
	ldi R24,16
	sts _sendBuf+1,R24
	.dbline 274
; 	sendBuf[2] = addr >> 8;
	ldd R2,y+0
	clr R3
	mov R2,R3
	clr R3
	sbrc R2,7
	com R3
	sts _sendBuf+2,R2
	.dbline 275
; 	sendBuf[3] = addr & 0xff;
	ldd R24,y+0
	andi R24,255
	sts _sendBuf+3,R24
	.dbline 276
; 	sendBuf[4] = setCount >> 8;
	mov R2,R20
	clr R3
	mov R2,R3
	clr R3
	sbrc R2,7
	com R3
	sts _sendBuf+4,R2
	.dbline 277
; 	sendBuf[5] = setCount & 0xff;
	mov R24,R20
	andi R24,255
	sts _sendBuf+5,R24
	.dbline 278
; 	crcData = crc16(sendBuf,6);
	ldi R18,6
	ldi R19,0
	ldi R16,<_sendBuf
	ldi R17,>_sendBuf
	xcall _crc16
	movw R22,R16
	.dbline 279
; 	sendBuf[6] = crcData >> 8;
	movw R2,R22
	mov R2,R3
	clr R3
	sts _sendBuf+6,R2
	.dbline 280
; 	sendBuf[7] = crcData & 0xff;
	movw R24,R22
	andi R25,0
	sts _sendBuf+7,R24
	.dbline 281
; 	sendCount = 8;
	ldi R24,8
	sts _sendCount,R24
	.dbline 282
; 	beginSend();	
	xcall _beginSend
	.dbline -2
	.dbline 283
; }//void presetMultipleRegisters(void)
L47:
	adiw R28,1
	xcall pop_gset5
	.dbline 0 ; func end
	ret
	.dbsym l finsh 1 c
	.dbsym r byteCount 22 c
	.dbsym r crcData 22 i
	.dbsym l addr 0 c
	.dbsym r setCount 20 c
	.dbsym r tempData 14 i
	.dbsym r tempAddr 10 c
	.dbsym r i 12 c
	.dbend
	.dbfunc e checkComm0Modbus _checkComm0Modbus fV
;        crcData -> R20,R21
;       tempData -> R22,R23
	.even
_checkComm0Modbus::
	xcall push_gset2
	.dbline -1
	.dbline 289
; 
; 
; 
; //检查uart0数据
; void checkComm0Modbus(void)
; {
	.dbline 293
; 	uint16 crcData;
; 	uint16 tempData;
; 	
; 	if(receCount > 4)
	ldi R24,4
	lds R2,_receCount
	cp R24,R2
	brlo X5
	xjmp L65
X5:
	.dbline 294
; 	{
	.dbline 295
; 		switch(receBuf[1])
	lds R20,_receBuf+1
	clr R21
	cpi R20,1
	ldi R30,0
	cpc R21,R30
	breq L71
	cpi R20,3
	ldi R30,0
	cpc R21,R30
	breq L71
	cpi R20,5
	ldi R30,0
	cpc R21,R30
	breq L71
	cpi R20,6
	ldi R30,0
	cpc R21,R30
	breq L71
	cpi R20,1
	ldi R30,0
	cpc R21,R30
	brge X6
	xjmp L68
X6:
L109:
	cpi R20,15
	ldi R30,0
	cpc R21,R30
	brne X7
	xjmp L92
X7:
	cpi R20,16
	ldi R30,0
	cpc R21,R30
	brne X8
	xjmp L100
X8:
	xjmp L68
X4:
	.dbline 296
; 		{
L71:
	.dbline 301
; 			case 1://读取线圈状态(读取点 16位以内)
; 			case 3://读取保持寄存器(一个或多个)
; 			case 5://强制单个线圈
; 			case 6://设置单个寄存器			
; 					if(receCount >= 8)
	lds R24,_receCount
	cpi R24,8
	brsh X9
	xjmp L68
X9:
	.dbline 302
; 					{//接收完成一组数据					
	.dbline 304
; 						//应该关闭接收中断
; 						UCSRB &= ~BIT(7);				
	cbi 0xa,7
	.dbline 305
; 						if(receBuf[0]==localAddr && checkoutError==0)
	lds R2,_localAddr
	lds R3,_receBuf
	cp R3,R2
	brne L74
	lds R2,_checkoutError
	tst R2
	brne L74
	.dbline 306
; 						{
	.dbline 307
; 							crcData = crc16(receBuf,6);
	ldi R18,6
	ldi R19,0
	ldi R16,<_receBuf
	ldi R17,>_receBuf
	xcall _crc16
	movw R20,R16
	.dbline 308
; 							if(crcData == receBuf[7]+(receBuf[6]<<8))
	lds R2,_receBuf+6
	clr R3
	mov R3,R2
	clr R2
	lds R4,_receBuf+7
	clr R5
	add R4,R2
	adc R5,R3
	cp R16,R4
	cpc R17,R5
	brne L76
	.dbline 309
; 							{//校验正确
	.dbline 310
; 								if(receBuf[1] == 1)
	lds R24,_receBuf+1
	cpi R24,1
	brne L80
	.dbline 311
; 								{//读取线圈状态(读取点 16位以内)
	.dbline 312
; 									readCoil();								
	xcall _readCoil
	.dbline 313
; 								}
	xjmp L81
L80:
	.dbline 314
; 								else if(receBuf[1] == 3)
	lds R24,_receBuf+1
	cpi R24,3
	brne L83
	.dbline 315
; 								{//读取保持寄存器(一个或多个)
	.dbline 316
; 									readRegisters();
	xcall _readRegisters
	.dbline 317
; 								}
	xjmp L84
L83:
	.dbline 318
; 								else if(receBuf[1] == 5)
	lds R24,_receBuf+1
	cpi R24,5
	brne L86
	.dbline 319
; 								{//强制单个线圈
	.dbline 320
; 									forceSingleCoil();								
	xcall _forceSingleCoil
	.dbline 321
; 								}
	xjmp L87
L86:
	.dbline 322
; 								else if(receBuf[1] == 6)
	lds R24,_receBuf+1
	cpi R24,6
	brne L89
	.dbline 323
; 								{
	.dbline 325
; 									//presetSingleRegister();								
; 								}
L89:
L87:
L84:
L81:
	.dbline 327
; 
; 							}
L76:
	.dbline 328
; 						}											
L74:
	.dbline 329
; 						receCount = 0;	
	clr R2
	sts _receCount,R2
	.dbline 330
; 						checkoutError = 0;	
	sts _checkoutError,R2
	.dbline 331
; 						UCSRB |= BIT(7);											
	sbi 0xa,7
	.dbline 332
; 					}
	.dbline 333
; 					break;
	xjmp L68
L92:
	.dbline 336
; 		
; 			case 15://设置多个线圈
; 					tempData = receBuf[6]; 
	lds R22,_receBuf+6
	clr R23
	.dbline 337
; 					tempData += 9;	//数据个数
	subi R22,247  ; offset = 9
	sbci R23,255
	.dbline 338
; 					if(receCount >= tempData)
	lds R2,_receCount
	clr R3
	cp R2,R22
	cpc R3,R23
	brsh X10
	xjmp L68
X10:
	.dbline 339
; 					{//应该关闭接收中断
	.dbline 340
; 						UCSRB &= ~BIT(7);			   
	cbi 0xa,7
	.dbline 341
; 						if(receBuf[0]==localAddr && checkoutError==0)
	lds R2,_localAddr
	lds R3,_receBuf
	cp R3,R2
	brne L96
	lds R2,_checkoutError
	tst R2
	brne L96
	.dbline 342
; 						{
	.dbline 343
; 							crcData = crc16(receBuf,tempData-2);
	movw R18,R22
	subi R18,2
	sbci R19,0
	ldi R16,<_receBuf
	ldi R17,>_receBuf
	xcall _crc16
	movw R20,R16
	.dbline 344
; 							if(crcData == (receBuf[tempData-2]<<8)+ receBuf[tempData-1])
	ldi R24,<_receBuf
	ldi R25,>_receBuf
	movw R30,R22
	sbiw R30,1
	add R30,R24
	adc R31,R25
	ldd R2,z+0
	movw R30,R22
	sbiw R30,2
	add R30,R24
	adc R31,R25
	ldd R3,z+0
	mov R4,R2
	mov R5,R3
	cp R16,R4

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -