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 support@ccsinfo.com

Help with using 2 UART RX interrupts with 18F46J50

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



Joined: 11 Aug 2010
Posts: 4

View user's profile Send private message Visit poster's website

Help with using 2 UART RX interrupts with 18F46J50
PostPosted: Wed Aug 11, 2010 1:13 pm     Reply with quote

I am trying to use both hardware UARTS on a PIC18F46J50 with CCS PCH 4.109, and I want to use RX interupts (INT_RDA and INT_RDA2) with each.

What I'm finding is that INT_RDA works, but INT_RDA2 never fires. I say it never fires both on the variable in the interrupt handler never being incremented and also on the basis that setting a breakpoint in the interrupt never gets hit.

In the main function, the for(;;) loop, the fprintf is to send a message to the device on the other end of the 485 to cause it to send a reply (that should trigger the interrupt). I can see from a line sniffer that the device on the other end replies, and if I turn off the interrupt and use fgetc, I can see the reply, so it isn't that nothing is being sent to the second serial port.

Here is sample program that recreates my problem. Sorry for the length, I tried to trim it as much as I could without removing something that might be important.

Code:
#include <18F46J50.h>

#use delay(clock=48Mhz)

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale

#FUSES PRIMARY                  //Primary clock is system clock when scs=00
#FUSES HSPLL                    //High Speed Crystal/Resonator with PLL enabled    not
#FUSES PLLDIV3 
#FUSES NOCPUDIV
// #FUSES DEBUG                    //Debug mode for use with ICD
// #FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NOPROTECT                //Code not protected from reading
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES IESO                      //Internal External Switch Over mode enabled
#FUSES IOL1WAY                  //Allows only one reconfiguration of peripheral pins

#FUSES NOWPCFG               
#FUSES WPEND                 
#FUSES WPDIS                 
#FUSES NOLPT1OSC                //Timer1 configured for higher power operation
#FUSES T1DIG                 
#FUSES MSSPMSK7             
             
#FUSES DSWDT2147483648       
#FUSES DSWDT                 
#FUSES DSBOR                 
#FUSES RTCOSC_T1             
#FUSES DSWDTOSC_INT         
           
#FUSES WPFP

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, stream=remote_232)
#use rs232(baud=19200,parity=N,xmit=PIN_C1,rcv=PIN_C0,enable=PIN_C2,bits=8, stream=cp_485)

/*

Uart handler code  with interrupts

*/
#define RX_SIZE   0x3f        // must be in modulo value for         

int RxBuf_485[RX_SIZE+1];      // 64 byte rcv ring buffer for comms485

int RxH_485= 0;   // buffer first in idx
int RxT_485= 0;   // buffer last in idx

int RxBuf_232[RX_SIZE+1];      // 64 byte rcv ring buffer for comms232

int RxH_232= 0;
int RxT_232= 0;

#INT_RDA2
void RDA2_isr(void)
{
  RxBuf_485[RxH_485++] = fgetc(cp_485); // capture the incomming char and bump the idx
  if (RxH_485 > RX_SIZE)
    RxH_485 =0;      // reset the idx if wrap point 

  //if (RxT_485 == RxH_485) printf("ERROR!  Rx_485 Full\n\r");    // does not stop just wraps over tail ?????                                                           
}

// Dequeue the Rx_485 buffer  returns a 0xff if no data available
int Getc_485(void)
{
  int    bufdat;
 
  if (RxT_485 != RxH_485)
    {
      bufdat = RxBuf_485[RxT_485++];
      if (RxT_485 > RX_SIZE)
   RxT_485 =0;    // reset the idx if wrap point
      return bufdat;
    }
  return -1;
}

//  see if anything in Rxbuf ret = number of elements available
int Poll_485RxB(void)
{
  int temp_T;
  temp_T = RX_SIZE-RxT_485;
  if( RxH_485 >= RxT_485) return (RxH_485 - RxT_485);
  else return   (RxH_485 + temp_T);             
}

#INT_RDA
void RDA_isr(void)
{
  RxBuf_232[RxH_232++] = fgetc(remote_232); // capture the incomming char and bump the idx
 
  if (RxH_232 > RX_SIZE) RxH_232 = 0;       // reset the idx if wrap point
 
  //if (RxT_232 == RxH_232) printf("ERROR!  Rx_232 Full\n\r");    // does not stop just wraps over tail ?????
}

// Dequeue the Rx_485 buffer  returns a 0xff if no data available
int Getc_232(void)
{
  int bufdat;
  if (RxT_232 != RxH_232)
    {
      //         printf("Rx_232 Tail %d\n\r" RxT_232);
      bufdat = RxBuf_232[RxT_232++];
      if (RxT_232 > RX_SIZE) RxT_232 =0x00;       // reset the idx if wrap point
      return bufdat;
    }
  return -1;
}

//  see if anything in Rxbuf ret = number of elements available
int Poll_232RxB(void)
{
  int temp_T;
  temp_T = RX_SIZE-RxT_232;
  if( RxH_232 >= RxT_232) return (RxH_232 - RxT_232);
  else return   (RxH_232 + temp_T);       
}


void main( void )
{
  //TODO: Read a switch and set speed based on that.
  setup_oscillator(OSC_PLL_ON);
  setup_adc_ports(NO_ANALOGS|VSS_VDD);
  setup_wdt(WDT_OFF);
  setup_timer_0(RTCC_EXT_L_TO_H);
 
  setup_timer_1(T1_FOSC | T1_DIV_BY_1);
 
  enable_interrupts(INT_RDA);      // remote Rx 232 port
  enable_interrupts(INT_RDA2);      // remote Rx 485 port
 
  enable_interrupts(GLOBAL);

  setup_timer_2(T2_DISABLED,0,1);
  setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
  setup_timer_4(T4_DISABLED,0,1);
  setup_ccp1(CCP_OFF);
  setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard

  fprintf(remote_232, "Starting\r\n");

  for(;;)
    {
      fprintf(cp_485, "\xbf\x04\x8d");
      fprintf(remote_232, "485: %d\r\n", RxH_485);
      fprintf(remote_232, "232: %d\r\n", RxH_232);
      delay_ms(100);
    }
}
Jeff King



Joined: 20 Oct 2003
Posts: 43
Location: Hillsdale, Michigan USA

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Aug 11, 2010 1:30 pm     Reply with quote

I'm doing something with the PIC18F25J50, which is in the same family as your part, and I do have TX interrupts working on the second serial port. I'm about to implement RX interrupts but one thing I noticed is you didn't define the pins for the second uart with the pin_select command. This family allows mapping of some of the peripherals, the 2nd UART being one. Here is my setup code, and as I said, I do know for a fact transmit works on the 2nd serial port


Code:

#define  XB_DI       PIN_B2
#define  XB_DO       PIN_B3

#pragma pin_select  U2TX=XB_DI
#pragma pin_select  U2RX=XB_DO
                         

#pragma use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7, ERRORS, STREAM=GPS)     
#pragma use rs232(uart2, baud=9600, ERRORS, STREAM=XBRADIO)


I'll let you know how the RX for the 2nd port works for me later today. I'm using 4.109 as well.
Jeff King



Joined: 20 Oct 2003
Posts: 43
Location: Hillsdale, Michigan USA

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sat Aug 14, 2010 1:23 am     Reply with quote

My RX ISR worked fine.

Any luck after you tried the pin select command?
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

Re: Help with using 2 UART RX interrupts with 18F46J50
PostPosted: Sat Aug 14, 2010 8:50 am     Reply with quote

JDBoyd wrote:


Code:
#include <18F46J50.h>

.....snip....

#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, stream=remote_232)
#use rs232(baud=19200,parity=N,xmit=PIN_C1,rcv=PIN_C0,enable=PIN_C2,bits=8, stream=cp_485)

....snip....


I would also include UART1 and UART2 here just for clarity. You're missing uart2 at a minimum.

having both will make your code more self-explanatory.

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
Jeff King



Joined: 20 Oct 2003
Posts: 43
Location: Hillsdale, Michigan USA

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Sat Aug 14, 2010 10:34 am     Reply with quote

Agreed, here are my new defines and works like a champ for me:


Code:
#define  XB_DI      PIN_B2
#define  XB_DO      PIN_B3

#pragma pin_select  U2TX=XB_DI
#pragma pin_select  U2RX=XB_DO                               

#pragma use rs232(uart1, baud=9600, ERRORS, STREAM=GPS)     
#pragma use rs232(uart2, baud=9600, ERRORS, STREAM=XBRADIO)     


uart1 pins being part of the part spec and uart2 being selected with the pin_select command

What I think is happening with the gents code, is since he is not using Pin Select, the compiler is defining the UART as a software one, and hence he has no hardware IRQ to fire.
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Sat Aug 14, 2010 10:43 am     Reply with quote

Jeff King wrote:
Agreed, here are my new defines and works like a champ for me:


Code:
#define  XB_DI      PIN_B2
#define  XB_DO      PIN_B3

#pragma pin_select  U2TX=XB_DI
#pragma pin_select  U2RX=XB_DO                               

#pragma use rs232(uart1, baud=9600, ERRORS, STREAM=GPS)     
#pragma use rs232(uart2, baud=9600, ERRORS, STREAM=XBRADIO)     


uart1 pins being part of the part spec and uart2 being selected with the pin_select command

What I think is happening with the gents code, is since he is not using Pin Select, the compiler is defining the UART as a software one, and hence he has no hardware IRQ to fire.


That's probably exactly what's happening. Software UART --hence no IRQ.


-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
JDBoyd



Joined: 11 Aug 2010
Posts: 4

View user's profile Send private message Visit poster's website

PostPosted: Tue Aug 17, 2010 8:03 am     Reply with quote

Jeff King wrote:
I'm doing something with the PIC18F25J50, which is in the same family as your part, and I do have TX interrupts working on the second serial port. I'm about to implement RX interrupts but one thing I noticed is you didn't define the pins for the second uart with the pin_select command. This family allows mapping of some of the peripherals, the 2nd UART being one. Here is my setup code, and as I said, I do know for a fact transmit works on the 2nd serial port


Code:

#define  XB_DI       PIN_B2
#define  XB_DO       PIN_B3

#pragma pin_select  U2TX=XB_DI
#pragma pin_select  U2RX=XB_DO
                         

#pragma use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7, ERRORS, STREAM=GPS)     
#pragma use rs232(uart2, baud=9600, ERRORS, STREAM=XBRADIO)


I'll let you know how the RX for the 2nd port works for me later today. I'm using 4.109 as well.


OK, I updated to 4.110, made the changes required by the new update (PLLDIV3 -> PLL3, remove the #fuse PRIMARY), and added #pin_select lines, and now the second is working.

Thanks.
fbtech



Joined: 25 Mar 2015
Posts: 7

View user's profile Send private message

PostPosted: Fri Mar 27, 2015 11:20 am     Reply with quote

Hello,
I have the problem of the 2 UART with 18f25j50.
I use the code posted in this discussion.

Here is my header file generated by PIC c wizard:
Code:

#include <18F25J50.h>
#device ADC=10

#FUSES NOWDT                    //No Watch Dog Timer

#use delay(clock=48MHz,crystal=8MHz,USB_FULL)

#byte PORTA   = 0xf80
#byte PORTB   = 0xf81
#byte PORTC   = 0xf82
#byte TRISA   = 0xf92
#byte TRISB   = 0xf93
#byte TRISC   = 0xf94

#define  XB_DI       PIN_B2
#define  XB_DO       PIN_B3

#pragma pin_select  U2TX=XB_DI
#pragma pin_select  U2RX=XB_DO

#pragma use rs232(uart1,baud=9600, ERRORS, STREAM=DATA1)     
#pragma use rs232(uart2, baud=9600, ERRORS, STREAM=DATA2)

//#use rs232(UART1,baud=2400,ERRORS,stream=UART1)
//#use rs232(UART2,baud=9600,ERRORS,stream=UART2)

#define USB_CONFIG_VID 0x2405
#define USB_CONFIG_PID 0x000B
#define USB_CONFIG_BUS_POWER 500
#define USB_STRINGS_OVERWRITTEN

char USB_STRING_DESC_OFFSET[]={0,4,18};

char const USB_STRING_DESC[]={
   //string 0 - language
      4,  //length of string index
      0x03,  //descriptor type (STRING)
      0x09,0x04,  //Microsoft Defined for US-English
   //string 1 - manufacturer
      14,  //length of string index
      0x03,  //descriptor type (STRING)
      'F',0,
      'B',0,
      'T',0,
      'e',0,
      'C',0,
      'H',0,
   //string 2 - product
      14,  //length of string index
      0x03,  //descriptor type (STRING)
      'F',0,
      'B',0,
      'T',0,
      'e',0,
      'C',0,
      'H',0
};

#include <usb_cdc.h>



here my main.c

Code:

#include <main.h>
#include <string.h> 

//RTCC
rtc_time_t wizardTempTime;

#INT_RDA
void  RDA_isr(void)
{

}

#INT_RDA2
void  RDA2_isr(void)
{

}

void initialisation(void)
{
   
   
}

/* TODO: Use usb_cdc_putc() to transmit data to the USB
virtual COM port. Use usb_cdc_kbhit() and usb_cdc_getc() to
receive data from the USB virtual COM port. usb_enumerated()
can be used to see if connected to a host and ready to
communicate. */

void main()
{
   
   char f,gfilename[12];
   char msg[64];
   
   PORTA = 0x00;
   PORTB = 0x00;
   PORTC = 0x00;
   
   TRISA = 0xDF;
   TRISB = 0x08;
   TRISC = 0x8C;
   
   //setup_adc_ports(sAN0);
   //setup_adc(ADC_CLOCK_INTERNAL|ADC_TAD_MUL_0);
   //set_adc_channel( 0 );
   // value = read_adc();
   // setup_adc( ADC_OFF );
   
   //RTCC
   setup_rtc(RTC_ENABLE | RTC_OUTPUT_SOURCE, 0);
   wizardTempTime.tm_year = 15;
   wizardTempTime.tm_mon = 3;
   wizardTempTime.tm_mday = 26;
   wizardTempTime.tm_wday = 4;
   wizardTempTime.tm_hour = 15;
   wizardTempTime.tm_min = 30;
   wizardTempTime.tm_sec = 37;
   rtc_write(&wizardTempTime);

   // enable_interrupts(INT_RDA);
   // enable_interrupts(INT_RDA2);
   // enable_interrupts(GLOBAL);
   // usb_init();
   fprintf(DATA1,"\r\n UART1 TEST \r\n");
   fprintf(DATA2,"\r\n UART2 TEST \r\n");
   
   while(true);
} //Main



The result that I have with Proteus 8.1 is as follows:

http://www.4shared.com/download/NMmJ1sUBba/UART_ERROR.jpg?lgfp=3000

I'm using 5.036 compiler.

Thanks
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Fri Mar 27, 2015 11:33 am     Reply with quote

Did you read this link?

http://www.ccsinfo.com/forum/viewtopic.php?t=47549
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
fbtech



Joined: 25 Mar 2015
Posts: 7

View user's profile Send private message

PostPosted: Fri Mar 27, 2015 12:53 pm     Reply with quote

The question is about the c program and I try to give the maximum information to get the answer.
thanks
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Sat Mar 28, 2015 12:04 am     Reply with quote

Are you running the code in proteus or on actual hardware?
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
Ttelmah



Joined: 11 Mar 2010
Posts: 19370

View user's profile Send private message

PostPosted: Sat Mar 28, 2015 5:09 am     Reply with quote

Seriously repeat 15 times the first rule of debugging. Simplify.

Then repeat the second. Proteus Isis, does not work well with PIC's.

Then repeat "pragma is pointless in CCS" (read what it says about it in the manual).

With those repeated, your test code becomes:
Code:

#include <18F25J50.h>
#device ADC=10

#FUSES HSPLL, PLL2, NOXINST, NOCPUDIV, NOFCMEN, NOIESO, NOIOL1WAY, NOWDT
#use delay(clock=48MHz)

#pin_select  U2TX=PIN_B2
#pin_select  U2RX=PIN_B3

#use rs232(uart1,baud=9600, ERRORS, STREAM=DATA1)     
#use rs232(uart2, baud=9600, ERRORS, STREAM=DATA2)

void main()
{
   setup_adc_ports(NO_ANALOGS);
   output_drive(PIN_B2); //This may be needed depending on compiler version
   delay_ms(100);
   //most RS232 level generator chips _need_ a few mSec after power on
   fprintf(DATA1,"\r\n UART1 TEST \r\n");
   fprintf(DATA2,"\r\n UART2 TEST \r\n");
   
   while(true)
      ;
} //Main


This correctly prints the two strings to the two UART's on a properly working board.
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