PDA

View Full Version : without communication modbus



scrwld
- 8th August 2010, 08:22
hello all, I need help I have a modbus communication program that works very well, but sometimes I lose communication, I have noticed that if the frame or the values are very large, I lose communication (I have an LED that tells me when the interruption occurs receive information), this LED does not light and the only way to restore communication is resetting the pic, although the program has routines that verify if the information is correct, I could not correct this behavior.

scrwld
- 14th September 2010, 22:06
hello all, I need help I have a modbus communication program that works very well, but sometimes I lose communication, I have noticed that if the frame or the values are very large, I lose communication (I have an LED that tells me when the interruption occurs receive information), this LED does not light and the only way to restore communication is resetting the pic, although the program has routines that verify if the information is correct, I could not correct this behavior.

this is the main code ( I forget).

thank



include "alldigital.pbp"
INCLUDE "P16F877A.INC"
DEFINE OSC 20
'***************************************
'* FUSE*
'***************************************
@ DEVICE HS_OSC 'OSCILADOR HIGH SPEED
@ DEVICE WDT_ON ' Watchdog Timer desconectado
@ DEVICE PWRT_ON ' Power-On Timer conectado
@ DEVICE BOD_ON ' Brown-Out Detect conectado
@ DEVICE LVP_OFF ' Low Voltage Programming desconectado
'//******************* INICIO PUERTOS COMO SALIDAS ***************************//
PORTA = %00111111
PORTB = 0
portc = %10111110
PORTD = 0
PORTE = %00000011
TRISA = %00111111
TRISB = 0
TRISC = %10111111 ' Set TX (RC.6), RC.0 to out, rest in
TRISD = 0
TRISE = %00000011
'*************** counter,index *************************************
buffer var byte[32] 'Receiving Buffer Trama MOdbus
crc16 var byte[2] 'for checksum
B0 var byte
B1 var byte
W0 var word
MBFrame var byte
NewFrame var bit
Length var byte
TMR1Ticks var byte
i var byte
MINPUT var byte
SlaveAddress var byte
Baudios VAR BYTE
TMR1Ticks = 0
Length = 0
MINPUT = 0

'//********************* Inicializo USART *****************************

RCSTA.7 = 1 'abilito puerto serial configura RC6 y RC7 para RX/TX
RCSTA.6 = 0 ' seleccino modo 8 bit en recepcion
RCSTA.5 = 0 ' no usado
RCSTA.4 = 1 'abilito recpcion continua = 1
RCSTA.3 = 0 'desabilito deteccion direccion
RCSTA.2 = 0 'guarda error de trama 0 = sin error
RCSTA.1 = 0 'guarda error de overrun 0 = sin error
RCSTA.0 = 0 'guarda el noveno bit de los datos recibidos uso paridad
' Enable transmit and asynchronous mode
if baudios=64 then
TXSTA = %00100100
else
TXSTA = %00100000
endif
SPBRG = Baudios ' Baudrate = 9600 or 19200
INTCON = %11000000 ' Enable interrupts
PIE1.5 = 1 ' Enable interrupt on RECEPCION USART
PIE1.1 = 1 ' Enable interrupt on TMR2
T2CON.1 = 1 ' TMR1 prescaler 1:16
TMR2 = 0 ' TMR2 Holding register = 0
ON INTERRUPT GoTo readMB ' Declare interrupt handler routine
'********************* PROGRAMA PRINCIPAL ******************************
Main:
'****************************** Read input *************************

MINPUT.7 = not PORTE.1
MINPUT.6 = not PORTE.0
MINPUT.5 = not PORTA.5
MINPUT.4 = not PORTA.4
MINPUT.3 = not PORTA.3
MINPUT.0 = not PORTA.0
MINPUT.2 = not PORTA.2
MINPUT.1 = not PORTA.1

Goto Main

'!!!! Desabilito interrupcion no colocar ningun codigo del user !!!!

Disable

'********************* interrupt ***********************

readMB:

If RCSTA.1 OR RCSTA.2 then ' If USART error then clear the error flag
RCSTA.4=0 ' // clear the error
RCSTA.4=1 ' // enable receiving again
EndIf

if (PIR1.5 = 1) then ' USART Interrupt
TMR1Ticks = 0
If (NewFrame = 1) Or (Length = 0) Then 'New modbus frame start
NewFrame = 0
T2CON.2 = 1 ' Enable Timer2
Length = 1
EndIf
while (PIR1.5 = 1) 'Write modbus frame to buffer
buffer [Length] = RCREG
Length = Length + 1
If Length >= 20 Then 'Max modbus frame to buffer 20 char
Length = 0
EndIf
Wend
EndIf

if (PIR1.1 = 1) then ' Timer2 interrupt
PIR1.1 = 0
T2CON.2 = 0 ' Timer2 disable
TMR1Ticks = TMR1Ticks + 1

If TMR1Ticks > 120 Then ' ~ 10 ms without new char
'There was no new char on USART => end of modbus frame
NewFrame = 1
Else
T2CON.2 = 1 'Enable timer
EndIf
EndIf
Resume
ENABLE
End

mackrackit
- 15th September 2010, 06:05
Am I reading your code correctly? You have an interrupt inside an interrupt?

If so, I do not think that will work?

Jerson
- 15th September 2010, 07:05
It may be possible the problem is in your crc16 or some other related section. In the code you posted, I do not see any led(did I miss it?)

This code appears Ok to me.

HenrikOlsson
- 15th September 2010, 07:14
I have noticed that if the frame or the values are very large, I lose communication
Define very large. Your buffer length seems to be 20 bytes so if the frame is longer than that I imagine you'll be in trouble. It shouldn't stop interrupting though.....

I can't seem to find where you turn on the LED you mentioned.

/Henrik.

scrwld
- 16th September 2010, 20:01
Am I reading your code correctly? You have an interrupt inside an interrupt?

If so, I do not think that will work?

Hello everyone sorry did not reply earlier.

hello mackrackit , is enabled every time it happens the serial interrupt. is used to determine if there are no more characters to read and works. original code from modbus.pl

If (NewFrame = 1) OR (Length = 0) then 'New modbus frame start
NewFrame = 0
T2CON.2 = 1 ' Enable Timer2
Length = 1
EndIf

hello Jerson, the crc16 is working, the led is switched off in the Main, is switched on every time PIR1.5 = 1. when the fault occurs, the LED lights (I'm in the interruption) and then turn off.

hello HenrikOlsson, explain why "Define very large", look:

while (PIR1.5 = 1) 'Write modbus frame to buffer
buffer[Length] = RCREG
Length = Length + 1
if Length >=20 then ' here check buffer
Length = 0
EndIf
wend

HenrikOlsson
- 16th September 2010, 20:51
Hi,
You said that the problem occured when the frame was large and I was asking HOW large.

The reason I asked is that your buffer wraps around when Length is 20 you only have space for 21 characters in your buffer.

You get you characters from RCREG and put them in Buffer[0], Buffer[1], Buffer[2].......Buffer[20]. When Length reaches 20 it wraps around to 0 and you overwrite what's in Buffer[0] and because you said the problem occured when the frame was "very large". So, is it when the frame is larger than 20 bytes?

/Henrik.