Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту


 
Опции темы
Непрочитано 29.06.2016, 21:59  
supercelt
Прописка
 
Регистрация: 29.03.2007
Сообщений: 185
Сказал спасибо: 11
Сказали Спасибо 1 раз в 1 сообщении
supercelt на пути к лучшему
По умолчанию Правильный вывод переменной на lcd1602a

stm32ret6b + lcd1602a

Пробую выводить на экран. Получается только со строками, так как почти везде и показано, как выводить строки. Но захожу в тупик, как только надо вывести именно переменную, т.е. числовое значение. Многие предлагают конвертнуть число в строку. И тут начинаются танцы с бубном. sprintf занимает много ресурсов, далее предлагают делить на 10 со сложением и т.д. К тому же все примеры из нета в кеиле5 дают ошибки. Подскажите пожалуйста, как выводить лучше всего переменную, как это делают профи, когда стоит вопрос о растрате ресурсов камня?

строки я вывожу вот так:

Функции:

Код:
void LCD_Set_Data(uint8_t data){
  if(((data ›› 7) & 0x01) == 1){GPIOC-›BSRR = 0x80;} else {GPIOC-›BRR = 0x80;}
  if(((data ›› 6) & 0x01) == 1){GPIOC-›BSRR = 0x40;} else {GPIOC-›BRR = 0x40;}
  if(((data ›› 5) & 0x01) == 1){GPIOC-›BSRR = 0x20;} else {GPIOC-›BRR = 0x20;}
  if(((data ›› 4) & 0x01) == 1){GPIOC-›BSRR = 0x10;} else {GPIOC-›BRR = 0x10;}
  if(((data ›› 3) & 0x01) == 1){GPIOC-›BSRR = 0x8;} else {GPIOC-›BRR = 0x8;}
  if(((data ›› 2) & 0x01) == 1){GPIOC-›BSRR = 0x4;} else {GPIOC-›BRR = 0x4;}
  if(((data ›› 1) & 0x01) == 1){GPIOC-›BSRR = 0x2;} else {GPIOC-›BRR = 0x2;}
  if(((data ›› 0) & 0x01) == 1){GPIOC-›BSRR = 0x1;} else {GPIOC-›BRR = 0x1;}
}
void LCD_Send_Command(uint8_t data){
  GPIOA-›BRR = 0x10; //RS = 0;
  LCD_Set_Data(data);

  GPIOA-›BSRR = 0x40; //E = 1
  Delay_ns();
  GPIOA-›BRR = 0x40; //E = 0
}
void LCD_Send_Data(uint8_t data){
  GPIOA-›BSRR = 0x10; //RS = 1;
  LCD_Set_Data(data);

  GPIOA-›BSRR = 0x40; //E = 1
  Delay_ns();
  GPIOA-›BRR = 0x40; //E = 0
}
void LCD_Send_String(uint8_t str_num, char* str){
  uint8_t i = 0;
  if(str_num == 0){
        LCD_Send_Command(0x80);
  }else{
        LCD_Send_Command(0xC0);
  }
  Delay_us(100);
  while(str[i] != 0){
        LCD_Send_Data(str[i]);
        Delay_ns();
        i++;
  }
}
Сам вывод:

Код:
char str[] = "TEXT";
////////
LCD_ini();
LCD_Send_String(0, str);
Реклама:
supercelt вне форума  
Непрочитано 29.06.2016, 22:21  
NewWriter
Заблокирован
 
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: Правильный вывод переменной на lcd1602a

Отвлечемся от самого кода, сейчас не об этом. Переменная - это какое-то число размерности, указанной в объявлении переменной. Число в двоичной системе. Дисплей отображает число отдельно по каждой цифре. Значит, исходную переменную надо разделить на цифры - bin2BCD, преобразование двоичного в поразрядное двоично-десятичное распакованное. Для двухразрядного десятичного числа:
самая младшая цифра равна остатку от деления переменной на 10. Остаток от деления - символ %. unit = value % 10. Следующая цифра - исходная же переменная, деленная на 10. Изучите самостоятельно, что такое остаток от деления и как его применить для большего числа разрядов. Типы получаемых переменных - unsigned int (вернее, даже char, 8 бит), целые. Аппаратно деление занимает не так уж много времени.
Вышенаписанное к тому, чтобы было понятие, что же происходит с числами.

Далее, дисплей выводит символы в соответствии с ANSI-кодами, по крайней мере, для цифр и латиницы. Чтобы получить код цифры из значения переменной, нужно просто прибавить (логическое побитное ИЛИ) к переменной код символа '0', то есть, 0х30.
Фсё, как бы...

Кстати! Это там у вас не Arduino-плата ли??

Последний раз редактировалось NewWriter; 29.06.2016 в 22:59.
NewWriter вне форума  
Непрочитано 29.06.2016, 22:39  
zöner
Гражданин KAZUS.RU
 
Регистрация: 16.02.2012
Сообщений: 441
Сказал спасибо: 89
Сказали Спасибо 735 раз(а) в 149 сообщении(ях)
zöner на пути к лучшему
По умолчанию Re: Правильный вывод переменной на lcd1602a

у stm32 вроде есть аппаратный делитель, выгоднее делить на степени 10, выводить в буфер в ОЗУ, и буфер писать в LCD
zöner вне форума  
Непрочитано 29.06.2016, 23:14  
supercelt
Прописка
 
Регистрация: 29.03.2007
Сообщений: 185
Сказал спасибо: 11
Сказали Спасибо 1 раз в 1 сообщении
supercelt на пути к лучшему
По умолчанию Re: Правильный вывод переменной на lcd1602a

Нет, не ардуино. Я купил макетку VT2429 и спаял на неё мк и обвеску. Получилось как бы самое минимальное discovery))
supercelt вне форума  
Непрочитано 29.06.2016, 23:40  
NewWriter
Заблокирован
 
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: Правильный вывод переменной на lcd1602a

Ну, слава богу, не ардуина.. значит, "наш человек"
NewWriter вне форума  
Непрочитано 30.06.2016, 10:42  
krug_vv
Вид на жительство
 
Регистрация: 09.12.2009
Адрес: Россия, Тула
Сообщений: 377
Сказал спасибо: 192
Сказали Спасибо 156 раз(а) в 99 сообщении(ях)
krug_vv на пути к лучшему
По умолчанию Re: Правильный вывод переменной на lcd1602a

Я вот так делал ( преобразование в строку и из строки)

Код:
// преобразование ASCII в u8
u8 symbol_TO_u8(u8 symbol)
{
	return symbol - 0x30;
}
//

// преобразование u8 в ASCII
u8 u8_TO_symbol(u8 digit)
{
	return digit + 0x30;
}
//

//делает из u8 (255) строку "255"
void	Convert_Byte_To_Str(u8* buffer, u8 byte1, u8 znakov)
{
	u8 tmp8;
	if(znakov==3)
	{
		tmp8 = byte1/100;
		buffer[0] = u8_TO_symbol(tmp8);
		byte1 -= tmp8*100;
		tmp8 = byte1/10;
		buffer[1] = u8_TO_symbol(tmp8);
		byte1 -= tmp8*10;
		tmp8 = byte1;
		buffer[2] = u8_TO_symbol(tmp8);
	}
	else
	{
		tmp8 = byte1/10;
		buffer[0] = u8_TO_symbol(tmp8);
		byte1 -= tmp8*10;
		tmp8 = byte1;
		buffer[1] = u8_TO_symbol(tmp8);
	}
}
//

//делает из строки "255" u8 (255)
u8 Convert_Str_To_Byte(u8* buffer, u8 znakov) //делаем из строки "255" байт 0xFF
{
	u8 tmp;
	if(znakov==3)
	{
		tmp = symbol_TO_u8(buffer[0])*100;
		tmp += symbol_TO_u8(buffer[1])*10;
		tmp += symbol_TO_u8(buffer[2]);
	}
	else
	{
		tmp = symbol_TO_u8(buffer[0])*10;
		tmp += symbol_TO_u8(buffer[1]);
	}
	return tmp;
}
//
Позже перешел на использование знака % (это 3 знака для 7-сегм индикаторов)

Код:
void Prepare_Chisla(u16 chislo)
{
	Chisla[2] = ( chislo )       % 10;
	Chisla[1] = ( chislo /= 10 ) % 10;
	Chisla[0] = ( chislo /  10 ) % 10;
}
//
krug_vv вне форума  
Непрочитано 30.06.2016, 11:53  
makakus
Почётный гражданин KAZUS.RU
 
Регистрация: 08.10.2007
Сообщений: 2,760
Сказал спасибо: 1,105
Сказали Спасибо 1,037 раз(а) в 569 сообщении(ях)
makakus на пути к лучшему
По умолчанию Re: Правильный вывод переменной на lcd1602a

Сколько кода/времени занимает деление, когда аппаратного делителя нет?

Я делал вычитанием, типа if(var_copy ›= 10000) {var_copy -=10000; digit5++;} потом тысячи, сотни и т.д. Инициализация digit1=digit2=digit3=digit4=digit5='0'. Даже для ускорения было сравнение с 50000, 5000 ... и проверки на 0 после вычитаний.

16-разрядное число без знака, ассемблер АВР: от 65 до 159 тактов контроллера.

Последний раз редактировалось makakus; 30.06.2016 в 11:55.
makakus вне форума  
Непрочитано 30.06.2016, 13:15  
zöner
Гражданин KAZUS.RU
 
Регистрация: 16.02.2012
Сообщений: 441
Сказал спасибо: 89
Сказали Спасибо 735 раз(а) в 149 сообщении(ях)
zöner на пути к лучшему
По умолчанию Re: Правильный вывод переменной на lcd1602a

в Cortex-M3 есть аппаратный делитель, в М0 - нет. Непонятно какой у т.с.
некоторые методы описаны там: http://we.easyelectronics.ru/Soft/pr...ye-chisla.html

Последний раз редактировалось zöner; 30.06.2016 в 13:17.
zöner вне форума  
Непрочитано 30.06.2016, 14:19  
scorpi_0n
Прописка
 
Регистрация: 10.03.2016
Сообщений: 114
Сказал спасибо: 14
Сказали Спасибо 46 раз(а) в 41 сообщении(ях)
scorpi_0n на пути к лучшему
По умолчанию Re: Правильный вывод переменной на lcd1602a

Там по времени выполнения не столь велика разница. И чипа re в М0 нет. И вообще как-то всё мутно, 512К не хватает на sprintf.
scorpi_0n вне форума  
Непрочитано 30.06.2016, 23:41  
NewWriter
Заблокирован
 
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: Правильный вывод переменной на lcd1602a

Ну топикстартера наверняка что-то типа 103 или 107, судя по всему, а в них можно делить, не боясь.
Однако, при выключенной оптимизации написанная операция деления заменяется инструкциями аппаратного умножения UMULL - unsigned multiplier 32 х 32 бит с 64 битным результатом, и инструкциями логического сдвига LSRS, суммирования, вычитания.
И лишь при включении оптимизации по размеру можно увидеть уже инструкцию аппаратного деления UDIV - Unsigned division. Там еще будут инструкции MLS - 32-битного умножения с вычитанием.
Из этого видно, что аппаратный делитель используется далеко не так часто, как написанная операция деления.


Последний раз редактировалось NewWriter; 30.06.2016 в 23:51.
NewWriter вне форума  
 

Закладки
Опции темы

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вывод данных в двоичном виде yoka1 AVR 17 26.02.2015 18:16
Обращение к переменной, расположенной в микросхеме памяти, по иненерфейсу SPI kotbimigot Микроконтроллеры, АЦП, память и т.д 9 29.09.2011 18:31
[Решено] Помогите определить семисегментник opylk Информация по радиокомпонентам 3 18.03.2010 19:38
Вывод переменной на LCD DDimon Микроконтроллеры, АЦП, память и т.д 9 12.01.2009 22:36
Вывод состояния через 1 вывод DL36 Микроконтроллеры, АЦП, память и т.д 0 16.11.2006 14:27


Часовой пояс GMT +4, время: 19:35.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot