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

Unpredictable printf behaviour

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



Joined: 09 Aug 2011
Posts: 6

View user's profile Send private message

Unpredictable printf behaviour
PostPosted: Fri Aug 26, 2011 1:45 am     Reply with quote

Hi, I am experiencing a strange problem with multiple rs232 ports. I am using compiler version PCH V4.104 with PIC18F6680. The device contains one hardware UART. I have configured the device to use the hardware UART as well as a software UART. In my application I use the SW UART for a debug output stream. As I understand the compiler manual, the last #USE RS232 defines the STDOUT stream, so I expect the printf and putc commands to print to the software UART. The simple program below demonstrates my problem:

Code:

#include <18F6680.h>
//------------------------------------------------------------------------------
// Pin configuration
//------------------------------------------------------------------------------
#define   PIN_TX            PIN_C0
#define   PIN_RX            PIN_C1
//------------------------------------------------------------------------------
// Configuration bits
//------------------------------------------------------------------------------
#pragma fuses HS         // Use external crystal as clock source
#pragma fuses NOWDT         // Disable watchdog timer
#pragma fuses NOPROTECT      // Don't read/write protect program memory
//------------------------------------------------------------------------------
// Compiler magic
//------------------------------------------------------------------------------

#pragma use delay(clock=8000000)

#pragma use rs232(UART1, BAUD=19200, BITS=8, STOP=1, PARITY=N, STREAM=HWSP)
#pragma use rs232(BAUD=19200, BITS=8, STOP=1, PARITY=N, XMIT=PIN_TX, RCV=PIN_RX, STREAM=SWSP)
#pragma use spi(BITS=8)

void main()

   // Setup SPI
   setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_XMIT_L_TO_H | SPI_CLK_DIV_4);
   
   // Print to the hardware UART
   fprintf(HWSP,"HW UART test\r\n");

   /* Lets try to print to the stdout (which should be the software UART,
   as it is the one last defined */   
   printf("SW UART test\r\n");     

   // Try to write directly to the software UART stream 
   fprintf(SWSP,"SW direct write\r\n");
   // Try again to write to STDOUT
   printf("Inderectly again\r\n");
   // Lets try to print some chars to STDOUT
   putc('a');
   putc('b');
   putc('c');
   
   // Loop forever
   while(1);
}


When I run this code I get the following output:

On the hardware UART:
Quote:

HW UART test
SW UART test
abc


On the software UART:
Quote:

SW direct write
Inderectly again


As far as I can see, the printf prints to the last stream used. Am I misunderstanding something, or is there a bug?

Best regards
Denis
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Fri Aug 26, 2011 3:58 am     Reply with quote

Yes, this is the classic 'bad CCS manual description' syndrome....

If you have multiple #USE RS232 statements _without stream names_, then the compiler assigns the name 'STDERR' to the first one, and STDOUT to the last. You can then use the last with the standard PRINTF functions, without using stream names.
However if you use stream names, the default disappears, and STDIO is attached to the last stream used.
So:
Code:

#use rs232(UART1, BAUD=19200, BITS=8, STOP=1, PARITY=N, STREAM=HWSP)
#use rs232(BAUD=19200, BITS=8, STOP=1, PARITY=N, XMIT=PIN_TX, RCV=PIN_RX)
#use spi(BITS=8)

#include <stdio.h>

void main()
{
   // Setup SPI
   setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_XMIT_L_TO_H | SPI_CLK_DIV_4);
   
   // Print to the hardware UART
   fprintf(HWSP,"HW UART test\r\n");
   fputc('\n',STDOUT); //switch streams to use.
   /* Lets try to print to the stdout (which should be the software UART,
   as it is the one last _used_ */   
   printf("SW UART test\r\n");     

   // Try to write directly to the software UART stream
   fprintf(STDOUT,"SW direct write\r\n");
   // Try again to write to STDOUT
   printf("Inderectly again\r\n");
   // Lets try to print some chars to STDOUT
   putc('a');
   putc('b');
   putc('c');
   
   // Loop forever
   while(1);
}


It is poor documentation...

Best Wishes
DeniTCH



Joined: 09 Aug 2011
Posts: 6

View user's profile Send private message

PostPosted: Fri Aug 26, 2011 6:24 am     Reply with quote

Thanks for the fast response! Well, this explains a lot. It does not help to manually assign the STDOUT nor STDIO stream name to the correct port. Is there a way to come around this without renaming all of the printf commands to fprintf or redefining the output stream every time?
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Fri Aug 26, 2011 8:38 am     Reply with quote

Just use #define.So:

Code:

#use rs232(UART1, BAUD=19200, BITS=8, STOP=1, PARITY=N, STREAM=HWSP)
#use rs232(BAUD=19200, BITS=8, STOP=1, PARITY=N, XMIT=PIN_TX, RCV=PIN_RX, STREAM=SWSP)
#use spi(BITS=8)

#define putc(x) fputc(x,SWSP)
#define printf(x) fprintf(SWSP,x)


Allows you to set the default to whatever stream you want.

Best Wishes
DeniTCH



Joined: 09 Aug 2011
Posts: 6

View user's profile Send private message

PostPosted: Mon Aug 29, 2011 2:28 am     Reply with quote

Elegant solution! I should have thought of that myself! Do you know if CCS supports __VA_ARG__ support in macros for full implementation of printf?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Aug 29, 2011 12:54 pm     Reply with quote

For CCS variable arguments support, look at these functions in the manual:
Quote:

va_arg()
nargs(),
va_end(),
va_start()

and this file:
Quote:

c:\program files\picc\drivers\stdarg.h
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