Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Работа printf()
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
fmdost
Доброго времени суток Уважаемые.
Подскажите как настроить printf() IAR в меге64? Не понял как задавать номер порта, и надо ли разрешать TXCIEx UDRIE?
defunct
Достаточно написать свой putchar() совместимый с прототипом:
int putchar(int ch)
fmdost
Цитата(defunct @ Sep 22 2007, 02:02) *
Достаточно написать свой putchar() совместимый с прототипом:
int putchar(int ch)

То-же самое написано в мануале. В С Я новичок. Обьясните пожалуйста чайнику про этот прототип?
Почему есть возвращаемое значение? И почему putchar(int ?) а не char?
defunct
Цитата(Т.Достоевский @ Sep 22 2007, 02:01) *
а не char?

Для AVR было бы лучше char, но низя, т.к. по стандарту int, и прототип этот уже объявлен в stdio.h, его вызывает функция printf при печати символов. (по крайней мере в IAR'е так).
Цитата
Почему есть возвращаемое значение?

чтобы возвращать код ошибки. putchar предназначен для вывода символов в любое последовательное устройсво вывода, например в файл. Как пример кода ошибки может быть - нет доступа/устройство не готово и т.п., но этим можно пренебречь.

простейший вариант putchar для отправки символов по UART'у может быть таким:

Код
int putchar(int ch)
{
    while( !(UCSRA & (1 << UDRE) ) );
    UDR = ch;
    return 0;
}
fmdost
Цитата(defunct @ Sep 22 2007, 03:19) *
Для AVR было бы лучше char, но низя, т.к. по стандарту int, и прототип этот уже объявлен в stdio.h,

int для совместимости, понял. Функцию так и сделал.
Вопрос по С. Можно ли реализовать:
Код
putchar(char) //типа собирает ф буффер а потом передаёт через прерывание UDRE
{
if (a<large_buffer)
  {
    buffer[a++]=char;
    if ( ! (USCRB & UDRIE0))
    {
       USCRB |= UDRIE0;//разрешить прерывание
       b=0;//для работы как указатель в прерывании по UDRE (если сравняется с а то ждать окончания по TXC
     }
    return 0;

  }
else
return -1;
}

чтоб максимально быстро собрал, и уже потом аппаратно передавал. Или есть более правильное решение?
defunct
Цитата(Т.Достоевский @ Sep 22 2007, 02:47) *
чтоб максимально быстро собрал, и уже потом аппаратно передавал.

Конечно, так и надо делать.

Цитата
Или есть более правильное решение?

разве что с технической стороны организации буфера - есть кольцевой буфер, и он больше подходит для этой задачи. А идеологически - вполне нормальное решение у вас.
rezident
Цитата(defunct @ Sep 22 2007, 05:19) *
простейший вариант putchar для отправки символов по UART'у может быть таким:

Код
int putchar(int ch)
{
    while( !(UCSRA & (1 << UDRE) ) );
    UDR = ch;
    return 0;
}

Вообще-то putchar при нормальной операции должен возвращать тот же символ, что и в аргументе указан. А EOF возвращает только в случае НЕуспешной операции. Цитата из стандарта ANSI C (C99)
Цитата
7.19.7.9 The putchar function
Synopsis
1 #include <stdio.h>
int putchar(int c);
Description
2 The putchar function is equivalent to putc with the second argument stdout.
Returns
3 The putchar function returns the character written. If a write error occurs, the error
indicator for the stream is set and putchar returns EOF.
fmdost
Цитата(defunct @ Sep 22 2007, 04:04) *
Конечно, так и надо делать.
разве что с технической стороны организации буфера - есть кольцевой буфер, и он больше подходит для этой задачи. А идеологически - вполне нормальное решение у вас.

Спасибо. Осталась одна непоняная вещь. Что значит возвращает ошибку? Можно ли это использовать в случае если сообщение болше чем буфер? Printf() ждёт, или просто прекращает передачу?
ЗЫ. Про кольцевые буфера помню, прикручу.
Сергей Борщ
Цитата(Т.Достоевский @ Sep 22 2007, 03:25) *
Что значит возвращает ошибку?
Значит сообщает вызывающей функции, что вывод не удался и не имеет смысла выводить остальные символы (если они есть). printf() в этом случае завершается и остаток строки не выводится.
Цитата(Т.Достоевский @ Sep 22 2007, 03:25) *
Можно ли это использовать в случае если сообщение болше чем буфер? Printf() ждёт, или просто прекращает передачу?
Если сообщение больше чем буфер - вы можете просто ждать в putchar() пока не появится место в буфере.
Код
int putchar (int byte)
{
    uint8_t Tmp = TxHead;
    uint8_t Tmp1 = (Tmp + 1) & (RS232_TXBUFF_SIZE - 1);
    while(Tmp1 == TxTail);        // Buffer full, wait
    TxBuffer[ Tmp ] = byte;
    TxHead = Tmp1;
    UCSRB |= (1 << UDRIE);
    return byte
}
fmdost
Цитата(Сергей Борщ @ Sep 24 2007, 00:51) *
Значит сообщает вызывающей функции, что вывод не удался и не имеет смысла выводить остальные символы (если они есть). printf() в этом случае завершается и остаток строки не выводится.
Если сообщение больше чем буфер - вы можете просто ждать в putchar() пока не появится место в буфере.

Точно! Теперь дошло! Ждать в printf() или putchar() это же оно и то-же! smile3046.gif
alexander55
Цитата(Т.Достоевский @ Sep 22 2007, 04:25) *
ЗЫ. Про кольцевые буфера помню, прикручу.

FIFO придумал заядлый собаковод, выгуливающий свою шавку вокруг большого столба.
Он понял 3 правила:
1. собачка бежит бежит по кругу в одном направлении
2. нельзя обгонять собачку
3. поводок должен быть меньше длины окружности столба.
Это моя шутка. All right reserved.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.