Перейти к содержанию
    

дравствуйте!

Может быть кто-то сталкивался с проблемами при перенаправлении printf и scanf на UART?

Я использую китайскую плату с MC stm32F103. Для программирования использую

IAR 7.40 и библиотеку HAL из stm32cubef1 (STM32Cube_FW_F1_V1.2.0)

 

Задача - перенаправить стандартный ввод-вывод на UART.

Задачу я решил, даже двумя способами, но у каждого способа оказались свои недостатки.

Буду рад, если найдутся желающие посмотреть мой нехитрый код и объяснить мне, как его исправить.

 

В программе с помощью макроса EXTTTY можно настроить три варианта ввода/вывода:

EXTTTY 0 - ввод/вывод в I/O Terminal оболочки IAR

EXTTTY 1 - ввод/вывод через UART посредством переопределения функций fputc и fgetc

EXTTTY 2 - ввод/вывод через UART посредством переопределения функций __write и __read и написания MyLowLevelPutchar и MyLowLevelGetchar

 

Проблемы при EXTTTY 1 - scanf с шаблоном "%d" "проглатывает" первый символ. (Вводишь 123, воспринимается как 23)

Проблемы при EXTTTY 2 Все раюотает примерно 2 минуты, а затем в терминал начинают сыпаться какие-то левые символы (может, вотчдог срабатывает?)

 

Может быть кто-нибудь сталкивался с подобными проблемами и смог это вылечить?

Код находится в прикрепленном архивчике и может свободно использоваться в собственных разработках.

 

Заранее благодарю откликнувшихся )

 

Прикрепленные файлы

Прикрепленный файл myprintf.zip ( 104.18 килобайт ) Кол-во скачиваний: 0

myprintf.zip

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я просто переписываю putc, getc да и всё. При этом можно перенапривить куда угодно. Например на LCD.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я просто переписываю putc, getc да и всё. При этом можно перенапривить куда угодно. Например на LCD.

 

А координаты вывода как передаете?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А координаты вывода как передаете?

 

Текста? Туда где курсор, а курсор всегда сдвигается на длину написанного вправо или вниз и начало строки если строка закончилась.

Можно (если ее нет) сделать функцию для установки позиции курсора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Текста? Туда где курсор, а курсор всегда сдвигается на длину написанного вправо или вниз и начало строки если строка закончилась.

Можно (если ее нет) сделать функцию для установки позиции курсора.

 

Функция не совсем удобно, у себя слегка поправил парсер, чтоб можно было задавать %XN=... %YN=...

Сорри за офтоп :rolleyes:

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Функция не совсем удобно, у себя слегка поправил парсер, чтоб можно было задавать %XN=... %YN=...

Сорри за офтоп :rolleyes:

И что мешает? Я так и делал...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я просто переписываю putc, getc да и всё. При этом можно перенапривить куда угодно. Например на LCD.

 

А вы пользуетесь компилятором IAR?

У меня возникает ошибка, что эти функции уже определены.

А вот fputc и fgets переопределяются нормально

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вы пользуетесь компилятором IAR?

У меня возникает ошибка, что эти функции уже определены.

А вот fputc и fgets переопределяются нормально

Я пользуюсь IAR, и определяю putchar.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте без HAL, через регистры, инициализировать UART и сделать fputc, fgetc.

Вот в этой теме, например, говорится о проблемах в HAL при передаче по UART:

http://electronix.ru/forum/index.php?showt...131520&st=0

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да пользуюсь IAR. Прошу прощения, действительно putchar.

В принципе в библиотеке описано

Вот примерно лет 10 назад )) для 44780 учебный проект какой-то ...

int16_t	putchar(int16_t	c_in)		// Вывести символ	в кодировке	Win. с управляющими	символами
{
uint8_t c;
uint8_t static	cr_direct_flag;		// Флаг	прямой адресации курсора

c = c_in;						   	// Привести к байту
if(cr_direct_flag==1){
  cr_direct_flag=0;				// Сбросить
  GotoXY(c	& 0x1f,c>>5);			// Выполнить прямую	адресацию курсора
  }
  else{
 if((c>=8) && (c<0x20)){
   switch©{
	case CR_TAB:
	  WaitEndData(' ');			// вывести ' '
	  WaitEndData(' ');			// вывести ' '
	  WaitEndData(' ');			// вывести ' '
	  WaitEndData(' ');			// вывести ' '
	  break;
	case CR_LEFT:
	  cr_left();
	case CR_RIGHT:
	  cr_right();
	  break;
	case CR_BS:
	  if(cr_left()>=0){
		WaitEndData('	');			// вывести ' '
		cr_left();
	  }
	  break;
	case CR_CURSHOW:
	  CURSHOW;					// Курсор показать
	  break;
	case CR_CURHIDE:
	  CURHIDE;					// Курсор погасить
	  break;
	case CR_DOWN:
	case CR_LF:
	  cr_down();				// Курсор вниз
	  break;
	case CR_UP:
	  cr_down();				// Курсор вверх
	  break;
	case CR_ENTER:
	  cr_home();				// Курсор в начало строки
	  break;
	case CR_HOME:
	  WaitEndCom(0x80);			// Курсор в	нулевую	позицию.
	  break;
	case CR_NEW:
	  CLEARLCD;					// Очистить	дисплей.
	  break;
	case CR_CURDIRECT:
	  cr_direct_flag=1;			// Адресовать курсор
	  break;
	case CR_BEEP:
	  break;
   }
 }
 else{
   if(c>=0x80){					// Если символ не латинский, то
	 c -= 0x80;					// Уменьшить таблицу
	 c = TabWin[c];				// Перекодировать
   }
   WaitEndData©;				// и вывести
 }
  }
return(1);
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Способ перенаправления printf dв EWARM, описанный в хелпе:

http://microsin.net/programming/arm-troubl...r-redirect.html

 

Всегда делаю так, все работает, scanf не использовал правда

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В IAR почти не пользуюсь ничем из printf/sprintf/...

Зачем, когда есть _Printf()? Все эти printf/sprintf/... её собственно и вызывают.

Она позволяет задать свою callback-функцию, с помощью которой можно сделать всё что угодно: и перенаправление и вывод в буфер ограниченный размером, и вывод с каким-то спец-форматированием выходного потока -

что угодно, что со стандартными функциями printf/sprintf/... затруднительно.

Пользуйтесь:

extern "C" int _Printf(void *(*)(void *, int), void *, const char *, va_list *);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В IAR почти не пользуюсь ничем из printf/sprintf/...

Зачем, когда есть _Printf()? Все эти printf/sprintf/... её собственно и вызывают.

 

Всегда использовал свой printf, более оптимизированный и одинаково работающий под любым компилятором ибо это удобнее, чем всякие закрытые либы иара...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

чем всякие закрытые либы иара...
Если работает и в память лезет - то можно и закрытые. У ИАРа библиотечный printf довольно вменяемый, в отличие от гцц.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если работает и в память лезет - то можно и закрытые. У ИАРа библиотечный printf довольно вменяемый, в отличие от гцц.

 

Вот и дело-то в том что изначально была авр-студия,а там он был "не очень"... А когда перешел на иар, просто переташил его за одним :rolleyes:

Изменено пользователем mantech

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...