Conversion Problem to hyperterminal

Go To Last Post
20 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

i am programming my microcontroller to retrieve temperature value from DS18B20 which works pretty well. Since i didnt want to be bothered by the type conversion. So throughout the code i used this code taken from

 #include 

    static int uart_putchar(char c, FILE *stream);

    static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,
                                             _FDEV_SETUP_WRITE);

    static int
    uart_putchar(char c, FILE *stream)
    {

      if (c == '\n')
        uart_putchar('\r', stream);
      loop_until_bit_is_set(UCSRA, UDRE);
      UDR = c;
      return 0;
    }

    int
    main(void)
    {
      init_uart();
      stdout = &mystdout;
      printf("Hello, world!\n");

      return 0;
    }

http://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html

so when i want to output it on my hyperterminal, i'll just simply use fprintf(stdout,"HOORAY");

the next step, i would like to remove the usage of fdev and use only simple uart_put and uart_get as being taught in abcminiuser's tutorial.

i normally will use ultoa(value,buffer[20], radix) to convert the data then uart_put(buffer); and it works.

Problem now is that i'm receiving a hex data and ultoa() does not work anymore, i keep on receiving error:
warning:pointer targets in passing argument 2 of 'ultoa' difer in signedness.

how do i rectify this problem. Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The second parameter to ultoa() needs to be and address of an array of characters in memory. I guess you either meant:

ultoa(value, &buffer[20], radix);

if you really meant to write from the 20th element of the array onwards or perhaps you simply meant:

char buffer[20];
ultoa(value, buffer, radix);

to define the 20 element array and then write from the 0th element onwards?

In either case this make parameter 2 of the function a pointer to char.

Having said all that I see that the warning is simply about "signedness". This may simply be because there are actually three types of "char" which are "signed char", "unsigned char" and finally "char" which is neither signed nor unsigned (your "HOORAY" falls into the latter category). If you want to quell the warning then just typecast the parameter.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks for the fast reply, quite obvious that i'm not good in programming :D So i'm referring to your second case, write from 0th element onwards.

So what do you mean with typecast? defining the type of variable? i did some talking with my supervisor and he said that i could pass my hex value directly into my uart_puts()

void uart_puts(const char *s )
{
    while (*s) 
      uart_putc(*s++);

}

So i'm receiving a value of the ID of the DS18B20 lets say

unsigned char id[8]

...//from DS18B20
uart_puts("ID: " );
for( i = 0; i < 8; i++ ){
uart_puts(id[i]);
}
He said it is most probably due to 'termination' problem. Can you direct me in this case? i guess i need to modify my uart_puts() to test terminator \0 ??

void uart_putc(unsigned char data)
{
	while ( !( UCSR0A & (1<<UDRE0) ) );

	UDR0 = data;

}

and by doing this i receive another new error:

warning: passing argument 1 of 'uart_puts' makes pointer from integer without a cast

thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

uart_puts is for sending a null terminated string. To send the data character by character (i.e.id[i]), you should use uart_putc.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

good point, i'd changed it to uart_putc() and now i'm recceving stuff non comprehended symbols. maybe i do need to do conversion?

i received 'ID: (

after some beginner's try and error method, i got it.

actually i should have just define my buffer as char instead of unsigned char -> that is the signedness problem.

char s[20]
        .......
	ultoa(id[i], s, 16);
	uart_puts(s);

it is now showing the correct output. So one more question, how do i specify that my output must consist of 2 digits??

Last Edited: Wed. Jul 15, 2009 - 03:47 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just going back to the signedness error:

void uart_puts(const char *s )

is a routine expecting a pointer to constant char (neither signed nor unsigned). But you then invoke it with:

unsigned char id[8];

uart_puts(id[i]);

your first error in that has already been pointed out but even if you'd used:

uart_puts(id);

you'd STILL get a warning as id[] is both "unsigned" and it's not "const"

Try to ensure your parameters are passed as the type that a routine expects or, if you know you are deliberately passing something of the wrong type then quell the warning and make it clear to the later reader of your code by including a deliberate typecast:

uart_puts((const char *)id);

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

cliff, thanks for your help, i went back and rectify my signedness problem and it works, apparaently i was writing my message same time as u did. Thanks for the help.
So one more question, how do i specify that my output must consist of 2 digits?? :D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not sure I understand your question - how do you specify to what that there's a 2 character limit? If you mean how can you ensure that the output of the ultoa() is no more than two digits then various ways:

if (id[i] < 100) {
 ultoa(...) etc...
}
else {
 // it ain't gonna fit in 2 digits
}

or let the conversion continue them simply truncate 's' with:

s[2] = 0;

but if the input was 1234 then this would result in s[] containing "12" which may not be what you wanted?

Cliff

BTW, if the range is 0..99 why use unsigned longs in the first place? Even a 'char' can hold up to 255.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hmm, i'm a beginner in this conversion stuff, so ultoa works well for me so far. If there's a better way, please teach me :D

what i meant is like this;
lets say my output should be '01', but by doing

ultoa(id[i], s, 16);
   uart_puts(s);

My output on the screen shows only '1'.
i used to do this

fprintf(stdout,"%02X ", id[i] );

and this will show '01' on my screen.
Hope you get the idea :D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
    static int
    uart_putchar(char c, FILE *stream)

While this is perfectly legal, I know of no one who splits up a function definition this way. The convention is to put it in one line. Though if there are many parameters, then you will often see those on separate lines. But never the return value.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I know of no one who splits up a function definition this way

You do you know ;-)

Our coding standard specifies this with the template layout:

function_type
function_name(
  arg1type arg1,       /* Out Description of arg1 */
  arg2type arg2,       /* I/O Description of arg2 */
  const arg3type *arg3 /* In Description of arg3 this is */
                       /* the third argument. */
) {
  local local1;
  local local2;
  etc.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

My output on the screen shows only '1'.
i used to do this
Code:
fprintf(stdout,"%02X ", id[i] );
and this will show '01' on my screen.

This is the price you pay for using the "tighter" ultoa() rather than (f/s)printf(). printf() gives you far more options for layout specification - but this is exactly the reason it also "costs" more flash space. Unless you have a space constrained AVR just use printf(). Otherwise you'll have to write your own zero padding routine. In fact, in this case, as you only have 1 or 2 digits it could be as simple as:

if (strlen(s) == 1) {
 s[1] = s[0];
 s[0] = '0';
 s[2] = 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Our coding standard specifies this with the template layout:

Sounds like a stupid idea to me. But, hey, that's what standards are for--to pad the dev hours to reformat perfectly good source code to meet ever-changing political correctness; to pad the QA hours to review, track, reject, approve the formatting of any change; to make it harder for normal people to read.

[where is that smiley for "tongue-in-cheek"? In practice, my team of one rigidly enforces coding style. I just change hats...]

Quote:
how do i specify that my output must consist of 2 digits??

Anyway, we all beat this to death recently. Search forum message titles for "bcd". In https://www.avrfreaks.net/index.p... I posted my right-justify-with-optional-leading-zero-supression routine. There are other approaches that are somewhat smaller/faster.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

to pad the dev hours to reformat

Not if you always write it that way in the first place ;-).

Some of our build systems include a layout checker that confirms that the code is correctly laid out before it even gets passed to lint and only when it's then passed that does it get passed to the C compiler.

I have to admit that while I write to our standard when doing it "for real" (it's simply so that everyone's code "reads" the same and looks familiar which aids understanding) for code examples here, to save lines in [code] I do it the way everyone else does with the return type and usually all the functions parameters on the same line.

It probably would bug most folks here that I also use (again because out standard dictates it) 1TBS:

http://en.wikipedia.org/wiki/Ind...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

It probably would bug most folks here that I also use (again because out standard dictates it) 1TBS:

As a read of that article (and a recent discussion of it here on 'Freaks) indicates: 1TBS is wrong; simply wrong.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Providing you do not do really cranky things with the pre-processor, you can write code in whichever style you prefer.

You just have a make rule to invoke "indent" in the manner that keeps the powers that be quiet.

Personally, I have very strong dislikes and preferences. For example avr-gcc inline ASM syntax is "so" horrible that I just avoid it.

However I will put up with all these strange fashions just as long as there is some attempt at indenting white space.

I have asked many times. Are there editors that remove all leading indentation on storage to disk, but indent on-the-fly so that you can edit something legible?

I ask because illegible code is often posted here. And I used to handle ASM formatting in this way.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Providing you do not do really cranky things with the pre-processor, you can write code in whichever style you prefer.

I don't know whether it is "really cranky", but with Cliff's style the below is quite difficult

    if (the_input & CHAN1_MASK)
        {
        process_chan (CHAN1);
        }
#ifdef EXTRACHANNEL
    else if (the_input & CHAN2_MASK)
        {
        process_chan (CHAN2);
        }
#endif

to be able to build for multiple configurations, but the Thought Police probably won't allow the conditional compilation anyway. If they did they couldn't justify the extra team person to do all the different combinations of source files for each configuration.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lee,

In my style that's no problem:

    if (the_input & CHAN1_MASK) { 
        process_chan (CHAN1); 
    } 
#ifdef EXTRACHANNEL 
    else if (the_input & CHAN2_MASK) { 
        process_chan (CHAN2); 
    } 
#endif

And our source code is littered with this kind of conditional compilation often in the form:

    if (the_input & CHAN1_MASK) { 
        process_chan (CHAN1); 
    } 
#ifdef CR0382_ADD_SUPPORT_SECOND_CHANNEL 
    else if (the_input & CHAN2_MASK) { 
        process_chan (CHAN2); 
    } 
#endif

or

    if (the_input & CHAN1_MASK) { 
        process_chan (CHAN1); 
    } 
#ifdef PR4427_SECOND_CHANNEL_WAS_OMITTED
    else if (the_input & CHAN2_MASK) { 
        process_chan (CHAN2); 
    } 
#endif

Where CR=Change Request, PR=Problem Report and the numbers are assigned from our bug-tracking database. While the #defines could be just a PR or CR number the addition of some descriptive words makes the code more readable. We do this with all post release code changes so that we can "pull" a fix from a release at any moment by a simple commenting of a #define in a shared .h file (and yes there are occasions where two changes/fixes overlap and that DOES make life a little more fun ;-) )

Cliff

Last Edited: Thu. Jul 16, 2009 - 09:47 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Quote:

Providing you do not do really cranky things with the pre-processor, you can write code in whichever style you prefer.

I don't know whether it is "really cranky", but with Cliff's style the below is quite difficult

    if (the_input & CHAN1_MASK)
        {
        process_chan (CHAN1);
        }
#ifdef EXTRACHANNEL
    else if (the_input & CHAN2_MASK)
        {
        process_chan (CHAN2);
        }
#endif

to be able to build for multiple configurations, but the Thought Police probably won't allow the conditional compilation anyway. If they did they couldn't justify the extra team person to do all the different combinations of source files for each configuration.

Lee

There is no problem with this sort of arrangement.

Some years ago there was a public domain source for a cross-assembler that deliberately used the pre-processor to insert unmatched parentheses. Any program like "indent" will struggle with this sort of thing. But seriously, just use "indent" to make Cliff's code readable for Lee. You can edit it in the "Wisconsin" style and post it back to Cliff in his "Finchingfield" format.

Assuming that Cliff maintains a consistent style, he will never know what you did. His company would just think that Lee is a subservient minion that obeys all their rules.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Lee,

In my style that's no problem:


??? From the link you gave on 1TBS

    if (x < 0) {
        printf("Negative");
        negative(x);
    } else {
        printf("Positive");
        positive(x);
    }

So are you "orthodox" or "reformed"? [As is the case in most of these types of discussion, dogma/rules/standards are religiously defended and followed...when convenient.] :twisted:

[like most of you, I started with a style 25 years ago that seemed "right for me", and now defend it to the death 'cause I'm used to looking at it. That said, I do NOT like any of the styles with the opening brace on the conditional line--too easy to hang way out there on the screen especially with heavy nesting.]

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.