Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

C18 formatting strings for usart

Status
Not open for further replies.

mikesmixes777

New Member
Does anyone know of any routines that can convert, for example, a 'int' into a string for the usart to display correctly on a pc.

For example:

function( int number, char*output)


int total=256457;
char my_str=[20];

Int2Str(total, my_str)

So in other words, this will place the ASCII equivalent of "256457" into the string labelled my_str,which then canbe sent to the usart.

I came across this sort of function in the MikroC compiler but I am looking for somethig similar in the C18 MPLAB compiler.

There are various ones for Byte,Short,Word,Int,Long and Float.
 
You could write a function by yourself (take the reminder of the division by 10, divide by 10, and so on...) or use the data conversion fucntions provided with the compiler (btoa, itoa, etc.). They're described in the C18 libraries manual.
 
The family of printf functions are used to do just that. It is in the library manual.:)

MPLAB® C18 C COMPILER LIBRARIES

4.7 CHARACTER OUTPUT FUNCTIONS
The character output functions provide a central family of functions for processing
output to peripherals, memory buffers and other consumers of character data.
When processing a call to fprintf, printf, sprintf, vfprintf, vprintf or
vsprintf...
 
3v0 said:
The family of printf functions are used to do just that. It is in the library manual.:)

They're useful to send a string to a stream, but don't you convert the integer to a string first?
 
eng1 said:
They're useful to send a string to a stream, but don't you convert the integer to a string first?

printf is short for printformated.
One of the inputs to the function is the format string that tells how to format the other parms.


To print the ASCII string for 123 to stdout which you must have setup.

int x=123;
printf("%i", x);

The manual covers it in detail.
 
Well, as far as the printf thing is concerned, that's been an oversight on my part :eek: However, IIRC Mike is writing to the usart by loading the TXREG a byte at time. So it seems to me that using the data conversion functions and a for loop to send out data is perfectably suitable (that's basically what I do!).
 
Last edited:
eng1 said:
Well, as far as the printf thing is concerned, that's been an oversight on my part :eek: However, IIRC Mike is writing to the usart by loading the TXREG a byte at time. So it seems to me that using the data conversion functions and a for loop to send out data is perfectably suitable (that's basically what I do!).

Well :D , you can do it that way. However printf is setup to handle just that sort of thing. I have not used it much in the past few years so am not up to speed on which printf does what and what all the format parmaters are. However I do recall that you can write a putc routine that takes a char as the input parm and writes it to the device of your choice. If you use a pointer to that routine as the first printf parm it will call that function to send out the characters it formats. You can use printf with any device you can write a putc function for.

There is always a trade off between investing time in your own code or in understanding how to use provided libraries. In this case, printf is a standard and most programmers use it.
 
For my LCD routines I wrote a new printf... which is just a wrapper for the vprintf() library routine with the ability to address the LCD:
Code:
/********************************************************************
*       Function Name:  PrintfXLCD                                  *
*       Return Value:   new cursor postion                          *
*       Parameters:     cursor position, format string, params...   *
*       Description:    a wrapper function which calls vfprintf()   *
*                       with the address of the destination buffer  *
*                       as the output stream. EOF is returned on    *
*                       error, else the number of characters output.*
*                       Output stream is then sent to the Hitachi   *
*                       HD44780 LCD controller.                     *
********************************************************************/
int PrintfXLCD (char cursor, const rom char *f, ...)
{
  va_list ap;
  char buf[40];
  char *buf2;
  int n;

  // Make a copy of buf pointer to send to vfprintf
  buf2 = buf;

  // Grab the variable parameter list
  va_start (ap, f);

  // vfprintf writes to a buffer when file != -1 or -2
  n = vfprintf ((FILE *) &buf2, f, ap);

  // De-allocate the variable parameter list
  va_end (ap);

  // Null terminate the string
  buf[n] = '\0';

  // Move LCD Output Screen Pos
  while (BusyXLCD());
  SetDDRamAddr(cursor);

  // Write buffer
  while (BusyXLCD());
  putsXLCD(buf);
    
  return n;
} /* PrintfXLCD */
You can see from this how to use the vfprintf routine to write a string in ram. For output to the USART you can replace the guts of the while() loop with a test of the TX buffer empty flag and a write to the TXREG.

For those wanting to use the LCD version - please feel free to use this under the GPLv2 license. For commercial use please contact me.

P.
 
Last edited:
I tried the printf function...

Code:
char buf[20] = "Counter:           ";

counter++
printf(count, &buf[8]);

What is the prototype to include for the use of printf?
 
It is included....
I have;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

I get the following error;

59:Warning [2058] call of function without prototype
 
from stdio.h
Code:
int printf (auto const MEM_MODEL rom char *fmt, ...);

You are not calling printf with a format string as the first parameter. Which is of type char*

The first parm is a format string.

Maybe you were intending
Code:
int count = 0;
printf("Counter: %i", count);
It would output
Code:
Counter: 0

The are many web tutorials on how to use C's printf.
 
Ok I have the following function;

Code:
void usart_str( char b[])
{
	unsigned short i=0;
	
	while(b[i]!=0)
	{
		write_usart(b[i++]);
	}
}

When I do the following
Code:
char buf[] = {"Hello"};
usart_str(buf);
I get 'Hello' on the screen.

However when I call
Code:
usart_str("\rStarting\r");
Nothing happens...I get the error "56:Warning [2066] type qualifier mismatch in assignment"....

Any ideas why?
 
mikesmixes777 said:
Ok I have the following function;
Code:
void usart_str( char b[])
{
	unsigned short i=0;
	
	while(b[i]!=0)
	{
		write_usart(b[i++]);
	}
}
When I do the following
Code:
char buf[] = {"Hello"};
usart_str(buf);
I get 'Hello' on the screen.

However when I call
Code:
usart_str("\rStarting\r");
Nothing happens...I get the error "56:Warning [2066] type qualifier mismatch in assignment"....

Any ideas why?
Yep... the char buff[] is a RAM pointer to a char, and the = {"Hello"} tells the initialisation code to copy "Hello" from ROM space into RAM space for you. Your usart_str is (implictly) expecting a RAM pointer.

When you try usart_str("Hello") the compiler is putting "Hello" into ROM as it did for you previously, but is NOT doing the copy into RAM space. You would need to write a version of usart_str that took a (rom char *) pointer which read the ROM space char into a RAM variable to pass to write_usart()

Good to read both Section 5 of the Data Sheet, and section 2.4 of the C18 User's Guide.

P.
 
I see what you saying... I found this function
Code:
void putrsUSART(far rom char *data)
{
    do
    {  // Transmit a byte
        while(BusyUSART());

        write_usart(*data);

    } while( *data++ );
}

However I STILL get the error. Am I missing the point somewhere.
 
mikesmixes777 said:
I see what you saying... I found this function
Code:
void putrsUSART(far rom char *data)
{
    do
    {  // Transmit a byte
        while(BusyUSART());

        write_usart(*data);

    } while( *data++ );
}

However I STILL get the error. Am I missing the point somewhere.
Yep, the dereferenced *data is still a far rom char. Try:
Code:
void putrsUSART(far rom char *data)
{
    char c;
    do
    {  // Transmit a byte
        while(BusyUSART());
        c = *data; // copies it into RAM space
        write_usart(c);
    } while(*data++);
}
You *may* find that casting *data to char in the call works, write_usart((char)*data)... depends on the compiler implementation.

P.
 
Thanks Aussi, I tried the suggested code and it still gave the error...

These are my functions:

Code:
void write_usart(unsigned char data)			
{	
	TXREG = data;						

	while(busy_usart());	
}

and;

Code:
void putrs_usart(far rom char *data)
{
	char c;
	do
    {  // Transmit a byte
        while(busy_usart());
        c = *data;
        write_usart(c);

    } while( *data++ );
}

I am using MPLAB C18 compiler...
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top