CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

18F26K22 Two Hardware UARTS - RS485

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jjacob



Joined: 08 Mar 2008
Posts: 54
Location: PORTUGAL (PORTO)

View user's profile Send private message

18F26K22 Two Hardware UARTS - RS485
PostPosted: Tue Apr 04, 2017 12:43 pm     Reply with quote

Hello,

I'm trying to implement a RS485 converter. I have a MASTER serial device that sends data to my converter, then converter sends to rs485 network. If convert receives something from rs485 network then sends to serial device.

Code:
#include <18F26K22.h>

#device adc=10

#FUSES INTRC_IO        // INTRC_IO Internal RC Osc, no CLKOUT
#FUSES NOFCMEN         //Fail-safe clock monitor disabled
#FUSES NOIESO          //Internal External Switch Over mode disabled
#FUSES NOPUT            //No Power Up Timer
#FUSES NOBROWNOUT       //No brownout reset
#FUSES NOWDT            //No Watch Dog Timer
#FUSES NOPBADEN        //PORTB pins are configured as digital I/O on RESET
#FUSES NOMCLR          //Master Clear pin NOT enabled
#FUSES NOLVP           //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST         //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES NODEBUG         //No Debug mode for ICD

#use    delay(clock = 16000000)

#define INIT_UART_BAUDRATE   9600
#use rs232(UART1, baud=INIT_UART_BAUDRATE, stream=rf, xmit=PIN_C6,rcv=PIN_C7, errors)
#use rs232(UART2, baud=INIT_UART_BAUDRATE, stream=rede, ENABLE = PIN_B5 , xmit=PIN_B6,rcv=PIN_B7, errors)


#define BUFFER_SIZE_A 32
BYTE buffer_A[BUFFER_SIZE_A];
BYTE next_in_A = 0;
BYTE next_out_A = 0;

#define BUFFER_SIZE_B 32
BYTE buffer_B[BUFFER_SIZE_B];
BYTE next_in_B = 0;
BYTE next_out_B = 0;

#INT_RDA

void serial_isr() {
    int t;

    buffer_A[next_in_A] = fgetc(rf);
    t = next_in_A;
    next_in_A = (next_in_A + 1) % BUFFER_SIZE_A;
    if (next_in_A == next_out_A)
        next_in_A = t; // Buffer full !!
}

#define bkbhit_A (next_in_A!=next_out_A)

BYTE bgetc_A() {
    BYTE c;

    while (!bkbhit_A);
    c = buffer_A[next_out_A];
    next_out_A = (next_out_A + 1) % BUFFER_SIZE_A;
    return (c);
}

#INT_RDA2

void serial_isr2() {
    int t;

    buffer_B[next_in_B] = fgetc(rede);
    t = next_in_B;
    next_in_B = (next_in_B + 1) % BUFFER_SIZE_B;
    if (next_in_B == next_out_B)
        next_in_B = t; // Buffer full !!
}

#define bkbhit_B (next_in_B!=next_out_B)

BYTE bgetc_B() {
    BYTE c;

    while (!bkbhit_B);
    c = buffer_B[next_out_B];
    next_out_B = (next_out_B + 1) % BUFFER_SIZE_B;
    return (c);
}

void main() {

    enable_interrupts(INT_RDA2 | INT_RDA);
    enable_interrupts(GLOBAL);

    printf("\r\n\Running...\r\n");

    // The program will delay for 10 seconds and then display
    // any data that came in during the 10 second delay

    do {


        while (bkbhit_A)
            fputc(bgetc_A(), rede);
       
        while (bkbhit_B)
            fputc(bgetc_B(), rf);

    } while (TRUE);
}



It works with only one of uart. With two simultaneous don't work. What I'm doing wrong?

Thanks for the help.
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Apr 04, 2017 12:53 pm     Reply with quote

this ?
enable_interrupts(INT_RDA2 | INT_RDA);

I don't think is 'legal'. At least I've always only used one device per enable_interrupt.

I'd have to check on the eng PC to confirm but I do know the 46K22 will run 2 HW UARTs at 921600 for days without a hiccup !

Jay
jeremiah



Joined: 20 Jul 2010
Posts: 1345

View user's profile Send private message

PostPosted: Tue Apr 04, 2017 1:07 pm     Reply with quote

It's not legal. The OP will have to call them like:
Code:

enable_interrupts(INT_RDA);
enable_interrupts(INT_RDA2);

The only time I've seen a bitwise OR used for enable_interrupts() is for Change Notification interrupts, but there is still a specific way to do it.
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Tue Apr 04, 2017 1:58 pm     Reply with quote

Also, general comments:

Far safer to use:

#use delay(INTERNAL=16MHz)

This ensures the clock is correctly programmed for 16Mhz.

You also don't need to specify the pins, if you use 'UART1' or 'UART2'. These are equivalent (for UART1) to

xmit=PIN_C6, rcv=PIN_C7, FORCE_HW

so it is rather silly to put the pin names as well...
jjacob



Joined: 08 Mar 2008
Posts: 54
Location: PORTUGAL (PORTO)

View user's profile Send private message

PostPosted: Wed Apr 05, 2017 4:07 am     Reply with quote

Hello,

Thank you all for your help. It's solved.

It was the:
Code:

enable_interrupts(INT_RDA);
enable_interrupts(INT_RDA2);
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group