PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : warum negative zahl im terminal wenn diese >32000



pebisoft
17.04.2005, 23:51
hallo, bei ausgabe des wertes "wert_1 = 34000" kommt im terminal "-31536"
zur anzeige. warum kommen die zahlen über "32000" als negative zahl
zur ausgabe.
mfg pebisoft



#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <string.h>
#include <delay_1.c>
#include <stdint.h>

#define READ 1
#define WRITE 2

#define USART_BAUD_RATE 19200
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16l)-1)

void usart_init(int Enable, int Interupts)
{
if (Enable & READ) UCSRB = (1<<RXEN);
if (Enable & WRITE) UCSRB |= (1<<TXEN);

if (Interupts & READ) UCSRB |= (1<<RXCIE);
if (Interupts & WRITE) UCSRB |= (1<<TXCIE);
UBRRL = (unsigned char) USART_BAUD_SELECT;
}

void usart_writeChar(unsigned char c)
{
while (!(UCSRA & (1<<UDRE))) {}
UDR = c;
while(!(UCSRA & (1<<TXC))) {}
}

void usart_writeString(unsigned char *string) {
while (!(UCSRA & (1<<UDRE))) {}
while ( *string)
usart_writeChar(*string++);
}

int main (void)
{

char s[10];
uint16_t wert_1;
usart_init( (READ + WRITE) , READ);

wert_1=34000;
itoa( wert_1, s, 10);
while(1)
{
usart_writeString(s);
usart_writeString("\r");
warte(20000);
}
}

PicNick
18.04.2005, 07:47
Pebi, sowas steht in der Doku für datentypen.
du müßtest uint als "unsigned" definieren und hoffen, daß itoa auch schlau genug ist.

JanB
18.04.2005, 07:48
Hallo,

warum kommen die zahlen über "32000" als negative zahl
zur ausgabe.
Weil die Funktion itoa() zur Umsetzung von
vorzeichenbehafteten Integerwerten in ASCII vorgesehen ist.
Bei (unsigned)Integerwerten größer 32767 ist das höchstwertige Bit gesetzt,
und das ist für itoa() das Kennzeichen für einen negativen Wert.

Gruß Jan

pebisoft
18.04.2005, 09:57
hallo, wie kann eine routine aussehen um dieses obern zu realisieren.
oder gibt es in winavr-c eine routine, die ich nicht kenne für diese problem.
mfg pebisoft

PicNick
18.04.2005, 11:41
An sich wäre da "ltoa" statt "itoa" zuständig.

extern char *ltoa(long int __val, char *__s, int __radix);

versuch's mal.

EDIT:
eventuell auch das:

extern char *utoa(long int __val, char *__s, int __radix);

Kjion
18.04.2005, 13:00
Hi,

oder gibt es in winavr-c eine routine, die ich nicht kenne für diese problem.

Auch selberschreiben ist in diesem Fall nicht schwer. Hier mal eine Routine von Peter Dannegger aus dem Mikrocontroller.net Forum:

void uart_put_int( uint16_t val )
{
uint16_t TEST[] = { 10, 100, 1000, 10000 };
uint8_t d, i;
uint8_t zero;
uint16_t uval = val;

zero = 1;
i = 4;
do {
i--;
for( d = '0'; uval >= TEST[i]; uval -= TEST[i] ) {
d++;
zero = 0;
}

if( zero == 0 )
uart_putc( d );

} while( i );

uart_putc( (uint8_t) uval + '0' );
}

oder eine von mir die immer eine bestimmte Anzahl von Zeichen ausgibt ( das mit den Füllbytes kann man auch rausschmeißen wenn man es nicht benötigt ):

void uart_put_dec(uint16_t wert, uint8_t anzahl, char fuell)
{
uint8_t i, s[5];

/* Zahl in String umwandeln */
for (i = 0; i < anzahl; i++)
{
s[anzahl - i - 1] = '0' + (wert % 10);
wert /= 10;
}

/* Füllbyte ersetzten */
for (i=0; i<(anzahl - 1); i++)
{
if (s[i] == '0')
s[i] = fuell;
else
break;
}

/* String ausgeben */
for (i=0; i<anzahl; i++)
uart_putc(s[i]);
}

MfG Kjion

pebisoft
18.04.2005, 14:31
hallo robort vielen dank. uint auf 32 und dein "ltoa" klappt wunderbar.
mfg pebisoft

"uint32_t wert_1;"
"ltoa( wert_1, s, 10)"

pebisoft
18.04.2005, 14:33
hallo, habe noch ein projekt "srf08 zum laufen zu bringen".
krieg ich nicht hin.
mfg pebisoft

PicNick
18.04.2005, 14:35
Ja Pebi, hab' ich gesehn. Das sieht aber irgendwie nach Arbeit aus. :-b