29.06.2016, 21:59
|
|
Прописка
Регистрация: 29.03.2007
Сообщений: 185
Сказал спасибо: 11
Сказали Спасибо 1 раз в 1 сообщении
|
Правильный вывод переменной на 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); |
|
|
|
|
29.06.2016, 22:21
|
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: Правильный вывод переменной на lcd1602a
Отвлечемся от самого кода, сейчас не об этом. Переменная - это какое-то число размерности, указанной в объявлении переменной. Число в двоичной системе. Дисплей отображает число отдельно по каждой цифре. Значит, исходную переменную надо разделить на цифры - bin2BCD, преобразование двоичного в поразрядное двоично-десятичное распакованное. Для двухразрядного десятичного числа:
самая младшая цифра равна остатку от деления переменной на 10. Остаток от деления - символ %. unit = value % 10. Следующая цифра - исходная же переменная, деленная на 10. Изучите самостоятельно, что такое остаток от деления и как его применить для большего числа разрядов. Типы получаемых переменных - unsigned int (вернее, даже char, 8 бит), целые. Аппаратно деление занимает не так уж много времени.
Вышенаписанное к тому, чтобы было понятие, что же происходит с числами.
Далее, дисплей выводит символы в соответствии с ANSI-кодами, по крайней мере, для цифр и латиницы. Чтобы получить код цифры из значения переменной, нужно просто прибавить (логическое побитное ИЛИ) к переменной код символа '0', то есть, 0х30.
Фсё, как бы...
Кстати! Это там у вас не Arduino-плата ли??
Последний раз редактировалось NewWriter; 29.06.2016 в 22:59.
|
|
|
|
29.06.2016, 22:39
|
|
Гражданин KAZUS.RU
Регистрация: 16.02.2012
Сообщений: 441
Сказал спасибо: 89
Сказали Спасибо 735 раз(а) в 149 сообщении(ях)
|
Re: Правильный вывод переменной на lcd1602a
у stm32 вроде есть аппаратный делитель, выгоднее делить на степени 10, выводить в буфер в ОЗУ, и буфер писать в LCD
|
|
|
|
29.06.2016, 23:14
|
|
Прописка
Регистрация: 29.03.2007
Сообщений: 185
Сказал спасибо: 11
Сказали Спасибо 1 раз в 1 сообщении
|
Re: Правильный вывод переменной на lcd1602a
Нет, не ардуино. Я купил макетку VT2429 и спаял на неё мк и обвеску. Получилось как бы самое минимальное discovery))
|
|
|
|
29.06.2016, 23:40
|
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: Правильный вывод переменной на lcd1602a
Ну, слава богу, не ардуина.. значит, "наш человек"
|
|
|
|
30.06.2016, 10:42
|
|
Вид на жительство
Регистрация: 09.12.2009
Адрес: Россия, Тула
Сообщений: 377
Сказал спасибо: 192
Сказали Спасибо 156 раз(а) в 99 сообщении(ях)
|
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;
}
// |
|
|
|
|
30.06.2016, 11:53
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.10.2007
Сообщений: 2,760
Сказал спасибо: 1,105
Сказали Спасибо 1,037 раз(а) в 569 сообщении(ях)
|
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.
|
|
|
|
30.06.2016, 13:15
|
|
Гражданин KAZUS.RU
Регистрация: 16.02.2012
Сообщений: 441
Сказал спасибо: 89
Сказали Спасибо 735 раз(а) в 149 сообщении(ях)
|
Re: Правильный вывод переменной на lcd1602a
в Cortex-M3 есть аппаратный делитель, в М0 - нет. Непонятно какой у т.с.
некоторые методы описаны там: http://we.easyelectronics.ru/Soft/pr...ye-chisla.html
Последний раз редактировалось zöner; 30.06.2016 в 13:17.
|
|
|
|
30.06.2016, 14:19
|
|
Прописка
Регистрация: 10.03.2016
Сообщений: 114
Сказал спасибо: 14
Сказали Спасибо 46 раз(а) в 41 сообщении(ях)
|
Re: Правильный вывод переменной на lcd1602a
Там по времени выполнения не столь велика разница. И чипа re в М0 нет. И вообще как-то всё мутно, 512К не хватает на sprintf.
|
|
|
|
30.06.2016, 23:41
|
|
Заблокирован
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,486
Сказал спасибо: 396
Сказали Спасибо 2,221 раз(а) в 1,319 сообщении(ях)
|
Re: Правильный вывод переменной на lcd1602a
Ну топикстартера наверняка что-то типа 103 или 107, судя по всему, а в них можно делить, не боясь.
Однако, при выключенной оптимизации написанная операция деления заменяется инструкциями аппаратного умножения UMULL - unsigned multiplier 32 х 32 бит с 64 битным результатом, и инструкциями логического сдвига LSRS, суммирования, вычитания.
И лишь при включении оптимизации по размеру можно увидеть уже инструкцию аппаратного деления UDIV - Unsigned division. Там еще будут инструкции MLS - 32-битного умножения с вычитанием.
Из этого видно, что аппаратный делитель используется далеко не так часто, как написанная операция деления.
Последний раз редактировалось NewWriter; 30.06.2016 в 23:51.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 19:35.
|
|