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

18f26j50 - two uarts and interrupts

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



Joined: 22 Apr 2011
Posts: 9

View user's profile Send private message

18f26j50 - two uarts and interrupts
PostPosted: Fri Apr 22, 2011 5:36 pm     Reply with quote

I would like to communicate with gps and gsm modem. My question is: how can i use interrupt on usart1 and 2 in the same time? is it possible? what am i doing wrong?

Last edited by macias86 on Sun Sep 25, 2011 11:46 am; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 22, 2011 7:40 pm     Reply with quote

Post your #fuses and your #use delay() lines, and post your compiler version.

Also post if this is a hardware project or a Proteus project.
macias86



Joined: 22 Apr 2011
Posts: 9

View user's profile Send private message

PostPosted: Sat Apr 23, 2011 2:24 am     Reply with quote

This is the rest of my code

Code:
#include <18F26j50.h>
#fuses HSPLL,NOWDT,NOPROTECT,NODEBUG,PLL2,NOCPUDIV,STVREN,NOXINST
#use delay(clock=48000000)


v4.114

it is hardware project

and i send chars to usb inside interrupts:

Code:
if(usb_enumerated()) usb_cdc_putc_fast(ch);


only usart1 interrupt works. but i have some errors, like lost chars.. I made similiar project but with one interrupt to read data from gps and it worked fine.


Last edited by macias86 on Sun Sep 25, 2011 11:47 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Sun Apr 24, 2011 2:50 am     Reply with quote

Some comments:
You do not need to read two characters to clear a framing error. A framing error occurs on a per character basic, and just _one_ character needs to be read.
If you don't actually want to do anything 'with' a framing error, then the normal read routine will clear it. If you want to 'throw away' the character with the error, then you need to read the one character, and exit the routine.
Similarly with OERR, just clear CREN, reset it, and read the next byte from the buffer. You have two 'good' bytes there, don't waste them. So:

Code:

void rda_interrupt()
{
    char ch;
    // look for a framing or overrun error and clear
    if(OERR)
    {
         CREN = OFF;
         CREN = ON;
         //The single read in the rest of the routine makes space in the buffer.
    }
    if (FERR)
    {
         ch=RCREG;
         return; //Throw away the error byte
    }
    ch = (RCREG & 0x7f);                                    // get the character
    if(usb_enumerated()) usb_cdc_putc_fast(ch);         // send to the USB
}

Your code as posted, is never going to work, since you have not initialised the USB. The USB will never enumerate without this, so nothing will ever get echoed. usb_init, is _required_ before using the USB.....

Best Wishes
macias86



Joined: 22 Apr 2011
Posts: 9

View user's profile Send private message

PostPosted: Sun Apr 24, 2011 3:19 am     Reply with quote

I didnt ask how to use usb ;) (btw. i included usb_cdc.h and i use usb_init_cs();). Thanks for comments to OERR and FERR.

Anyway I asked how to use two RX interrupts together. Where is the trick? I can use both separately (only RDA active or only RDA2 active) but not together. When i turn both ON then only RDA seems to work.
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Sun Apr 24, 2011 10:24 am     Reply with quote

Just do it....
_However_ USB might well be the problem.
If the USB buffer is full, a buffer flush will try to take place. This _will not work_ with interrupts disabled (which they are, if you are inside an interrupt). This is why there is the comment in the remarks for usb_cdc.h, that if you want to call usb_cdc_putc _inside an interurpt_, you should use usb_cdc_putc_fast_noflush instead.

Best Wishes
macias86



Joined: 22 Apr 2011
Posts: 9

View user's profile Send private message

PostPosted: Sun Apr 24, 2011 11:05 am     Reply with quote

Yes i know that about usb. i took old version to modify into new program. :P

What can i do with those two usart rx interrupts?
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Mon Apr 25, 2011 8:43 am     Reply with quote

The point is that dual RS232 interrupts work fine.
Your code is being stopped by _something_ you are doing in the interrupts themselves. When I point out problems with your posted code, you then say this is not the code you are testing. Er... This is _not_ how to find faults/get help...

Step back. Make each serial interrupt, _just_ write data to two ring buffers (ex_sisr.c). Then in your main code, do the transmission to USB.

Don't be surprised if it then all starts working...

Best Wishes
macias86



Joined: 22 Apr 2011
Posts: 9

View user's profile Send private message

PostPosted: Mon Apr 25, 2011 12:04 pm     Reply with quote

#byte RCSTA2 = 0xF9C

instead of

#byte RCSTA2 = 0xFA8

and then this posted code works perfect.
Stupid family changes..
Thought there is some trick like starting pll separately. I even searched for errata's.
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Mon Apr 25, 2011 2:03 pm     Reply with quote

No, just using register addresses, and not letting the compiler do it's job.
Either use putc, and getc, or if you must use register addresses let the compiler locate them for you. The compiler can automatically locate registers for you. Use the ability.

Best Wishes
macias86



Joined: 22 Apr 2011
Posts: 9

View user's profile Send private message

PostPosted: Mon Apr 25, 2011 3:58 pm     Reply with quote

Ok. How can i auto locate registers in ccs?
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Tue Apr 26, 2011 2:16 am     Reply with quote

getenv.

#byte RCSTA2 = getenv("SFR:RCSTA2")

The thing that annoys me though, is that with the wrong register address, your code would not have worked as you claimed:
Quote:

"I can use both separately (only RDA active or only RDA2 active) but not together. When i turn both ON then only RDA seems to work."


Best Wishes
macias86



Joined: 22 Apr 2011
Posts: 9

View user's profile Send private message

PostPosted: Tue Apr 26, 2011 2:44 am     Reply with quote

Ttelmah wrote:

The thing that annoys me though, is that with the wrong register address, your code would not have worked as you claimed:
Quote:

"I can use both separately (only RDA active or only RDA2 active) but not together. When i turn both ON then only RDA seems to work."


Yes. That was weird..

Thank You for Your help.
Problem solved.
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