2020/09/21 01:26:07
I am trying to implement Modbus RTU on dspic33ev256gm106 using 8mhz external crystal. I have used MCC code configurator for coding. But it can't transfer data.
I use ADM2481 RS485 Transceiver. I connect the pin with dspic33ev
RC0 --> RxD
RC1 --> TxD
RC2, RC11 --> /RE, DE
RS485 code:
void RS485_write(unsigned short addr_esclave, unsigned short function, unsigned short memAddress, unsigned short* data, unsigned short numbytes) {
int i=0;
buffer[0] = (unsigned char)addr_esclave;
buffer[1] = (unsigned char)function;
buffer[2] = (memAddress >> 8) & 0x00FF;
buffer[3]=(memAddress >> 0) & 0x00FF;
buffer[4]=(numbytes >> 8) & 0x00FF;
buffer[5]=(numbytes >> 0) & 0x00FF;
buffer[6]= (unsigned char)(2*numbytes);
for (i = 0; i < numbytes; i++){
buffer[2*i+7]=(data[i] >> 8) & 0x00FF;
buffer[2*i+1+7]=data[i] & 0x00FF;
CRC_16(2*numbytes + 7, 0);
RS485_CTRL = 1; //Enable driver; disable Receive
for(i=0; i< (2*numbytes+9); i++)

int CRC_16(unsigned int dataLength, char check) //CRC 16 for modbus checksum
unsigned int CheckSum;
unsigned int j;
unsigned char lowCRC;
unsigned char highCRC;
unsigned short i;
CheckSum = 0xffff;
for (j = 1; j < dataLength; j++) {
CheckSum = CheckSum^(unsigned int) buffer[j];
for (i = 8; i > 0; i--)
if ((CheckSum)&0x0001)
CheckSum = (CheckSum >> 1)^0xa001;
CheckSum >>= 1;
highCRC = CheckSum >> 8;
CheckSum <<= 8;
lowCRC = CheckSum >> 8;
if (check == 1) {
if ((buffer[dataLength + 1] == highCRC) & (buffer[dataLength] == lowCRC))
return 1;
return 0;
} else {
buffer[dataLength] = lowCRC;
buffer[dataLength + 1] = highCRC;

main :
int main(void)
// initialize the device
RS485_CTRL = 0; //disable driver; Receive Enable
unsigned short addr_esclave = 21;
unsigned short code_fct= 0x06;
unsigned short memAdress = 0X3;
unsigned short data[1] ;
unsigned short length = 1;
data[0] = 0x0000;

RS485_write(addr_esclave, code_fct, memAdress, data, length);
RS485_CTRL = 0;
while (1)
// Add your application code
return 1;

I will appreciate any help.
2020/09/22 20:09:16

But it can't transfer data.

What does this mean?
[1] There is nothing coming out the TX pin?
[2] There is something being sent, but the receiver doesn't recognise it?
[3] Some other problem?
2020/09/22 22:44:20
If the main is your real code, you are not setting DE before transmitting.
how is RS485_CTRL defined? is it a define to one of the two pins? because in one point you say you use two pins for communication control whereas in the code the comment suggest that one do both.
or is it a macro?
2020/09/23 03:47:18
Hi ric,
There is nothing coming out from the Tx pin.
2020/09/23 04:13:36
i've defined RS485_CTRL in rs485.h:
#define RS485_CTRL LATCbits.LATC2

As the comment suggest RC2 control both DE and/RE, RC11 is just an input.
I am setting DE before the transmission in rs485_write function. 
2020/09/23 04:40:47
As the comment suggest RC2 control both DE and/RE, RC11 is just an input.

what you wrote in the OP
RC2, RC11 --> /RE, DE

suggested otherwise so i had to check
I am setting DE before the transmission in rs485_write function.

uh! i missed that line, sorry
What about the IO Initialization?
I don't trust MCC, it should be just a couple of lines of C
_LATC1 = 1;
_TRISC1 = 0;
_ANSELC1 = 0;
_RP49R = 1; //1 is for U1TX, 3 is for U2TX

ANSELC1 needs to be cleared because the pin is multiplexed with the OPAMP so it will still be analog even if TRISC1 is cleared.
2020/09/23 04:44:09
As the comment suggest RC2 control both DE and/RE, RC11 is just an input.

That might have been your intention, but the comment did NOT make it clear to anyone else that this is what you did.
The secret to effective debugging is
get rid of all the faff, and just test one thing at a time.
In this instance, if nothing is coming out the TX pin, then there's something wrong with the UART1_Write() call.
Just try sending single known characters out that, and see if you can get the TX pin to toggle. Everything else is irrelevant until that works.
A storage scope is VERY useful at this stage.
© 2021 APG vNext Commercial Version 4.5

Use My Existing Forum Account