RS 485 bus - 4 wires

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

RS 485 bus - 4 wires

669 Views
Paleantrop
Contributor III

Hello,

 

I am trying to implement a 4 wires RS 485 bus using MCF52259 and MQX. Theoretically, I have the RxEnable and TxEnable lines to GPIO ports and Tx - Rx data to uart2 port.

So, by default RxEnable and TxEnable are  0 which means Rx mode available. And when I want to transmit I must set the RxEnable to 1 and TxEnable to 1.

The problem is that I cannot manage to enable the TxEnable only when data is transmitted on Tx. Take a look on the attached file.I am not sure how to do it, using interrupts or time delays

Also, I copy paste part of my code, maybe someone has an idea :

 

 

 

[....]while(fstatus(uart0_ptr)) // read from uart0 - terminal window  {     read(uart0_ptr, (char_ptr)req + nBytes,1);     SetEnable(); // set TxEnable and RxEnable               write(uart2_ptr,(char_ptr)req + nBytes,1);              nBytes++;                        }     nBytes =0;           _time_delay(100);         ResetEnable(); // reset TxEnable , Rx Enable     [....]      

 

Thank you

 

 

 

0 Kudos
1 Reply

308 Views
boogy
Contributor III

I am using all three uarts on a MC52259 with controls only on the transmit enable for each 485 driver. The rx enable is always on.

 

The first thing I do is set up a 250uS timer that runs a timer task.

In order to do this I have set up my BSP with BSP_ALARM_FREQUENCY  = 4000.

 

 MQX_TICK_STRUCT dticks;
 MQX_TICK_STRUCT ticks;

 _time_init_ticks(& ticks, 0);
 _time_init_ticks(& dticks, 0);
 _time_add_usec_to_ticks(& ticks,250);
 _time_add_usec_to_ticks(& dticks,250);

 com_timer_fd = _timer_start_periodic_at_ticks(check_uart_timer, 0,
      TIMER_ELAPSED_TIME_MODE, & ticks, & dticks);

 

My check_uart_timer routine looks for a non zero value in a global counter and decrements it.

When it reaches zero it turns off the transmit enable.

void check_uart_timer

{

 if(uart1_timer)
  if(! -- uart1_timer)
  {
   ioctl(ch1_enable_fh, GPIO_IOCTL_WRITE_LOG0, NULL);
   
  }

}

I use the GPIO_IOCTL_WRITE_LOG0 because it is the fastest method.

 

All you have to do is calculate how many 250uS time slices you need for the whole packet and set your counter to that value.

_mqx_int    unc1_puts(char *s)
{
 _mqx_int err;
 err = 0;

  ioctl(ch1_enable_fh, GPIO_IOCTL_WRITE_LOG1, NULL); // turn on the transmit enable
  err = fputs(s,ch1_fh); //err returns how many bytes in the string
  uart1_timer = (40000 * err  / uart1_baud) +1; //this was derived partially by theory mostly by experimentation
  while(uart1_timer)
   _time_delay(10);

}

 

The time delay allows other tasks to execute while the system handles the communications.

The uart1_baud holds the programmed baud rate for the channel.