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

using PUTC on 2 serial ports

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



Joined: 30 Sep 2003
Posts: 89

View user's profile Send private message

using PUTC on 2 serial ports
PostPosted: Wed Mar 22, 2006 8:46 am     Reply with quote

I have 2 serial ports set up. Call them S1 and S2.

I put in the #use rs232(....) statements in with the one for S1 last as that is the one I use for printf statements. Unfortunately it automatically becomes the default port for PUTS.

I would like to use PUTS with port S2. How do I go about that, or can I?
_________________
-Pete
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Mar 22, 2006 8:49 am     Reply with quote

READ THE MANUAL! StReAmS! This comes up all the time. From the help file:
Quote:
Syntax:
puts (string). value = fputs (string, stream)



Parameters:
string is a constant string or a character array (null-terminated). Stream is a stream identifier (a constant byte)



Returns:
undefined



Function:
Sends each character in the string out the RS232 pin using PUTC(). After the string is sent a RETURN (13) and LINE-FEED (10) are sent. In general printf() is more useful than puts().



If fputs() is used then the specified stream is used where puts() defaults to STDOUT (the last USE RS232)



Availability:
All devices



Requires
#use rs232



Examples:
puts( " ----------- " );

puts( " | HI | " );

puts( " ----------- " );



Example Files:
None



Also See:
printf(), gets()


pfournier



Joined: 30 Sep 2003
Posts: 89

View user's profile Send private message

PostPosted: Wed Mar 22, 2006 9:38 am     Reply with quote

I've never used streams before. It is what I wanted, but I never made the connection like that before. (I didn't find it that obvious.) I hunted through the forum for somthing similar but I guess my search terms didn't make the right hit.

Unfortuately, it adds 5.5k to my code, which I cannot afford at this point. I will have to calculate parity on my own.

Thanks for pointing it out the connection.
_________________
-Pete
mpfj



Joined: 09 Sep 2003
Posts: 95
Location: UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Mar 23, 2006 4:45 am     Reply with quote

pfournier wrote:
Unfortuately, it adds 5.5k to my code, which I cannot afford at this point.

Which PIC are you using ? How many hardware serial ports does it have ?

The additional code may be due to your PIC only having a single "hardware" serial port, with the second serial port being iplemented as a "software" comms port. This requires extra code to be added.

I would think that using a second "hardware" (if available) would only add a tiny amount of code (for initialisation, etc), whereas using a "software" comms port requires all the code to bit-bang the data in and out.

It might be worth checking the listing file to see where / what the extra code is.
pfournier



Joined: 30 Sep 2003
Posts: 89

View user's profile Send private message

PostPosted: Thu Mar 23, 2006 7:19 am     Reply with quote

I'm using the PIC18LF8622. It has 2 hardware USARTS. I thought it sounded extereme as well. If I get time I'll do a comparison, in the mean time it was pretty simple to add parity myself. I thought maybe "STREAM" handling might have something to do with it.
_________________
-Pete
mpfj



Joined: 09 Sep 2003
Posts: 95
Location: UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Mar 23, 2006 7:38 am     Reply with quote

I've just compiled the following ...

Code:
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC                    //Internal RC Osc
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOIESO                   //Internal External Switch Over mode disabled
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES BORV25                   //Brownout reset at 2.5V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES NOSTVREN                 //Stack full/underflow will not cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#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 FCMEN                    //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=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=S1)
//#use rs232(baud=9600,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8,stream=S2)

void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF|ADC_TAD_MUL_0);
   setup_psp(PSP_DISABLED);
   setup_spi(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);
   setup_low_volt_detect(FALSE);
   setup_oscillator(False);
   
   fprintf(S1, "%s", "Hello");
   //fprintf(S2, "%s", "World");
}

Without the 2nd comms port, the code compiles to ...

Code:
CCS PCH C Compiler, Version 3.243, 32117               23-Mar-06 13:35

               Filename: C:\Documents and Settings\Mark\My Documents\123.lst

               ROM used: 166 bytes (0%)
                         Largest free fragment is 65370
               RAM used: 6 (0%) at main() level
                         6 (0%) worst case
               Stack:    1 locations

If I uncomment the 2nd comms port, the code compiles to ...

Code:
CCS PCH C Compiler, Version 3.243, 32117               23-Mar-06 13:37

               Filename: C:\Documents and Settings\Mark\My Documents\123.lst

               ROM used: 222 bytes (0%)
                         Largest free fragment is 65314
               RAM used: 6 (0%) at main() level
                         6 (0%) worst case
               Stack:    1 locations

So that's only 56 extra bytes !!
pfournier



Joined: 30 Sep 2003
Posts: 89

View user's profile Send private message

PostPosted: Thu Mar 23, 2006 7:43 am     Reply with quote

Hmmmmmm. Let me give it a quick retry.
_________________
-Pete
Ttelmah
Guest







PostPosted: Thu Mar 23, 2006 7:44 am     Reply with quote

No, Streams are not really 'handled', but are a flag to the compiler, to connect the associated I/O, to the selected code. I'd be triple checking that the #use statement, has the right I/O pins. The only addition, should be a few dozen bytes for the second serial handler.
How does the size change, if you leave the same print statements in place, but swap the stream declarations?. Remember that printing itself, does use a lot of code space, especially with the printf/fprintf statement...

Best Wishes
pfournier



Joined: 30 Sep 2003
Posts: 89

View user's profile Send private message

PostPosted: Thu Mar 23, 2006 8:01 am     Reply with quote

Here are the differences in my code. and the differences in size. I wonder if having the transmit in an interrupt is what is causing the issue. When I get time I may try it without the interrupt.

BTW: pins are correct



Code:
#use rs232(baud=ARINC_BAUD, xmit=PIN_G1, rcv=PIN_G2, ERRORS, parity=O, bits=8)
//#use rs232(stream=ARINC_STREAM, baud=ARINC_BAUD, xmit=PIN_G1, rcv=PIN_G2, ERRORS, parity=O, bits=8)


#INT_TBE2 //RS232 #2 send data interrupt
transmitChar_2()
   {
     while( (bit_test(pir3,4)) && (gunSerial_Out_Flag2!=2) )
       {
          //fputc( gcTx_Buffer2[gunTx_Next_Out2], ARINC_STREAM );
          txreg2=(gcTx_Buffer2[gunTx_Next_Out2]);
          gunTx_Next_Out2=(gunTx_Next_Out2+1)%TX_BUFFER_SIZE;
          if(gunTx_Next_In2==gunTx_Next_Out2)
            {
              disable_interrupts(INT_TBE2);
              gunSerial_Out_Flag2=2;
            }
       }
   }

CCS PCH C Compiler, Version 3.245, 27769 22-Mar-06 15:58

Filename: V:\CCDA-PS\Software\Main\ccda_ps_model_1.lst

ROM used: 60240 bytes (92%)
Largest free fragment is 5292
RAM used: 2060 (54%) at main() level
2141 (56%) worst case
Stack: 8 worst case (6 in main + 2 for interrupts)


*******************************************************************

Code:
//#use rs232(baud=ARINC_BAUD, xmit=PIN_G1, rcv=PIN_G2, ERRORS, parity=O, bits=8)
#use rs232(stream=ARINC_STREAM, baud=ARINC_BAUD, xmit=PIN_G1, rcv=PIN_G2, ERRORS, parity=O, bits=8)


#INT_TBE2 //RS232 #2 send data interrupt
transmitChar_2()
   {
     while( (bit_test(pir3,4)) && (gunSerial_Out_Flag2!=2) )
       {
          fputc( gcTx_Buffer2[gunTx_Next_Out2], ARINC_STREAM );
          //txreg2=(gcTx_Buffer2[gunTx_Next_Out2]);
          gunTx_Next_Out2=(gunTx_Next_Out2+1)%TX_BUFFER_SIZE;
          if(gunTx_Next_In2==gunTx_Next_Out2)
            {
              disable_interrupts(INT_TBE2);
              gunSerial_Out_Flag2=2;
            }
       }
   }

CCS PCH C Compiler, Version 3.245, 27769 23-Mar-06 08:53

Filename: V:\CCDA-PS\Software\Main\ccda_ps_model_1.lst

ROM used: 65482 bytes (100%)
Largest free fragment is 50
RAM used: 2060 (54%) at main() level
2141 (56%) worst case
Stack: 8 worst case (6 in main + 2 for interrupts)
_________________
-Pete
mpfj



Joined: 09 Sep 2003
Posts: 95
Location: UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Mar 23, 2006 8:26 am     Reply with quote

I've added an irq handler to my test code and use fputc() in the isr, but it's still a tiny amount of code used !!

I think you'll have to compare the listing files themselves and work out where the extra code usage is.
pfournier



Joined: 30 Sep 2003
Posts: 89

View user's profile Send private message

PostPosted: Thu Mar 23, 2006 9:35 am     Reply with quote

As you can probably tell my code is HUGE. I have a lot of waste right now but I need it in there for testing purposes.

I have started comparing list files. What I am finding is that code that has nothing to do with the THAT serial port is expanding for no obvious reason. As a "for instance" I have a printf statement (which uses the other serial port) with 113 instructions that grows to 136 instructions!

In fact EVERY printf instruction gets larger!!!!! I have NO idea why.

So that is why my code grew so large, every prinf statement got expanded for some reason.

Perhps I'll write a short program (maybe I'll use to one you provided), add some printfs and see what happens.
_________________
-Pete
Ttelmah
Guest







PostPosted: Thu Mar 23, 2006 9:54 am     Reply with quote

I'd suspect you are running into extra page switching.
Ufortunately, this is a 'classic' problem. If (for instance), adding just one extra variable, moves a variable that is in common use, into a bank, which is 'different' from the bank being used by other variables in the same part of the program, every data fetch in that part of the program, to/from that variable, changes from being a single word operation, to really involving three words (change bank, get/put byte, change bank back)...
This is why re-ordering variables, can have a massive effect on code size....

Best Wishes
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Thu Mar 23, 2006 9:59 am     Reply with quote

pfournier wrote:
As you can probably tell my code is HUGE. I have a lot of waste right now but I need it in there for testing purposes.

I have started comparing list files. What I am finding is that code that has nothing to do with the THAT serial port is expanding for no obvious reason. As a "for instance" I have a printf statement (which uses the other serial port) with 113 instructions that grows to 136 instructions!

In fact EVERY printf instruction gets larger!!!!! I have NO idea why.

So that is why my code grew so large, every prinf statement got expanded for some reason.

Perhps I'll write a short program (maybe I'll use to one you provided), add some printfs and see what happens.


Probably because its adding support for streams to each printf. If you are not using printf's on the 2nd serial stick with your other approach. You could also use sprintf to put the data into a string and then output that string to the proper port. This would save you quite a bit of code. If you are using many printf's, it might be better to write your own sprintf/printf function. I believe that CCS "inlines" the code so you program can grow quite large. If you make your own function, this function can be called multiple times thus saving valuable ROM space. Here's a link http://www.ccsinfo.com/forum/viewtopic.php?t=6703&highlight=sprintf where PCM noted some printf code. I have written a printf routine for the C18 but it probably wouldn't be much use since it uses variable arguments and pointers to constants (things CCS doesn't support).
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