Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Problem with using sn75176 in a serial connection between PIC18F452 and PIC16F628

Status
Not open for further replies.

losturcos

Member level 4
Joined
Aug 30, 2007
Messages
76
Helped
4
Reputation
8
Reaction score
3
Trophy points
1,288
Activity points
1,838
hi!
i am making a serial connection rs485 between pic18f452 and pic16f628.
The procedure is one send byte message the other get it and replies as an ok msg. This happens three times. Then the receiver becomes the sender and the same procedure occurs.
Now, the program works if i connect RX and TX pins directly. But when i use sn75176, one for each pic, it doesn't work. I set the DeRe pin high before the message sending and clear it after sending, this is the nearly only difference at the code. No data transmission. If i put a big delay(150ms) after sending msg, two or three transmissions seems to happen. Then it is locked again. What can the problem be? Do you have a guess. I will send the codes when i prepare them for sending.

Thanks.

Note: I use no interrupts.
 

connection sn75176 problem

If you use RS485 driver's RE pin to block loop back of Tx data to the local receiver UART, you also have to
place a pullup resistor at the RxD pin, otherwise the floating RxD level may cause a framing error at the receiver
and lock the UART, unless you reset the error.
 

sn75176 loop mode

**broken link removed**
This is the simple proteus scheme of the serial connection part of my project.
And the codes are like below:
Code:
// serLib.h
#ifndef SERLIB_H_
#define SERLIB_H_

#endif /*SERLIB_H_*/

#define BAUD 9600     
#define FOSC 4000000L
#define NINE 0     /* Use 9bit communication? FALSE=8bit */

#define DIVIDER ((int)(FOSC/(16UL * BAUD) -1))
#define HIGH_SPEED 1

#if NINE == 1
#define NINE_BITS 0x40
#else
#define NINE_BITS 0
#endif

#if HIGH_SPEED == 1
#define SPEED 0x4
#else
#define SPEED 0
#endif

#define   RX_PIN TRISB1
#define   TX_PIN TRISB2

//void SendChar(unsigned char);
unsigned char ReceiveChar(void);
unsigned char getche(void);
void init_comms(void);

void init_comms()
{
   TRISB1 = 1;
   TRISB2 = 0;
   SPBRG = DIVIDER;
   RCSTA = (NINE_BITS|0x90);
   TXSTA = (SPEED|NINE_BITS|0x20);
   //RCIE = 1;
   //GIE = 1;
}

void SendChar(unsigned char byte)
{
   serialEnable = SEND_ENABLE;
   while(!TXIF)
      continue;
   TXREG = byte;
   serialEnable = RECEIVE_ENABLE;
}

unsigned char ReceiveChar()
{
   return RCREG;
}
Code:
// SerialProcesses.h
void SerialProcesses()
{
   char temp;
   if(serialMode == WAIT_MODE)
   {
      if(RCIF)
      {
         if(serialIndexTX == 3)
         {
            arrayDataOut[serialIndexRC] = ReceiveChar();
            serialIndexRC++;
            if(serialIndexRC > 2)
            {
               serialIndexTX = 0;
               serialMode = SEND_MODE;
            }
            else
            {
               serialMode = SEND_MODE;
               b_sendOk = 1;
            }
         }
         else
         {
            if(ReceiveChar() == 55)
            {
               serialMode = SEND_MODE;
            }
         }
         RCIF = 0;
      }
   }
   else
   {
      if(b_sendOk == 1)
      {
         SendChar(55);
         serialMode = WAIT_MODE;
         b_sendOk = 0;
      }
      else
      {
         SendChar(arrayDataIn[serialIndexTX]);
         if(++serialIndexTX > 2)
         {
            serialIndexRC = 0;
            serialMode = WAIT_MODE;
         }
         else
         {
            serialMode = WAIT_MODE;
         }
      }
   }
   return;
}
Code:
// StartUp.h
void StartUp()
{
   TRISA = 0;
   TRISB = 0b10000010;
   PORTA = 0;
   PORTB = 0;
   GIE = 0;
   
   init_comms();
   
   return;
}
Code:
// picA Main
void main(void)
{
   StartUp();

        serialMode = SEND_MODE;
   serialIndexRC = 3;
   serialEnable = SEND_ENABLE;
   serialEnableReg = 1;
   
   while(1)
   {
      DataIn();
      SerialProcesses();
      DataOut();
   }
   
   return;
}
Code:
// picB Main
void main(void)
{
   StartUp();

        serialMode = WAIT_MODE;
   serialIndexRC = 3;
   serialEnable = RECEIVE_ENABLE;
   serialEnableReg = 1;
   
   while(1)
   {
      DataIn();
      SerialProcesses();
      DataOut();
   }
   
   return;
}

Added after 2 hours 49 minutes:

i suppose the problem is about FERR or OERR. i will search it tomorrow.
Of course i welcome any guesses :)
 

sn75176 communication

In RS485 half duple mode, you will have to take care of direction control in a proper way.

After transmitting, if you check for the TX BUFFER to be empty and then switch to receive mode, the last byte would still be transmitting in the transmision register .... you will be truncating the last byte in the middle of transmission.

So check for TX REGISTER and not TX BUFFER to be empty BEFORE switching to receive mode. Better still give a 1 mS delay before switching to receive mode.

The other end should take care not to respond before 1 mS.

Hope this helps.

Cheers

Ravi
 

init_comms

I controlled TRMT bit, and one byte transmission successfully sent. But then no transmission happens. I found out that frame error is the reason, but i couldn't find out how to solve that problem yet.
 

txsta rcsta

Aslo don't forget to put two terminal resistors between A and B (pins 6 and 7), see 75176 pdf
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top