View previous topic :: View next topic |
Author |
Message |
SQR-1
Joined: 28 Mar 2019 Posts: 10
|
RDA2 interruption |
Posted: Thu Mar 28, 2019 11:41 am |
|
|
Good morning ... can you help me with a problem?
I have a PIC18F67K40, I can send from the PIC but can not receive since the interruption does not work. I wrote a very short program to try but it does not work.
What could be happening?
This is the program:
Code: |
#include <18F67K40.h>
#FUSES NOWDT //No Watch Dog Timer
#use delay(crystal=20000000)
#use FIXED_IO( E_outputs=PIN_E1,PIN_E0 )
#use rs232(baud=9600,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8,stream=PORT1,restart_wdt)
#INT_RDA2
void RDA2_isr(void)
{
printf(" Hola Universo. ");
}
void main()
{
enable_interrupts(INT_TBE2);
enable_interrupts(INT_RDA);
enable_interrupts(INT_RDA2);
enable_interrupts(GLOBAL);
printf(" Hola mundo. ");
while(TRUE)
{
printf(" Sending... ");
delay_ms(2000);
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Thu Mar 28, 2019 12:09 pm |
|
|
You should always have "errors" in your #use rs232 macro declaration or else it will lock up once the receive buffer fills up.
Besides that, I am not sure that you have set your TX up properly. From the datasheet, it looks like TX2 is remappable. Therefore, you should have a #pin_select before your #use rs232 macro to tell it.
Something like:
Code: | #pin_select TX2=PIN_G1 |
And instead of saying xmit = ..., rcv = ..., you can now just say
#use Code: | rs232(baud=9600,parity=N,UART2,bits=8,stream=PORT1,restart_wdt,errors) |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19382
|
|
Posted: Thu Mar 28, 2019 12:28 pm |
|
|
Yes. dluu13 is right. Currently you are setting up a software UART on
pins G1 & G2, so no hardware interrupt.
PPS devices _must_ be setup with #pin select, before you use them. |
|
![](templates/subSilver/images/spacer.gif) |
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Thu Mar 28, 2019 12:40 pm |
|
|
Another thing, you have enabled some interrupts that you did not make ISR for. This can cause you to get resets (at least I have gotten some ugly resets that way) |
|
![](templates/subSilver/images/spacer.gif) |
SQR-1
Joined: 28 Mar 2019 Posts: 10
|
|
Posted: Thu Mar 28, 2019 12:47 pm |
|
|
Thanks for the reply ... but it does not work ... if insert #pin_select TX2 = PIN_G1 does not receive or send.
With this reduced code it sends correctly but does not activate the interruption.
Code: |
#include <18F67K40.h>
#FUSES NOWDT //No Watch Dog Timer
#use delay(crystal=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8)
#INT_RDA2
void RDA2_isr(void)
{ printf(" Hola Mundo. "); }
void main()
{
enable_interrupts(INT_RDA2);
enable_interrupts(GLOBAL);
while(TRUE)
{ printf(" Sending... "); delay_ms(2000); }
} |
It also tells me a warning to the build:
Compiling D:\Usuario\Desktop\Comunicacion-RS2332\Comunicacion_RS2332_03 on 28-mar.-19 at 19:45
>>> Warning 216 "Comunicacion_RS2332_03.c" Line 17(1,2): Interrupts disabled during call to prevent re-entrancy: (@PSTRINGC_957)
Memory usage: ROM=0% RAM=1% - 1%
0 Errors, 1 Warnings.
Build Successful. |
|
![](templates/subSilver/images/spacer.gif) |
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Thu Mar 28, 2019 1:08 pm |
|
|
I can't really see why it's not working to send if you have pin_select, but you still have not put "errors" in your #use rs232 declaration.
For reference, here's a snippet of me setting up RS232 in one of my projects:
Code: | #pin_select U2TX=RS232_TX
#pin_select U2RX=RS232_RX
#define PC U2STREAM
#USE RS232(BAUD=115200, UART2, BITS=8, PARITY=N, STOP=1, STREAM=PC, ERRORS, RECEIVE_BUFFER=128) |
The RECEIVE_BUFFER tells the compiler to automatically setup a #int_rda2 for me that fetches the chars in the receive buffer.
The ERRORS tells the compiler to automatically reset errors when they occur.
I set it up with UART2 instead of XMIT=... and RCV=... to use the hardware. It may be that if you use XMIT and RCV, then the compiler will make a software UART instead of hardware. If you are not using a hardware UART then there is no way you will get an interrupt.
Also, I think you are getting the warning because you are using printf inside the ISR. In general, it's not a good idea to sit within the ISR doing something slow like printf. Much better to set a flag, and then service the flag to do the printf inside your main loop. |
|
![](templates/subSilver/images/spacer.gif) |
SQR-1
Joined: 28 Mar 2019 Posts: 10
|
|
Posted: Thu Mar 28, 2019 1:20 pm |
|
|
Thank you, thank you, thank you ... following your instructions, it works perfectly for me ... it's nice to see data in port !!!
Today I can sleep happily ... ;-)
Thank you |
|
![](templates/subSilver/images/spacer.gif) |
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Thu Mar 28, 2019 1:21 pm |
|
|
Good to hear. Have a nice sleep :D |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19382
|
|
Posted: Thu Mar 28, 2019 1:59 pm |
|
|
Yes, you always have to setup both pins, and preferably use the 'UARTx'
syntax to force the hardware UART to be used. You can use just one
pin, but you do this by enabling both, and then turning part of the UART
off afterwards.
Glad you have it working. ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
SQR-1
Joined: 28 Mar 2019 Posts: 10
|
Interruption does not work |
Posted: Mon May 06, 2019 6:03 am |
|
|
Good morning companions, again I have problems with the serial communications, specifically with the interruptions ... I can send data well but does not activate the interruption of input data. I put a led inside the interruption to turn on and off a led every time data arrive but I do not observe positive results ... what am I doing wrong?
Thank you.
////////////////////////////////////////////////////////
#pin_select U2TX = PIN_G1
#pin_select U2RX = pin_G2
#define PC U2STREAM
#USE RS232 (BAUD = 115200, UART2, BITS = 8, PARITY = N, STOP = 1, STREAM = PC, ERRORS, RECEIVE_BUFFER = 128)
///////////////////////////////////////////
#INT_RDA2
void SerialDataReceive(void)
{
output_toggle(ALERT);
delay_ms(100);
}
#INT_TIMER0
void RTCC_isr(void)
{
//RESTART_WDT();
runing();
}
////////////////////////////////////////////////
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8|RTCC_8_BIT); //409 us overflow
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //13,1 ms overflow
set_analog_pins(PIN_A0,PIN_A1,PIN_A2);
setup_adc(ADC_CLOCK_INTERNAL);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4);
setup_timer_2(T2_DIV_BY_16, 50, 1);
//setup_wdt(WDT_1MS);
enable_interrupts(INT_TIMER2);
disable_interrupts(INT_TIMER1);
enable_interrupts(INT_TIMER0);
enable_interrupts(int_rda2); //InterrupciĆ³n Puertos serie
enable_interrupts(GLOBAL);
delay_ms(500);
enable_interrupts(int_ext);
ext_int_edge(0,H_TO_L);
enable_interrupts(int_ext1);
ext_int_edge(1,H_TO_L);
enable_interrupts(int_ext2);
ext_int_edge(2,H_TO_L);
valores_iniciales();
restaurar_reles();
lcd_backlight=ON;
lcd_init();
...
...
... |
|
![](templates/subSilver/images/spacer.gif) |
dluu13
Joined: 28 Sep 2018 Posts: 395 Location: Toronto, ON
|
|
Posted: Mon May 06, 2019 6:33 am |
|
|
You have added receive_buffer in your rs232 setup options. It may be that the automatically generated ISR that CCS makes when you specify that option will override whatever ISR you write yourself. The receive_buffer automatically generates an ISR that places the received character into a circular buffer, which you use functions like getc() to access. kbhit() will return 1 when there is something in the buffer.
You should spend some time reading the manual in the rs232 section, along with kbhit and other functions related to receive buffer.
Alternatively, you can remove the receive_buffer in your setup options to use your own isr. |
|
![](templates/subSilver/images/spacer.gif) |
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Mon May 06, 2019 6:58 am |
|
|
Hi,
You need to actually 'get' a character inside to the serial interrupt handler in order to clear the interrupt.
Code: | #INT_RDA2
void SerialDataReceive(void)
{
unsigned int8 Temp;
Temp = fgetc(PC); <----------- Required!!!
output_toggle(ALERT);
delay_ms(100);
}
|
_________________ John
If it's worth doing, it's worth doing in real hardware! |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9177 Location: Greensville,Ontario
|
|
Posted: Mon May 06, 2019 7:50 am |
|
|
this...
inside any ISR is BAD to do !!!!
ISR code ( handler) NEEDS to be short and fast.
NO printing,
NO delays,
NO floating point math...
No polling...
Jay |
|
![](templates/subSilver/images/spacer.gif) |
SQR-1
Joined: 28 Mar 2019 Posts: 10
|
|
Posted: Mon May 06, 2019 7:54 am |
|
|
I do not understand what happens ... if I send, lose characters nothing happens but if you keep pressing a key (from hyperterminal) after a couple of seconds the interruption breaks ... but it seems a random case ... |
|
![](templates/subSilver/images/spacer.gif) |
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Mon May 06, 2019 9:46 am |
|
|
Hi,
Post a complete test program that shows the issue. Make it so that we can cut, paste and compile.
Post your code using the <code> tags.
Tell us how you are testing your program. What hardware are you using? _________________ John
If it's worth doing, it's worth doing in real hardware! |
|
![](templates/subSilver/images/spacer.gif) |
|