После долгих поисков, проб и ошибок я нашел решение.
Я неверно истолковал ошибку, которую увидел, и Томас прав. Функция была слишком большой для чипа, когда она добавлялась к моим собственным функциям.
Очевидные решения никуда не делись, но я перечислю их здесь, чтобы помочь другим новичкам, когда они столкнутся с этой проблемой.
itoa () - 16 бит и ultoa () - 32 бита реализованы, но слишком малы.
sprintf (% d) слишком мал и sprintf (% lld) не реализован в WinAVR (AVR-GCC).
Этот код работает (с оговоркой):
void main()
{
unsigned long long tagid;
char tagid_str[12];
tagid = 109876543210ull
convert_to_decimal(tagid_str, tagid);
}
void convert_to_decimal(char* dst, unsigned long long src)
{
int i;
for (i = 0; i < 12; i ++)
{
dst[11 - i] = '0' + (int)(src % 10);
src /= 10;
}
dst[12] = 0;
}
Но посмотрите на статистику:
Программа: 7358 байт ( 89,8% заполнено )
(.text + .data + .bootloader)
Данные: 256 байт ( 25,0% заполнено )
(.data + .bss + .noinit)
Виновником является оператор % . Я не могу объяснить, почему при его использовании с long long генерируется почти 8 тысяч кода!
Вот рабочая альтернатива. Я изменил его, чтобы использовать только unsigned long long (64 бита) до 12 десятичных цифр, чтобы соответствовать формату считывателя RFID, который я использую.
void main()
{
unsigned long long tagid;
char tagid_str[12];
tagid = 000000000000ull;
ulltostr((unsigned long long)tagid, tagid_str);
tagid = 000000000001ull;
ulltostr((unsigned long long)tagid, tagid_str);
tagid = 109876543210ull;
ulltostr((unsigned long long)tagid, tagid_str);
tagid = 900000000000ull;
ulltostr((unsigned long long)tagid, tagid_str);
tagid = 999999999999ull;
ulltostr((unsigned long long)tagid, tagid_str);
}
//http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=31199
void ulltostr(unsigned long long val, char *s )
{
char *p;
unsigned char d, i;
unsigned char zero;
unsigned long long test;
unsigned long long uval = val;
p = s;
zero = 1;
i = 12;
do{
i--;
if ( i==0) test =10;
else if ( i==1) test =100;
else if ( i==2) test =1000;
else if ( i==3) test =10000;
else if ( i==4) test =100000;
else if ( i==5) test =1000000;
else if ( i==6) test =10000000;
else if ( i==7) test =100000000;
else if ( i==8) test =1000000000;
else if ( i==9) test =10000000000;
else if ( i==10) test=100000000000;
else if ( i==11) test=1000000000000;
else if ( i==12) test=10000000000000;
for( d = '0'; uval >= test; uval -= test )
{
d++;
zero = 0;
}
if( zero == 0 )
*p++ = d ;
}while( i );
*p++ = (unsigned char)uval + '0';
}
И статистика:
Программа: 758 байт ( 9,3% Полный)
(.text + .data + .bootloader)
Данные: 0 байт ( 0,0% Полный)
(.data + .bss + .noinit)
намного лучше :) 1053 *
Я провел большую часть своего времени с Дугласом Джонсом , но ответ наконец пришел от AVR Freaks .