View previous topic :: View next topic |
Author |
Message |
theteaman
Joined: 04 Aug 2006 Posts: 98
|
Is it possible for RTCC to interfere with UART? |
Posted: Mon Jan 09, 2012 9:59 pm |
|
|
Hi
I'm using an 18F2550 with 20MHz crystal. I have a timer that blinks an LED at 2HZ:
Code: |
setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);
enable_interrupts(INT_RTCC);
#int_rtcc
void led_blink_isr(void)
{
timer0_counter++;
if(timer0_counter > 18)
{
timer0_counter = 0;
if(blinking_led_high)
output_low(PIN_A0);
else
output_high(PIN_A0);
blinking_led_high = !blinking_led_high;
}
}
|
and I'm using hardware UART to send data:
Code: |
#use rs232(baud=31250, xmit=PIN_C6, PARITY=N, STREAM=OUT_PORT)
|
When the timer is disabled, the UART works fine. But when I enable the timer, the UART data output is sometimes corrupted. I'm guessing the RTCC is interrupting my UART output.. any idea how to fix this?
Thanks! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 09, 2012 10:02 pm |
|
|
Quote: |
#use rs232(baud=31250, xmit=PIN_C6, PARITY=N, STREAM=OUT_PORT)
|
That's not a hardware UART. That's software. When you specify only
one of the hardware pins, the compiler creates a software UART on
that pin. |
|
|
theteaman
Joined: 04 Aug 2006 Posts: 98
|
|
Posted: Mon Jan 09, 2012 10:39 pm |
|
|
PCM programmer wrote: | Quote: |
#use rs232(baud=31250, xmit=PIN_C6, PARITY=N, STREAM=OUT_PORT)
|
That's not a hardware UART. That's software. When you specify only
one of the hardware pins, the compiler creates a software UART on
that pin. |
Ohhhhhh I did not realise this. Thanks for the heads up! The issue is that I use PIN_C7 for something else and it cannot be changed.. I'm guessing this means I cannot use hardware uart as it required C7 as RX.. Does this mean my only option is to disable the RTCC interrupt every time I use the UART, and enable after? If so, is this going to introduce poor performance?
Thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 09, 2012 11:12 pm |
|
|
You can add the DISABLE_INTS parameter to the #use rs232() statement
and the compiler will disable interrupts while each character is transmitted.
If you transmit at 31250 baud, it takes 320 usec to transmit one char,
so interrupts will be disabled during that time. You will have to decide
if that's a problem for your main code. |
|
|
theteaman
Joined: 04 Aug 2006 Posts: 98
|
|
Posted: Mon Jan 09, 2012 11:17 pm |
|
|
PCM programmer wrote: | You can add the DISABLE_INTS parameter to the #use rs232() statement
and the compiler will disable interrupts while each character is transmitted.
If you transmit at 31250 baud, it takes 320 usec to transmit one char,
so interrupts will be disabled during that time. You will have to decide
if that's a problem for your main code. |
It's fine if ints are disabled for 320us per character. What I was wondering is whether there is big performance hit when actually disabling interrupts (disable_interrupt(INT_RTCC)).
I imagine it just sets a CPU flag, so it should be a quick operation? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jan 09, 2012 11:24 pm |
|
|
To execute that line of code, it's almost nothing. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Tue Jan 10, 2012 3:32 am |
|
|
Do a search here.
Just set _both_ pins in the #USE RS232. Then drive the receive pin with whatever you want as normal.
If you look at the table of 'what pins do', when set as a receive pin, if you drive it as an output, it still works as an output, and you can read from it as an input even though the UART is on it as well.
The code for getc, won't be loaded unless you actually use it.
Best Wishes |
|
|
theteaman
Joined: 04 Aug 2006 Posts: 98
|
|
Posted: Wed Jan 11, 2012 6:44 pm |
|
|
Ttelmah wrote: | Do a search here.
Just set _both_ pins in the #USE RS232. Then drive the receive pin with whatever you want as normal.
If you look at the table of 'what pins do', when set as a receive pin, if you drive it as an output, it still works as an output, and you can read from it as an input even though the UART is on it as well.
The code for getc, won't be loaded unless you actually use it.
Best Wishes |
Thanks! So just to confirm:
Code: | #use rs232(baud=31250, xmit=PIN_C6, rcv=PIN_C7, PARITY=N) |
is hardware uart? I'm asking because it seems to still be causing a problem.. |
|
|
theteaman
Joined: 04 Aug 2006 Posts: 98
|
|
Posted: Thu Jan 12, 2012 5:40 pm |
|
|
Ttelmah wrote: | Do a search here.
Just set _both_ pins in the #USE RS232. Then drive the receive pin with whatever you want as normal.
If you look at the table of 'what pins do', when set as a receive pin, if you drive it as an output, it still works as an output, and you can read from it as an input even though the UART is on it as well.
The code for getc, won't be loaded unless you actually use it.
Best Wishes |
Hi Ttelmah
It's strange, but I cannot seem to use PIN_C7 as an output when I set the hardware UART as:
Code: |
#use rs232(baud=31250, xmit=PIN_C6, rcv=PIN_C7, PARITY=N, ERRORS) |
I am wondering if there is anything I need to look out for? |
|
|
theteaman
Joined: 04 Aug 2006 Posts: 98
|
|
Posted: Sat Jan 14, 2012 7:58 pm |
|
|
Hi
Another thread stated you can disable the UART, then perform the output_high() operation, and then enable the UART again. But it didn't work for me. I am using the 18F2550.
Any help appreciated, thanks. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Sun Jan 15, 2012 2:57 am |
|
|
Ok.
You have to be careful, since 'what happens' depends on how you are doing things, and the chip involved.
In CCS, it is 99% of the time easiest/most reliable, to let the compiler handle things like TRIS for you. _However_ when you are doing things like this (wanting pins to do different jobs), it can cause problems. Here the compiler 'knows' which pins are used by the UART, and what the TRIS settings have to be for this, so if you are using 'standard_io' (the default), it will override the TRIS settings for the UART pins to those required for the UART.
I have used pins multiple ways many times, but when I do, I always switch to fast_io, and make sure that _I_ set the pins as needed by the UART when I'm using the UART, and then manually take command when I want to do the other jobs. Whether you have to switch the UART off or not, depends on what you actually want to do, _and the chip involved_. On some chips, if the UART is enabled, the transmit pin overrides it's output pin whatever the TRIS setting. On others it doesn't. This is shown in the table associated with the pin in the data sheet. The same applies for the input pin.
So, you need to work out what you actually want to do:
1) use the RX input as a digital input?
2) use the RX input as a digital output?
3) use the TX output as a digital output?
4) use the TX output as a digital input?
Then you need to check how tris needs to be set for the possibilities you want, and whether the UART overrides this combination or not. If not, then the UART doesn't have to be switched off, but if the UART would override the combination, then the UART has to be turned off.
Do this, and take manual control of the tris, and it'll work.
Best Wishes |
|
|
theteaman
Joined: 04 Aug 2006 Posts: 98
|
|
Posted: Sun Jan 15, 2012 7:03 pm |
|
|
Thank you Ttelmah, it worked when I set the tris as you stated.
Just for anyones information, the code I used was:
Code: | void disableUART(void)
{
setup_uart(false);
set_tris_c(TRIS_C & 0b01111111);
}
void enableUART(void)
{
setup_uart(true);
set_tris_c(TRIS_C | 0b10000000);
} |
|
|
|
|