реклама на сайте
подробности

 
 
> Оператор "printf" и функция "putchar" для работы с символьным LCD
Буратино
сообщение Mar 19 2010, 11:47
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215



не понимаю, что за беда с выводом.
Прописал "putchar" в виде:
Код
void putchar( char c ) {
    if ( !c )
    return( 0 );
    Transmit_Byte( c );  /*функция отправки сообщения в последовательный порт*/
}


LCD оснащен контроллером, который принимает данные по последовательному порту и выводит на экран дисплея 16*02
Не могу разобраться почему:

printf("%a", 30.0) выводит "???"
printf("%.2A", 30.0) выводит "???"
printf("%c", 'a') ничего выводит
printf("<%3c|%-3c>", 'a', 'b') выводит "< крокозябра >"
и т.д. совсем другими словами не то что я ожидаю.

printf("Hello World!") выводит "Hello World!", но если использовать длинную строку или несколько операторов "printf" со строками, то выводятся куски строк в хаотичном порядке.
размер Data Stack в компиляторе IAR установил в 0x300.

Мне нужно выводить на экран простые конструкции состоящие из текста и числовых данных, что делать? smile.gif

Сообщение отредактировал Буратино - Mar 19 2010, 12:46


--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Буратино
сообщение Mar 19 2010, 18:20
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215



Все, разобрался (хотя и остались некоторые непонятки):
Не включил в проект #include <stdio.h> rolleyes.gif
---
zltigo, прошу прощения, что наорал на Вас, злой очень был.
Все никак не решусь на новый виток в образовании, вот если бы ногу или руку сломать (на крайний случай ветрянка сойдет), чтоб дома в кровати валяться и книги умные читать..

Сообщение отредактировал Буратино - Mar 19 2010, 18:28


--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Mar 19 2010, 18:37
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Буратино @ Mar 19 2010, 21:20) *
Все, разобрался (хотя и остались некоторые непонятки):

Некошерно смотрится дергание бита разрешения прерывания sad.gif. Ну и volatile для UART_TxHead0 лишнее - только warning вызывает. tmptail0 лишняя сущность... Про имена помолчу.... Прототипы своих функций тоже игнорируем sad.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 19 2010, 21:20
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(zltigo @ Mar 19 2010, 20:37) *
Некошерно смотрится дергание бита разрешения прерывания sad.gif
Нормально смотрится. Нужны прервания - разрешаем, не нужны - запрещаем. Флаг-то аппаратно торчит всегда, когда свободен буфер передачи. Это вам не '550.
Цитата(zltigo @ Mar 19 2010, 20:37) *
Ну и volatile для UART_TxHead0 лишнее - только warning вызывает.
Формально - не лишняя. Переменная меняется в другой относительно прерывания нити.
Цитата(zltigo @ Mar 19 2010, 20:37) *
tmptail0 лишняя сущность...
Вовсе нет. Без нее получаем предупреждение компилятора на неопределенный порядок чтения двух volatile в сравнении.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Mar 19 2010, 21:53
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Сергей Борщ @ Mar 20 2010, 00:20) *
Нормально смотрится. Нужны прервания - разрешаем, не нужны - запрещаем. Флаг-то аппаратно торчит всегда, когда свободен буфер передачи.

Свободен сдвиговый регистр - записываем прямо в UART, не свободен в буфер и по прерыванию уже вычитываем, либо по анализу указателей, либо флаг можно завести.
Цитата
Формально - не лишняя. Переменная меняется в другой относительно прерывания нити.

Абсолютно лишняя, ибо пока выполняется обработчик она измениться за его пределами не может. для Tail volatile нужен, Head - нет.
Цитата
Вовсе нет. Без нее получаем предупреждение компилятора на неопределенный порядок чтения двух volatile в сравнении.

Два volatile, повторяю, ну совсем не нужны, а warning, гарантировано при if ( UART_TxHead0 != UART_TxTail0 ) вылезет хоть есть tmptail0, хоть нет.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 20 2010, 09:54
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(zltigo @ Mar 19 2010, 23:53) *
Свободен сдвиговый регистр - записываем прямо в UART, не свободен в буфер и по прерыванию уже вычитываем, либо по анализу указателей, либо флаг можно завести.
И все эти телодвижения только ради того, чтобы не запрещать/разрешать прерывание? Нафиг. Хорошо, пусть даже идем вашим путем. В прерывании вычитываем из буфера. Буфер пуст - все данные переданы. Что делать дальше? Флаг прерывания сбросить невозможно - для этого нужно что-то начать передавать. Если выйдем из прерывания не запретив его - тут же попадем в это же прерывание снова. Что мы можем сделать кроме как запретить это прерывание? Еще раз повторяю - это не '550, тут не получается начать генерить прерывания положив первый байт в передатчик. И такая реализация дает более компактный код, без всяких лишних проверок "свободен/не свободен сдвиговый регистр".
Цитата(zltigo @ Mar 19 2010, 23:53) *
Абсолютно лишняя, ибо пока выполняется обработчик она измениться за его пределами не может.
Ну хорошо, тут соглашусь.
Цитата(zltigo @ Mar 19 2010, 23:53) *
Два volatile, повторяю, ну совсем не нужны, а warning, гарантировано при if ( UART_TxHead0 != UART_TxTail0 ) вылезет хоть есть tmptail0, хоть нет.
Тюю... Невнимательно посмотрел исходник. Рассмотрел только TransmitByte, увидел, что она очень похожа на один из вариантов используемого мной кода и экстраполировал этот вывод и на обработчик прерывания. Виноват. У автора ветки действительно лишний.
Код
void uart_t::send(uint8_t byte)
{
    uint8_t Tmp = (TxHead + 1) & (UART_TX_BUFF_SIZE - 1);
    while(Tmp == TxTail)
       ;       // Buffer full
    TxBuffer[ TxHead ] = byte;
    TxHead = Tmp;
    UCSRB |= (1<<UDRIE);
}

inline void  uart_t::UDRE_handler(void)
{
    uint8_t Tmp = TxTail;
    UDR = TxBuffer[ Tmp ];
    TxTail = Tmp = (Tmp + 1) & (UART_TX_BUFF_SIZE - 1);
    if(Tmp == TxHead)
        UCSRB &= ~(1<<UDRIE);
}


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Mar 20 2010, 10:34
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Сергей Борщ @ Mar 20 2010, 12:54) *
И все эти телодвижения....

Это не все, это на вскидку три разных варианта. Каждый из 3x не сложнее суммарного дергания периферии с целью разрешения/запрещения прерывания в функции передачи и обработчике.
Цитата
И такая реализация дает более компактный код, без всяких лишних проверок "свободен/не свободен сдвиговый регистр".

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

Цитата
У автора ветки действительно лишний.
Код
inline void  uart_t::UDRE_handler(void)
{
    uint8_t Tmp = TxTail;
    UDR = TxBuffer[ Tmp ];
    TxTail = Tmp = (Tmp + 1) & (UART_TX_BUFF_SIZE - 1);
    if(Tmp == TxHead)
        UCSRB &= ~(1<<UDRIE);
}

Ну вообще-то и у тебя лучше обойтись smile.gif без.

Код
union {
volatile uint8_t TxTail;
uint8_t TxTail_int;
};

inline void  uart_t::UDRE_handler(void)
{
    UDR = TxBuffer[ TxTail_int ];
    TxTail_int = (TxTail_int + 1) & (UART_TX_BUFF_SIZE - 1);
    if(TxTail_int == TxHead)
        UCSRB &= ~(1<<UDRIE);
}

Меньше указивок, меньше думать и больше свободы компилятору.
P.S.
Кстати, в таких случаях я предпочитаю НЕ накладывать маску на индексы при их наращивании - пусть крутятся по полному циклу, а маска накладывается при использовании индекса. В этом случае одними действием вычитания индексов можно узнать сколько байтов в буфере - бывает нужно при пакетной передаче.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 20 2010, 11:11
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(zltigo @ Mar 20 2010, 12:34) *
Очень очень зависит от конкретики и железа. Компактность кода, тоже не всегда синоним скорости - для тех контроллеров, у которых периферия находится на медленной шине безусловное действие прочитать-изменить-записать флаг в при каждом вызове передачи байта катострофически проигрывает по времени, например, анализу софтового флага.
В данном случае код был под конкретный контроллер - AVR. В котором, во-первых, периферия висит на быстрой шине (других просто нет), а во-вторых - без сброса разрешения прерывания просто не получится.
Цитата(zltigo @ Mar 20 2010, 12:34) *
Кстати, в таких случаях я предпочитаю НЕ накладывать маску на индексы при их наращивании - пусть крутятся по полному циклу, а маска накладывается при использовании индекса. В этом случае одними действием вычитания индексов можно узнать сколько байтов в буфере - бывает нужно при пакетной передаче.
Так я же написал - это один из вариатнтов. Опять же, речь идет об AVR, у которого FIFO нет (двойная буферизация не считается), и толку от знания "сколько конкретно байт в буфере" нет никакого.
Код
void uart_t::send(uint8_t byte)
{
    uint8_t Tmp = TxHead;
    while((uint8_t)(Tmp - TxTail) >=  (uint8_t) UART_TX_BUFF_SIZE)
    ; // Buffer full
    TxBuffer[ Tmp++ & (UART_TX_BUFF_SIZE - 1) ] = byte;
    TxHead = Tmp;
    UCSRB |= (1<<UDRIE);
}

inline void uart_t::UDRE_Handler()
{
    uint8_t Tmp = TxTail;
    UDR = TxBuffer[ Tmp++ & (UART_TX_BUFF_SIZE - 1) ];
    TxTail = Tmp;
    if(Tmp == TxHead)
        UCSRB &= ~(1<<UDRIE);
}
Но результирующий код получается длинее на 6 байт. И чего я на него перешел? Надо вернуться к первому - память кода может пригодиться.

Цитата(zltigo @ Mar 20 2010, 12:34) *
Меньше указивок, меньше думать и больше свободы компилятору.
Фу. union в таком применении - грязный хак. Как раз таки и не дающий никакой дополнительной свободы компилятору, но чреватый какими-нибудь граблями если компилятор окажется черезчур умным. А думать надо всегда smile.gif

Впрочем, мы уклонились от темы ветки.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ReAl
сообщение Mar 20 2010, 18:38
Сообщение #9


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Сергей Борщ @ Mar 20 2010, 13:11) *
Фу. union в таком применении - грязный хак.
продолжая уклоняться - если уж всё равно плюсы, то можно попробовать http://electronix.ru/forum/index.php?showt...mp;#entry535341


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Буратино   Оператор "printf" и функция "putchar" для работы с символьным LCD   Mar 19 2010, 11:47
- - barabek   Цитата(Буратино @ Mar 19 2010, 21:47) pri...   Mar 19 2010, 12:09
- - Буратино   printf("%f", 30.0); выводит "0.0000...   Mar 19 2010, 12:12
- - zltigo   Цитата(Буратино @ Mar 19 2010, 14:47) Про...   Mar 19 2010, 12:34
- - Буратино   А почему эта функция не putchar()? --- Буратино ...   Mar 19 2010, 12:43
|- - zltigo   Цитата(Буратино @ Mar 19 2010, 15:43) А п...   Mar 19 2010, 12:46
|- - Буратино   Цитата(zltigo @ Mar 19 2010, 15:46) А вот...   Mar 19 2010, 12:51
- - Буратино   Пересмотрел форум, и понял ,что функция printf() ...   Mar 19 2010, 15:36
|- - zltigo   Цитата(Буратино @ Mar 19 2010, 18:36) Я у...   Mar 19 2010, 15:49
- - one_eight_seven   А в контроллер уже зашиты ASCII коды? Может, я не...   Mar 19 2010, 15:49
- - Буратино   zltigo ,почему Вы такой злой? Ну нет желания помоч...   Mar 19 2010, 15:59
|- - zltigo   Цитата(Буратино @ Mar 19 2010, 18:59) zlt...   Mar 19 2010, 16:34
|- - Буратино   Цитата(zltigo @ Mar 19 2010, 21:37) Некош...   Mar 19 2010, 18:45
||- - zltigo   Цитата(Буратино @ Mar 19 2010, 21:45) Что...   Mar 19 2010, 18:52
||- - zltigo   Цитата(Сергей Борщ @ Mar 20 2010, 14:08) ...   Mar 20 2010, 11:14
|||- - Сергей Борщ   Цитата(zltigo @ Mar 20 2010, 13:14) При н...   Mar 20 2010, 15:08
|||- - zltigo   Цитата(Сергей Борщ @ Mar 20 2010, 18:08) ...   Mar 20 2010, 15:35
||- - zltigo   Цитата(Сергей Борщ @ Mar 20 2010, 14:11) ...   Mar 20 2010, 18:51
|- - Сергей Борщ   Цитата(zltigo @ Mar 20 2010, 01:08) Абсол...   Apr 20 2010, 21:59
|- - zltigo   Цитата(Сергей Борщ @ Apr 21 2010, 00:00) ...   Apr 20 2010, 22:13
||- - Сергей Борщ   Цитата(zltigo @ Apr 21 2010, 01:28) Это п...   Apr 21 2010, 07:31
||- - ReAl   Цитата(zltigo @ Apr 21 2010, 01:28) Это п...   Apr 24 2010, 21:28
|- - zltigo   Цитата(Сергей Борщ @ Apr 21 2010, 00:14) ...   Apr 24 2010, 22:39
- - sonycman   Кстати, можно вопрос по поводу UARTов микроконтрол...   Mar 20 2010, 12:57
|- - zltigo   Цитата(sonycman @ Mar 20 2010, 15:57) В о...   Mar 20 2010, 13:10
|- - sonycman   Цитата(zltigo @ Mar 20 2010, 17:10) Пальц...   Mar 20 2010, 14:00
|- - zltigo   Цитата(sonycman @ Mar 20 2010, 17:00) У В...   Mar 20 2010, 14:41
- - Буратино   RE: Оператор "printf" и функция "putchar" для работы с символьным LCD   Mar 20 2010, 16:49
- - zltigo   Цитата(Буратино @ Mar 20 2010, 19:49) А ...   Mar 20 2010, 17:01


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 17:18
Рейтинг@Mail.ru


Страница сгенерированна за 0.02191 секунд с 7
ELECTRONIX ©2004-2016