CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

18f8722 two serial ports Problems

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
surfer0815



Joined: 10 Sep 2010
Posts: 7
Location: Germany

View user's profile Send private message

18f8722 two serial ports Problems
PostPosted: Sat Jan 08, 2011 4:57 am     Reply with quote

Hi!
I tried it now for a few days, to get serial com working on 18f8722, so now I hope someone here could give me the tricky bit I have to set for a working pic.

If I compile this code, I can see on both serial Ports on PC the 2 different messages on startup, but Interrupt is not working.

I send a charachter from PC to PIC (on both Ports the same) and nothing happens.

Normaly I should get the "fire-1" or "fire-2" Message, if Interrupt occured, but nothing hapens.

My Compiler Version is 4.110

Hope there is someone who had same Problems an got it out?

//#####8722-serial-test.h###########
#include <18F8722.h>
#device adc=8

#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed osc with HW enabled 4X PLL
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES noLVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES noFCMEN //Fail-safe clock monitor enabled
//#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES MCU //Microcontroller Mode

#use delay(clock=10000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS,stream=uart1)
#use rs232(baud=9600,parity=N,xmit=PIN_g1,rcv=PIN_g2,bits=8,errors,stream=uart2)

#define led pin_f0

//#######8722-serial-test.c############
#include "8722-serial-test.h"

short int int_=0,int2_=0;

#int_RDA
void RDA_isr()
{
int_=1;
}

#int_RDA2
void RDA2_isr()
{
int2_=1;
}

void main()
{
port_b_pullups(TRUE);
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_spi2(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_timer_4(T4_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
//enable_interrupts(INT_RDA);
enable_interrupts(INT_RDA2);
enable_interrupts(GLOBAL);
setup_low_volt_detect(FALSE);
setup_oscillator(False);

output_high(led);delay_ms(500);output_low(led);delay_ms(500);output_high(led);delay_ms(500);output_low(led);

fprintf(uart1,"here i am uart1");
fprintf(uart2,"here i am uart2");

while(1){
If (int_==1){
disable_interrupts(INT_RDA);
output_toggle(led);
fprintf(uart1,"fire-1");
int_=0;
enable_interrupts(INT_RDA);
}
If (int2_==1){
disable_interrupts(INT_RDA2);
output_toggle(led);
fprintf(uart2,"fire-2");
int2_=0;
enable_interrupts(INT_RDA2);
}


}
}
surfer0815



Joined: 10 Sep 2010
Posts: 7
Location: Germany

View user's profile Send private message

PostPosted: Sat Jan 08, 2011 6:11 am     Reply with quote

Ok, I tried a few things more and here is what i got:

If I put this to one of the ISR Routines: fprintf(uart1,"int occured");
I send a char to the pic, and then I see an endless output off "int occuredint occuredint occured....."

So the Problem seems to be, that the Pic never gets out of the ISR again, but why?

Does CCS not clear the Interrupt Flag bit by itself, so a new interrupt can occur?
drh



Joined: 12 Jul 2004
Posts: 192
Location: Hemet, California USA

View user's profile Send private message

PostPosted: Sat Jan 08, 2011 7:07 am     Reply with quote

You need to read the RCREG in the isr to clear the RX interrupt flag.
_________________
David
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Sat Jan 08, 2011 7:38 am     Reply with quote

drh wrote:
You need to read the RCREG in the isr to clear the RX interrupt flag.


I don't think that's true, even though the symptoms he describes may indicate otherwise. I believe the compiler handles clearing the interrupt bit automatically in the ISR call.


Surfer, try this and see what happens. Try to post the actual code that you are using at the time of the problem and use the 'code' feature in the forum.

Code:
//#####8722-serial-test.h###########
#include <18F8722.h>
#device adc=8

#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed osc with HW enabled 4X PLL
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES noLVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES noFCMEN //Fail-safe clock monitor enabled
//#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES MCU //Microcontroller Mode

#use delay(clock=10000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS,STREAM=uart1)
#use rs232(baud=9600,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8,ERRORS,STREAM=uart2)

#define led pin_f0

//#######8722-serial-test.c############
#include "8722-serial-test.h"

short int int_=0,int2_=0;

#int_RDA
void RDA_isr()
{
int_=1;
}

#int_RDA2
void RDA2_isr()
{
int2_=1;
}

void main()
{
   port_b_pullups(TRUE);
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF|ADC_TAD_MUL_0);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_spi2(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_timer_4(T4_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_RDA);
   enable_interrupts(INT_RDA2);
   enable_interrupts(GLOBAL);
   setup_low_volt_detect(FALSE);
   setup_oscillator(False);
   
   output_high(led);     
   delay_ms(500);
   output_low(led);
   delay_ms(500);
   output_high(led);
   delay_ms(500);
   output_low(led);
   
   fprintf(uart1,"here i am uart1\n\r");
   fprintf(uart2,"here i am uart2\n\r");
   
   while(1)
   {
      If (int_==1)
      {
         output_toggle(led);
         fprintf(uart1,"fire-1\n\r");
         int_=0;
      }
      If (int2_==1)
      {
         output_toggle(led);
         fprintf(uart2,"fire-2\n\r");
         int2_=0;
      }
   }
}


I didn't actually try to compile this, so there might need to be some minor corrections.

Report back with the results. Try only sending one character to the first UART and see what happens. Then try sending just one character to the second UART and see what happens. Then try sending one character to both.

Also, describe your hardware. Are you using a RS232 level converter? Do you have pullups on the RX pins? Is this a production development board?
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Sat Jan 08, 2011 7:58 am     Reply with quote

jecottrell wrote:
drh wrote:
You need to read the RCREG in the isr to clear the RX interrupt flag.


I don't think that's true, even though the symptoms he describes may indicate otherwise. I believe the compiler handles clearing the interrupt bit automatically in the ISR call.

It is true.

You cannot clear the interrupt flag, _without_ first reading the character. If a character is still present in the input buffer, the flag will immediately set itself again, and the interrupt handler will be called again.
The compiler _attempts_ to clear the flag, but unless the hardware condition is cleared, it won't work.

On the following interrupts, you _must_ clear the hardware condition in the handler:
INT_RDA (and RDA2). Must read the character.
INT_TBE (you need to load a character, or disable the interrupt).
INT_RB (need to read port B).

and several more when you get into things like Can bus, USB etc..

Best Wishes
surfer0815



Joined: 10 Sep 2010
Posts: 7
Location: Germany

View user's profile Send private message

PostPosted: Sat Jan 08, 2011 8:07 am     Reply with quote

David (drh):

Thats it! Thanks a lot!
If i read the rcreg1 in isr1 and rcreg2 in isr2, the code WORKS!!!!

jecottrell:

I tried out your posted code, but same issue as my own code, if i send one char, programm hangs in isr.

But if i clear rcreg1 and rcreg2, your code is working and putting chars out!

For now I just worked with one single serial port, and didnĀ“t had this Problems, could it be a compiler bug?

Thanks for your help guys!
surfer0815



Joined: 10 Sep 2010
Posts: 7
Location: Germany

View user's profile Send private message

PostPosted: Sat Jan 08, 2011 8:13 am     Reply with quote

Ttelmah:

You are right, that the incoming char, has to be read in the isr itself, otherwise rcreg is not cleared and the isr loops endless times!

Now I put a simple buf=fgetc(ua1); to the isr and rcreg is cleared automatically!
jecottrell



Joined: 16 Jan 2005
Posts: 559
Location: Tucson, AZ

View user's profile Send private message

PostPosted: Sat Jan 08, 2011 8:38 am     Reply with quote

Excellent.

That's interesting to know, it's not the ISR that clears the interrupt, its reading the character.

Are there any other Interrupts that are like that, merely calling the ISR doesn't clear the INT bit?

Thanks.
Ttelmah



Joined: 11 Mar 2010
Posts: 19537

View user's profile Send private message

PostPosted: Sat Jan 08, 2011 9:21 am     Reply with quote

jecottrell wrote:
Excellent.

That's interesting to know, it's not the ISR that clears the interrupt, its reading the character.

Are there any other Interrupts that are like that, merely calling the ISR doesn't clear the INT bit?

Thanks.

It is worth looking at the data sheet for RBIF.

"This interrupt can wake the device from SLEEP. The user in the Interrupt Service Routine, can clear the interrupt in the following manner:
a) Any read or write of PORTB (except with the MOVFF instruction). This will end the mismatch condition.
b) Clear flag bit RBIF.
A mismatch condition will continue to set flag bit RBIF. Reading PORTB will end the mismatch condition, and allow flag bit RBIF to be cleared."

Note the critical thing. You can 'clear' RBIF, but it will set again immediately, if the 'mismatch' is still there.

This applies to _all_ interrupts reflecting a 'hardware' condition. You can't exit the I2C interrupt, unless you update the I2C buffer (writing or reading). Serial transmit can't be left, unless you load a character to send (or disable the interrupt). The USB serial receive code must read the data. If (on a DS PIC), you program an interrupt to be 'level' triggered, you can't leave, till either the line changes state again, or you reverse the 'sense' of the interrupt. etc. etc.. There are more interrupts that behave this way, than don't.....

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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