0
\$\begingroup\$

I have a problem when trying to test send and receive lines on RS485 communication, anyone know what may cause a problem here? It works without interrupt but with interrupt won't work. I am working on NXP LPC1788, and trying to make an interrupt echo program for RS485 (what I send, it sends me back to terminal). Thanks in advance.

int main(void) {

    uart2()

    NVIC_EnableIRQ(UART2_IRQn); 

    while(1) {

    } //while   

} //main

void receive(void) {

    SMR_485RECEIVE; //Receive data flow
    delay_1_ms();
    delay_1_ms();   
    receive_byte = LPC_UART2->RBR;
    }

void send(void) {

    SMR_485TRANSMIT; //Transmit data flow
    delay_1_ms();
    delay_1_ms();
    LPC_UART2->THR = receive_byte;
    }

void UART2_IRQHandler(void) __irq {

    BYTE tip = LPC_UART2->IIR & 0x06;       
    if((tip == 0x04) && !(LPC_UART2->RBR == '\0')){
        receive(); 
        delay_1_ms();
        send();
        }       

    }

If I'm right before sending I need to call SMR_485TRANSMIT and then store BYTE to output data register THR, when I want to receive byte I call SMR_485RECEIVE and then store data from input data register RBR to variable receive_byte. I deleted delays of 1ms and my code looks like this right now:

void receive(void) {


    SMR_485RECEIVE;
    delay_1_micro();
    receive_byte = LPC_UART2->RBR;
    }

void send(void) {


    SMR_485TRANSMIT;//Transmit data flow
    delay_1_micro();
    LPC_UART2->THR = receive_byte;
    }

void UART2_IRQHandler(void) __irq {

    BYTE tip = LPC_UART2->IIR & 0x06;       
    if(tip == 0x04){
        receive();
        delay_1_micro();
        send();
        }       
    }

But it won't work, I dont understand whats the problem in my code when switching direction of data flow?

\$\endgroup\$
  • \$\begingroup\$ What is SMR_485RECEIVE;? And I believe you can directly read data from RBR register without any delay! \$\endgroup\$ – Swanand Apr 20 '15 at 8:08
  • \$\begingroup\$ @Swanand SMR_485RECEIVE is used for data flow control when you want to receive data, just put the GPIO pin on '0', it is CTS pin. It is defined at the top of the main.c file #define SMR_485TRANSMIT LPC_GPIO5->SET |= (1<<0) //TRANSMIT #define SMR_485RECEIVE LPC_GPIO5->CLR |= (1<<0) //RECEIVE \$\endgroup\$ – Lazar Apr 20 '15 at 8:12
  • \$\begingroup\$ how is the ISER0 ISPR0 ICPR0 IABR0and similar registers being setup for this interrupt? perhaps I'm missing it, but I do not see where the appropriate bit in the ICPR0 register is being written to '1 to clear the interrupt pending indication. (if not cleared, then the interrupt handler will be re-executed, as soon as the handler exits. \$\endgroup\$ – user3629249 Apr 21 '15 at 1:22
  • \$\begingroup\$ have you tested the code to assure that successive input characters, with no echo, works? have you tested the code to assure that successive outputs, with no receiving works? After getting the individual directions to work correctly, then the testing for 'echo' processing can begin, knowing that both input operation and output operation work correctly \$\endgroup\$ – user3629249 Apr 21 '15 at 1:41
  • \$\begingroup\$ @user3629249 Steps that I went through during setup of RS485 interrupt are: 1) Initialize UART2 peripheral and required pins 2) Clear DLAB bit in LCR register 3) Enable RBRIE and THREIE interrupt bits (flag bits) in IER register 4) Enable interrupt for UART2 with NVIC_EnableIRQ(UART2_IRQn) 5) Masked 2 bits RDR and THRE in IIR register and checking them all the time if they are set, if RDA is set go to receive function, if THRE is set go to send function and thats it. Are there steps that I forgot and that may be the reason it wont work? \$\endgroup\$ – Lazar Apr 21 '15 at 8:31
2
\$\begingroup\$

Your Interrupt handler tries to read RBR twice (once in the handler, once in receive). That won't work, the RBR reads one byte from the FIFO each time.

The RS485 switching also seems to be incorrect. You ususally switch to transmit mode immediately before sending a byte, and you switch back to receive in the THRE interrupt when transmission is over.

The 1ms delays will be problematic with baud rates > 2400, causing lost frames.

\$\endgroup\$
  • \$\begingroup\$ Note that the NXP LPC17xx may have an UART with hardware support for the RS485 directional switch. \$\endgroup\$ – Turbo J Apr 20 '15 at 11:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.