View previous topic :: View next topic |
Author |
Message |
macias86
Joined: 22 Apr 2011 Posts: 9
|
18f26j50 - two uarts and interrupts |
Posted: Fri Apr 22, 2011 5:36 pm |
|
|
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
|
|
Posted: Fri Apr 22, 2011 7:40 pm |
|
|
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
|
|
Posted: Sat Apr 23, 2011 2:24 am |
|
|
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: 19510
|
|
Posted: Sun Apr 24, 2011 2:50 am |
|
|
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
|
|
Posted: Sun Apr 24, 2011 3:19 am |
|
|
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: 19510
|
|
Posted: Sun Apr 24, 2011 10:24 am |
|
|
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
|
|
Posted: Sun Apr 24, 2011 11:05 am |
|
|
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: 19510
|
|
Posted: Mon Apr 25, 2011 8:43 am |
|
|
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
|
|
Posted: Mon Apr 25, 2011 12:04 pm |
|
|
#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: 19510
|
|
Posted: Mon Apr 25, 2011 2:03 pm |
|
|
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
|
|
Posted: Mon Apr 25, 2011 3:58 pm |
|
|
Ok. How can i auto locate registers in ccs? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Tue Apr 26, 2011 2:16 am |
|
|
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
|
|
Posted: Tue Apr 26, 2011 2:44 am |
|
|
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. |
|
|
|