|
|
View previous topic :: View next topic |
Author |
Message |
fabien.casas
Joined: 28 Nov 2006 Posts: 6
|
SOLVED: problem with INT_RDA not being fired |
Posted: Thu Jan 11, 2007 12:15 pm |
|
|
Hi all,
I'm developing software for a 18F4550 with CCS v. 3.249, and I have a strange problem with the UART receive interrupt.
The built-in serial functions (putchar, getch, kbhit...) work fine, but my RDA ISR seems to never be called.
So I made a new project, starting from ex_SISR.c.
I changed the fuses and #use to match my hardware, and added a small (validated) snippet to blink a led at each received char:
Code: |
#include <18F4550.h>
#fuses HSPLL,CPUDIV1,PLL6,NOWDT,NOPROTECT,NOLVP,NODEBUG,VREGEN,USBDIV
#use delay(clock=48000000)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7)
#bit WATCHDOG_DISABLE = 0xF92.4
#bit GIE = 0xFF2.7
#bit PIE = 0xFF2.6
#bit RCIF = 0xF9E.5
#bit RCIE = 0xF9D.5
#byte RCSTA = 0xFAB
#byte TXSTA = 0xFAC
#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;
#int_rda
void serial_isr() {
int t;
// this blinks a LED :
static int1 b;
if (b) output_high (PIN_C0);
else output_low (PIN_C0);
b = ! b;
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out)
next_in=t; // Buffer full !!
}
#define bkbhit (next_in!=next_out)
BYTE bgetc() {
BYTE c;
while(!bkbhit) ;
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}
void main() {
WATCHDOG_DISABLE = TRUE;// external watchdog disabled
enable_interrupts(global);
enable_interrupts(int_rda);
if (PIE) printf("\nPIE\n");
if (RCIE) printf("\nRCIE\n");
printf ("\nRCSTA = 0x%X\n", RCSTA);
printf("\r\n\Running...\r\n");
// The program will delay for 10 seconds and then display
// any data that came in during the 10 second delay
do {
delay_ms(3000);
printf("\r\nBuffered data => ");
while(bkbhit)
putc( bgetc() );
} while (TRUE);
}
|
Here is what I get as an output:
Quote: |
PIE
RCIE
RCSTA = 0x00
Running...
azer
Buffered data =>
Buffered data =>"
|
-> (global interrupts,) peripheral interrupts and EUSART Receive Interrupt are enabled
-> the characters I sent to the PIC ("azer") are not transmitted back,
-> the LED (on RC0) is not blinking when I send characters to the PIC
-> PIC EUSART is disabled (RCSTA:SPEN = 0), despite #use rs232, and despite obvious serial communication...
Looking at the ASM code, I found this:
Code: |
...
004C: BTFSS F9D.5 // <- this checks if EUSART RX Int is unmasked
004E: GOTO 0058 // <- this goes to "return of ISR"
0052: BTFSC F9E.5 // <- this checks if EUSART RX Int flag is clear
0054: GOTO 01A6 // <- this branches to serial_isr
0058: ...
|
which seems rather ok to me, despite my poor ASM skills.
So here are my questions, at least:
- could someone please point out that obvious mistake I'm not seeing ?
- how does the "#use rs232" stuff bind to the hardware resources ?
- does the "#use rs232" stuff bind to the PIC's serial peripheral (like EUSART or MSSP) ?
Thanks for your help.
fab
Last edited by fabien.casas on Fri Jan 12, 2007 7:55 am; edited 1 time in total |
|
|
Ttelmah Guest
|
|
Posted: Thu Jan 11, 2007 1:09 pm |
|
|
I'd add a hardware buffer flush, before enabling the interrupts, and also add 'errors' to the RS232 statement. Something like:
Code: |
while (RCIF) getc();
|
What else shares with the serial on this chip?. Is it disabled? (SPI).
Best Wishes |
|
|
fabien.casas
Joined: 28 Nov 2006 Posts: 6
|
|
Posted: Fri Jan 12, 2007 3:37 am |
|
|
Thanks for your answer.
I've added the "errors" option, and flushed the buffer and the flag before enabling interrupts, as you suggested, but there's still no interrupt.
Yes, on 18F4550, the EUSART shares its Rx pin (RC7) with the SPI device (MSSP). The SPI uses it as the SDO line. My software doesn't use SPI, and I could check it is disabled.
I've set RC6 (Tx) as an output, and RC7 (Rx) as an input as suggested by the datasheet, before enabling interrupts, but still no luck.
By the way, I've looked at the ASM generated by the "kbhit" built-in function, and it seems that it checks the state of the Rx pin. I would have thought it checked the interrupt flag instead...
Is there something that can prevent the serial built-ins from using interrupts, other than the "DISABLE_INTS" option ?
fab |
|
|
Ttelmah Guest
|
|
Posted: Fri Jan 12, 2007 5:01 am |
|
|
If the code is checking the input bit, then a software UART is being used. Why?. Don't touch the TRIS registers yourself. The compiler does this for you, and it may be confusing it. Add 'bits=8' to the #use statement.
I have just coded a 'test' program as follows:
Code: |
#include <18F4450.h>
#device adc=8
#FUSES NOWDT, WDT128, HSPLL, CPUDIV, PLL5, NOPROTECT, BROWNOUT, BORV43, PUT, STVREN, BBSIZ2, NOLVP, NOWRT, LPT1OSC, IESO, FCMEN, PBADEN, NOWRTC, NOWRTB, NOEBTR, NOEBTRB, NOCPB, MCLR, NOXINST
#use delay(clock=48000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)
int1 have_data=false;
int8 chr;
#int_RDA
RDA_isr() {
chr=getc();
have_data=false;
}
void main() {
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
setup_low_volt_detect(FALSE);
setup_oscillator(False);
while (TRUE) {
if (have_data) {
putc(chr);
have_data=false;
}
}
}
|
This runs perfectly (I am using a 20Mhz clock), and is using the hardware UART:
Code: |
.................... #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)
009C: BTFSS F9E.5
009E: BRA 009C
00A0: MOVFF FAB,18
00A4: MOVFF FAE,01
00A8: BTFSS 18.1
00AA: BRA 00B0
00AC: BCF FAB.4
00AE: BSF FAB.4
00B0: NOP
00B2: GOTO 00B8 (RETURN)
|
Best Wishes |
|
|
fabien.casas
Joined: 28 Nov 2006 Posts: 6
|
|
Posted: Fri Jan 12, 2007 7:54 am |
|
|
That's it Ttelmah !
Quote: |
If the code is checking the input bit, then a software UART is being used.
|
I tried with just adding "bits=8" to the use_rs232 statement, but that was not enough, my code was still using a software uart.
The problem was that I didnot configure my device/source code properly, using the "device editor" tool ! The Rx and Tx pins in the "Edit Device" dialog box were not set.
With these set, the compiler generated code for REAL uart (and so my LED started to blink in an admirable way... ).
I guess there are settings that can't be set from user's code (I tried completing my #fuse list with your example, and it didn't work either). So I'll be more carefull next time.
Thanks a lot Ttelmah, you really helped me !
fab |
|
|
KaraMuraT
Joined: 16 May 2006 Posts: 65 Location: Ankara/Turkey
|
|
Posted: Wed Mar 14, 2007 1:22 am |
|
|
That topic is very similar with mine ( http://www.ccsinfo.com/forum/viewtopic.php?t=30003 )
I noticed the difference between the dissasambly listing of mine and Ttelmah's. Which may cause to use soft UART.
Code: | Mine: #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=CPORT,errors)
Ttelmah's: #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)
My Disassembly listing: TTelmah's
0E0E AA9E BTFSS 0xf9e, 0x5, ACCESS 009C: BTFSS F9E.5
0E10 D7FE BRA 0xe0e 009E: BRA 009C
0E12 CFAB MOVFF 0xfab, 0x18 00A0: MOVFF FAB,18
0E16 CFAE MOVFF 0xfae, 0x1 00A4: MOVFF FAE,01
0E1A A218 BTFSS 0x18, 0x1, ACCESS 00A8: BTFSS 18.1
0E1C D002 BRA 0xe22 00AA: BRA 00B0
0E1E 98AB BCF 0xfab, 0x4, ACCESS 00AC: BCF FAB.4
0E20 88AB BSF 0xfab, 0x4, ACCESS 00AE: BSF FAB.4
0E22 EF14 GOTO 0xe28 00B0: NOP
00B2: GOTO 00B8 (RETURN)
|
I think the diffrerence may caused by MPLAB & PCW diffrence but I think it can draw the picture.
So how can I make sure that HW EUSART is enabled?
PS: If I shrink the program with these settings, it responds every INT_RDA request. And can get every character properly. But the actual size causes just 1 character receive and that's it. You can not receive any additional character.
Same thing happens to EXT1 interrupt. it just can get only about %20 of the signals properly. I know both INT_RDA and INT_EXT1 interrupts are low priority, is it to key to trace the problems?
I appreciate any ideas. Thank you...
PIC: 18F4620
CCS: 4.023 & 3.212
IDE: MPLab 7.50 _________________ /// KMT
/// www.muratursavas.com |
|
|
KaraMuraT
Joined: 16 May 2006 Posts: 65 Location: Ankara/Turkey
|
|
Posted: Wed Mar 14, 2007 3:26 am |
|
|
It's obvious that this is a problem related with Internal oscillator. We already discussed it on an another thread. If I keep oscillator on the IDLE mode everthing works fine. But the cost is 1.5 mA and I can not effort it.
I have to think another solution for heads up on RS232 connection. _________________ /// KMT
/// www.muratursavas.com |
|
|
|
|
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
|