View previous topic :: View next topic |
Author |
Message |
EricLinderson
Joined: 19 Mar 2007 Posts: 8
|
Trouble using 2 UART (rs232) |
Posted: Tue Apr 24, 2007 5:00 am |
|
|
I'm trying to use 2 uart ports with a PIC18F6722, the first UART works fine and is connected with a bluetooth module that uses wireless spp. The problem is the 2nd UART (connected with a GPS module) , I can see the incoming data with an oscilloscope on the RX2 pin but there is no interrupt generated. If I try to send data I can see that on the TX2 pin with the oscilloscope too. Anyone know a solution?
PS. The GPS worked with another PIC with one UART.
Code: |
#include <18F6722.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#use delay(CLOCK=32000000)
#priority RDA2,RDA
#fuses INTRC, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use rs232(baud=4800, xmit=PIN_G1, rcv=PIN_G2, parity=N, BITS=8, ERRORS, STREAM=GPS)
#use rs232(baud=9800, xmit=PIN_C6, rcv=PIN_C7, parity=N, BITS=8, ERRORS, STREAM=Bluetooth)
#define B_SIZE 70
char BUFFER_G[B_SIZE];
char BUFFER_B[B_SIZE];
char B_IN = 0;
char G_IN = 0;
bool newBT;
bool newGPS;
void init_irq()
{
SETUP_UART(TRUE);
SETUP_CCP1(CCP_OFF);
SETUP_CCP2(CCP_OFF);
SETUP_CCP3(CCP_OFF);
SETUP_CCP4(CCP_OFF);
SETUP_PSP(PSP_DISABLED);
SET_TRIS_C(0xBF);
SET_TRIS_G(0xFD);
ENABLE_INTERRUPTS(GLOBAL);
ENABLE_INTERRUPTS(INT_RDA);
ENABLE_INTERRUPTS(INT_RDA2);
}
void main()
{
SETUP_ADC(ADC_OFF);
setup_oscillator(OSC_32MHZ|OSC_PLL_ON);
while(1) {
if(newBT==1){
output_high(LED_BLUE);
DISABLE_INTERRUPTS(INT_RDA);
DISABLE_INTERRUPTS(INT_RDA2);
//Print BUFFERT_B on a display
ENABLE_INTERRUPTS(INT_RDA2);
ENABLE_INTERRUPTS(INT_RDA);
newGPS=0;
}
if(newGPS==1){
output_high(LED_GREEN);
DISABLE_INTERRUPTS(INT_RDA);
DISABLE_INTERRUPTS(INT_RDA2);
//Print BUFFER_G on a display
ENABLE_INTERRUPTS(INT_RDA2);
ENABLE_INTERRUPTS(INT_RDA);
newGPS=0;
}
delay_ms(250);
}
}
|
Interrupt code
Code: |
#int_rda
void serial_isr()
{
char bt;
int i;
DISABLE_INTERRUPTS(INT_RDA);
DISABLE_INTERRUPTS(INT_RDA2);
bt=fgetc(Bluetooth);
if(bt!=null){
output_low(LED_BLUE);
if(bt==0x0D)
{
newBT=1;
for(i=B_IN;i<B_SIZE-1;B_SIZE)
B_IN=B_SIZE;
}
}
ENABLE_INTERRUPTS(INT_RDA2);
ENABLE_INTERRUPTS(INT_RDA);
}
#int_rda2
void serial_isr2()
{
char gp;
int i;
DISABLE_INTERRUPTS(INT_RDA);
DISABLE_INTERRUPTS(INT_RDA2);
gp=fgetc(GPS);
if(gp!=null){
output_low(LED_GREEN);
if(gp==0x0D)
{
newGPS=1;
for(i=G_IN;i<B_SIZE-1;B_SIZE)
G_IN=B_SIZE;
}
}
ENABLE_INTERRUPTS(INT_RDA2);
ENABLE_INTERRUPTS(INT_RDA);
}
|
That was the interresting code I think...
Last edited by EricLinderson on Wed Apr 25, 2007 5:16 am; edited 1 time in total |
|
|
Passer Guest
|
|
Posted: Tue Apr 24, 2007 7:04 am |
|
|
Your init_irq() is never used.
|
|
|
EricLinderson
Joined: 19 Mar 2007 Posts: 8
|
|
Posted: Tue Apr 24, 2007 7:33 am |
|
|
you've got a point.. :P but I'm sure I removed that line by accident recently, it didn't work before either... |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Apr 24, 2007 8:57 am |
|
|
Which compiler version are you using?
You disable and enable the interrupts in the interrupt handler, there is no need to do so as all interrupts will be (temporarily) disabled by hardware as soon as an interrupt is fired.
What is the output voltage of the GPS module? If it is 3V and your PIC is operating at 5V this could be the cause of your problem. A TTL input will accept these voltage levels but the Schmitt Trigger input on PIN_G2/Rx2 won't. |
|
|
EricLinderson
Joined: 19 Mar 2007 Posts: 8
|
|
Posted: Wed Apr 25, 2007 2:04 am |
|
|
thank you, that solved the first problem. I used a driver to push the voltage up to 5v and now the interrupt occurs.
My next problem is that the buffer is just filled with, what seems like, random charactersand I can't get anything out of it. I've tried different baudrates, but when I used the first uart 4800 bps worked.
One step on the way, but still not fully solved.. More suggestions anyone? |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Apr 25, 2007 3:47 am |
|
|
Good to hear part of your problem is solved.
For the other question I have to ask again: Which compiler version are you using?
Quote: | for(i=G_IN;i<B_SIZE>B_SIZE) |
Can you fix/edit the code you posted on top of this thread? Now it is corrupted as part of the code was interpreted as HTML code. On posting code always remember to select the 'Disable HTML in this post' option, or even better, make this the default setting in your user profile. |
|
|
EricLinderson
Joined: 19 Mar 2007 Posts: 8
|
|
Posted: Wed Apr 25, 2007 5:18 am |
|
|
Hi again. My compiler version is 3.242, and I have corrected the post now.
I hope that'll help... |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Apr 25, 2007 5:30 am |
|
|
Version 3.242 seems like a good version to me.
Code: | for(i=G_IN;i<B_SIZE-1;B_SIZE)
G_IN=B_SIZE; | I'm not sure what you want to do here, but as it is this code will loop forever.
I hope you have removed the disabling and enabling of the interrupts in your interrupt handler? I already mentioned that on entry of the interrupt handler all interrupts will be disabled by hardware. But it is also a bug; if a character arrives in between the (short) time it takes to execute your interrupt handler, than no interrupt will be generated and you are missing characters. |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Wed Apr 25, 2007 5:39 am |
|
|
Code: |
if(bt!=null){
output_low(LED_BLUE);
if(bt==0x0D)
{
newBT=1;
for(i=B_IN;i<B_SIZE-1;B_SIZE)
B_IN=B_SIZE;
}
}
|
a)- In the _for_ loop the var i never change.
b)- B_IN always is assigned with a constant value (B_SIZE)
c)- You never store the incoming data.
d)- Variable bt is overwritten all the time.
Humberto |
|
|
Guest
|
|
Posted: Wed Apr 25, 2007 6:26 am |
|
|
ckielstra wrote: | Version 3.242 seems like a good version to me.
Code: | for(i=G_IN;i<B_SIZE-1;B_SIZE)
G_IN=B_SIZE; | I'm not sure what you want to do here, but as it is this code will loop forever.
I hope you have removed the disabling and enabling of the interrupts in your interrupt handler? I already mentioned that on entry of the interrupt handler all interrupts will be disabled by hardware. But it is also a bug; if a character arrives in between the (short) time it takes to execute your interrupt handler, than no interrupt will be generated and you are missing characters. |
Thank you for the input, the interrupt handling is removed. The bug that you have mentioned is corrected with the #priority setting where the desired interrupt RDA2 is on top. So it should trigger first of all.
for(i=G_IN;i<B_SIZE-1;B_SIZE) is corrected to for(i=G_IN;i<B_SIZE-1;i++) although still no progress. Rubbish data like chars with value 0xFF, 0xFA etc. are coming in. It seems very mystical... |
|
|
EricLinderson
Joined: 19 Mar 2007 Posts: 8
|
|
Posted: Wed Apr 25, 2007 6:35 am |
|
|
Humberto wrote: | Code: |
if(bt!=null){
output_low(LED_BLUE);
if(bt==0x0D)
{
newBT=1;
for(i=B_IN;i<B_SIZE-1;B_SIZE)
B_IN=B_SIZE;
}
}
|
a)- In the _for_ loop the var i never change.
b)- B_IN always is assigned with a constant value (B_SIZE)
c)- You never store the incoming data.
d)- Variable bt is overwritten all the time.
Humberto |
Thanks for your input!
a) is solved in the previous post.
b) is just a reset of the buffer when a complete string is received.
c) for the moment it is sent to LCD for verification
d) bt is actually stored into the buffer until a 0x0D is received as an end of the string. This code is a bit simplified.
Thanks for making an effort, do you have any other thoughts or experiences? It would be helpful! |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Wed Apr 25, 2007 7:53 am |
|
|
We can comment only the posted codes, we canĀ“t imagine the behaviour of your project
if it has hidden or not posted codes that modify some visible variables.
Humberto |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Apr 25, 2007 8:36 am |
|
|
Quote: | Rubbish data like chars with value 0xFF, 0xFA etc. are coming in. It seems very mystical... | Right now the only thing that I can think of is that your system is not running at 32MHz. Do a simple test by toggling an output in a loop. Make sure the delay time is long (5+ seconds) and measure the time using a clock, not by simply counting.
For more clever suggestions post a short test program that shows the problem. Show all your #fuses, #use, #include statements. The posted program should be compilable "as is", without any editing. Make it be very short (30 lines, max). |
|
|
EricLinderson
Joined: 19 Mar 2007 Posts: 8
|
|
Posted: Wed Apr 25, 2007 10:32 am |
|
|
Thanks for the tip, I'll implement such program in a few days, am a bit busy now. |
|
|
EricLinderson
Joined: 19 Mar 2007 Posts: 8
|
|
Posted: Wed May 02, 2007 1:14 pm |
|
|
I've tried every solution now, and after separately tested every component with a terminal I've come to the conclution that the PIC receives bad characters. It can send fine, on both UARTs, but if i echo the received chars it will just return bogus chars.
I use code something like this:
Code: |
char c;
while(1){
c=fgetc(Terminal);
fputc(c, Terminal);
}
|
I'm suspecting that the internal buffer is corrupted in some way... Any suggestions? |
|
|
|