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

Профессионал
    
Группа: Свой
Сообщений: 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. Мне нужно выводить на экран простые конструкции состоящие из текста и числовых данных, что делать?
Сообщение отредактировал Буратино - Mar 19 2010, 12:46
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
 |
Ответов
|
Mar 19 2010, 18:20
|

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

|
Все, разобрался (хотя и остались некоторые непонятки): Не включил в проект #include <stdio.h> --- zltigo, прошу прощения, что наорал на Вас, злой очень был. Все никак не решусь на новый виток в образовании, вот если бы ногу или руку сломать (на крайний случай ветрянка сойдет), чтоб дома в кровати валяться и книги умные читать..
Сообщение отредактировал Буратино - Mar 19 2010, 18:28
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Mar 19 2010, 21:20
|

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

|
Цитата(zltigo @ Mar 19 2010, 20:37)  Некошерно смотрится дергание бита разрешения прерывания  Нормально смотрится. Нужны прервания - разрешаем, не нужны - запрещаем. Флаг-то аппаратно торчит всегда, когда свободен буфер передачи. Это вам не '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)
|
|
|
|
|
Mar 19 2010, 21:53
|

Гуру
     
Группа: Свой
Сообщений: 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
|
|
|
|
|
Mar 20 2010, 09:54
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Mar 20 2010, 10:34
|

Гуру
     
Группа: Свой
Сообщений: 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); } Ну вообще-то и у тебя лучше обойтись  без. Код 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
|
|
|
|
Сообщений в этой теме
Буратино Оператор "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, 12:34) Очень... Mar 20 2010, 11:11       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       ReAl Цитата(Сергей Борщ @ Mar 20 2010, 13:11) ... Mar 20 2010, 18:38       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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|