1. 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.
    Dismiss Notice

C18 formatting strings for usart

Discussion in 'Microcontrollers' started by mikesmixes777, Jan 23, 2008.

  1. mikesmixes777

    mikesmixes777 New Member

    Joined:
    Nov 21, 2007
    Messages:
    58
    Likes:
    0
    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.
     
  2. eng1

    eng1 New Member

    Joined:
    Apr 7, 2006
    Messages:
    951
    Likes:
    19
    Location:
    Italy
    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.
     
  3. mikesmixes777

    mikesmixes777 New Member

    Joined:
    Nov 21, 2007
    Messages:
    58
    Likes:
    0
    the data conversion functions were what I was looking for. :) thanks eng1
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. 3v0

    3v0 Coop Build Coordinator Forum Supporter

    Joined:
    Jul 14, 2006
    Messages:
    9,404
    Likes:
    227
    Location:
    OKLAHOMA USA

    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...
     
  6. eng1

    eng1 New Member

    Joined:
    Apr 7, 2006
    Messages:
    951
    Likes:
    19
    Location:
    Italy
    They're useful to send a string to a stream, but don't you convert the integer to a string first?
     
  7. 3v0

    3v0 Coop Build Coordinator Forum Supporter

    Joined:
    Jul 14, 2006
    Messages:
    9,404
    Likes:
    227
    Location:
    OKLAHOMA USA
    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.

    The manual covers it in detail.
     
  8. eng1

    eng1 New Member

    Joined:
    Apr 7, 2006
    Messages:
    951
    Likes:
    19
    Location:
    Italy
    Thank you for reminding me of that, 3v0! :)
     
  9. 3v0

    3v0 Coop Build Coordinator Forum Supporter

    Joined:
    Jul 14, 2006
    Messages:
    9,404
    Likes:
    227
    Location:
    OKLAHOMA USA
    That is one of the things I like about this forum. One can show up with a question you should know the answer to and not get beat up for it.
     
  10. eng1

    eng1 New Member

    Joined:
    Apr 7, 2006
    Messages:
    951
    Likes:
    19
    Location:
    Italy
    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: Jan 23, 2008
  11. 3v0

    3v0 Coop Build Coordinator Forum Supporter

    Joined:
    Jul 14, 2006
    Messages:
    9,404
    Likes:
    227
    Location:
    OKLAHOMA USA
    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.
     
  12. aussiepoof

    aussiepoof New Member

    Joined:
    Dec 16, 2006
    Messages:
    114
    Likes:
    4
    Location:
    Western Australia
    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 (text):

    /********************************************************************
    *       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: Jan 23, 2008
  13. mikesmixes777

    mikesmixes777 New Member

    Joined:
    Nov 21, 2007
    Messages:
    58
    Likes:
    0
    I tried the printf function...

    Code (text):


    char buf[20] = "Counter:           ";

    counter++
    printf(count, &buf[8]);
     
    What is the prototype to include for the use of printf?
     
  14. 3v0

    3v0 Coop Build Coordinator Forum Supporter

    Joined:
    Jul 14, 2006
    Messages:
    9,404
    Likes:
    227
    Location:
    OKLAHOMA USA
    Check the library manual.

    It should be part of an include file.
    Have you trieded #include <stdio.h>
     
  15. mikesmixes777

    mikesmixes777 New Member

    Joined:
    Nov 21, 2007
    Messages:
    58
    Likes:
    0
    It is included....
    I have;

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

    I get the following error;

     
  16. 3v0

    3v0 Coop Build Coordinator Forum Supporter

    Joined:
    Jul 14, 2006
    Messages:
    9,404
    Likes:
    227
    Location:
    OKLAHOMA USA
    from stdio.h
    Code (text):
    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 (text):
    int count = 0;
    printf("Counter: %i", count);
    It would output
    Code (text):
    Counter: 0
    The are many web tutorials on how to use C's printf.
     
  17. mikesmixes777

    mikesmixes777 New Member

    Joined:
    Nov 21, 2007
    Messages:
    58
    Likes:
    0
    Ok I have the following function;

    Code (text):
    void usart_str( char b[])
    {
        unsigned short i=0;
       
        while(b[i]!=0)
        {
            write_usart(b[i++]);
        }
    }
    When I do the following
    Code (text):
    char buf[] = {"Hello"};
    usart_str(buf);
    I get 'Hello' on the screen.

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

    Any ideas why?
     
  18. aussiepoof

    aussiepoof New Member

    Joined:
    Dec 16, 2006
    Messages:
    114
    Likes:
    4
    Location:
    Western Australia
    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.
     
  19. mikesmixes777

    mikesmixes777 New Member

    Joined:
    Nov 21, 2007
    Messages:
    58
    Likes:
    0
    I see what you saying... I found this function
    Code (text):
    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.
     
  20. aussiepoof

    aussiepoof New Member

    Joined:
    Dec 16, 2006
    Messages:
    114
    Likes:
    4
    Location:
    Western Australia
    Yep, the dereferenced *data is still a far rom char. Try:
    Code (text):
    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.
     
  21. mikesmixes777

    mikesmixes777 New Member

    Joined:
    Nov 21, 2007
    Messages:
    58
    Likes:
    0
    Thanks Aussi, I tried the suggested code and it still gave the error...

    These are my functions:

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

        while(busy_usart());   
    }
     
    and;

    Code (text):
    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...
     

Share This Page