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

Рекомендуемые сообщения

Доброго дня всем.

Такое вот дело, нужно сделать некую железку, функционал сейчас не важен. Имеется на руках плата Nucleo-F401RE и дисплей.

Поскольку сделан он под Ардуину, а платы Nucleo имеют (в том числе) совместимую с ним разводку разъемов под периферию, дисплей втыкается без переделки, как есть. Все это и красиво и удобно, но вот шина данных, а в данной реализации дисплея используется 8-битная шина, не попадают пин-в-пин с портами МК. Переделка не планируется, надо исходить из то, что есть. Следовательно имеем такую картину:

LCD_D7 - PA8
LCD_D6 - PB10
LCD_D5 - PB4
LCD_D4 - PB5
LCD_D3 - PB3
LCD_D2 - PA10
LCD_D1 - PC7
LCD_D0 - PA9

Чтобы отправить байт в дисплей, нужно его раскидать побитно. Моя реализация работает, вот так она выглядит:

void lcd35_setData(unsigned char lcd35_data)
{
// Share data between data bus pins.
  unsigned int d7, d6, d5, d4, d3, d2, d1, d0;
  
// Clear data bus pins.  
  GPIOA->BSRR = (GPIO_BSRR_BR10 | GPIO_BSRR_BR9 | GPIO_BSRR_BR8);
  GPIOB->BSRR = (GPIO_BSRR_BR10 | GPIO_BSRR_BR5 | GPIO_BSRR_BR4 | GPIO_BSRR_BR3);
  GPIOC->BSRR = GPIO_BSRR_BR7;
  
// Split bits
  d7 = (unsigned int)((lcd35_data & 0x80) << 1);
  d6 = (unsigned int)((lcd35_data & 0x40) << 4);
  d5 = (unsigned int)((lcd35_data & 0x20) >> 1);
  d4 = (unsigned int)((lcd35_data & 0x10) << 1);
  d3 = (unsigned int)(lcd35_data & 0x08);
  d2 = (unsigned int)((lcd35_data & 0x04) << 8);
  d1 = (unsigned int)((lcd35_data & 0x02) << 6);
  d0 = (unsigned int)((lcd35_data & 0x01) << 9);
  
// Set data
  GPIOA->ODR |= (d7 | d2 | d0);
  GPIOB->ODR |= (d6 | d5 | d4 | d3);
  GPIOC->ODR |= d1;
}

Может можно сделать оптимальнее? Это прилично замедляет вывод изображения, особенно если выводить картинку целиком (480*320 по 2 байта на пиксель). Я всегда подстраивал железо под удобство написания кода, а тут вот вынужден извращаться.

Кстати, гугление по данному экрану (Renesas R61581) выводило только на ардуинистов, неужели никто не подключал его к другим железкам?! Он, говорят, почти совместим с ILI9488. Я бегло прошелся по протоколу оного, да, есть такое, но в команды не углублялся. Вроде все отличие кроется в инициализации.

P.S. Сейчас вот подумал, может сперва стоило привести lcd35_data к соответствующему типу, а потом уже применять маску и сдвиг.

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Разве сами порты ремапятся? Была утром такая мысль, но прошелся по общему описанию и не нашел упоминания об этом.

Спасибо, сейчас гляну глубже.

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

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

да не, это я чето загнал на ночь глядя. Надо подумать. Должно как то решаться проще

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

Сделал через бит-бандинг, что раза в 2 ускорило вывод картинки.

void lcd35_setData(unsigned char lcd35_data)
{
  LCD35_D0 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D1 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D2 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D3 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D4 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D5 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D6 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D7 = (lcd35_data & 1);
}

LCD35_D0..D7 - прямые адреса битов.

Другие варианты? Или этот можно как-то оптимизировать? Если бы этот был ПИК, можно было бы без маски обойтись асм вставкой: сдвиг в С и присвоение. А тут не знаю как.

Глянул, здесь тоже есть сдвиг через С, команда RRX, но пока не знаю как ее можно применить.

Изменено пользователем Zhuk72
Ссылка на комментарий
Поделиться на другие сайты

да асм как бы тут тоже работает. Просто вставкой в код можно оформить. Но дело не в этом. Дисплей все равно будет работать тормознуто, потому как по хорошему надо из буфера DMA в порт мутить, а такая схема не позволит. Либо надо перекодированный буфер делать.

Я в свое время делал так - создавал 2 буфера-массива равных по обьему самому большому символу из знакогенераторной таблицы. Потом обсчитывал битовую маску для нужного символа и отправлял по DMA на экран. Пока шла отправка, обсчитывался второй буфер. Он успевал обсчитываться быстрее чем дисплей успевал принимать. Потом указатель на буфер менял и пулял его в ДМА. И так по кругу. Получалась неразрывная передача и дисплей работал шустро. Если все это делать битбэнгом, то получится раз в 20 медленнее. Попробуйте реализовать такой механизм с перекодировкой. У 401-го ядро мощное, если его не отвлекать побитной отправкой, то скорее всего получится значительно ускорить процесс.

Можно поступить чуть хитрее (смотря конечно что у вас за задача). Можно сразу кодировать символьную таблицу и битмапы с учетом перестановок. Тогда вам не придется постоянно переставлять биты. Простенький скрипт подготовки и у вас в руках готовые перекодированные битмапы. Проблема только будет с адресами и графическими примитивами. Но это уже значительное сокращение обьема расчетов.

Вообще конечно вы сильно усложняете себе задачу и всего то из-за трудностей с простеньким переходничком. Но эт дело хозяйское конечно. Я бы просто порезал пины на борде дисплея и проводками перекинул биты в нужные мне места. Это делов - 30 минут с паяльником. А головняков на неделю бы снял

вот тута вот можно дороги резануть и тонким проводом перепаять на нужные места. Дисплей это не испортит

2018-03-12_00-02-29.png.d189de092985299d3f6bd06948f6c399.png

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

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

Я не имел дела с его асм, поэтому надо разбираться.

Данные надо перекодировать перед отрицательным строб-сигналом. Как тут ДМА поможет? Мне на него одинаковые блоки 39*13 нужно выводить, аудиоспектроанализатор, поэтому мне кажется скорости хватит, адреса позиций фиксированные, выводимая информация тоже.

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

ну тады я пожалуй все советы раздал. Осталось думать с вашей стороны

ДМА может тактироваться таймером, а таймер в свою очередь может выдавать и строб сигналы (как вариант)

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

Вариант с асм еще быстрее работает. Не так, чтобы огого, но быстрее. Сам удивился, что удалось.

/* Это указывается в объявлении файла */
register APSR_Type apsr __asm("apsr");

void lcd35_setData(unsigned char lcd35_data)
{
  __asm("rrx lcd35_data, lcd35_data");
  LCD35_D0 = apsr.b.C;
  __asm("rrx lcd35_data, lcd35_data");
  LCD35_D1 = apsr.b.C;
  __asm("rrx lcd35_data, lcd35_data");
  LCD35_D2 = apsr.b.C;
  __asm("rrx lcd35_data, lcd35_data");
  LCD35_D3 = apsr.b.C;
  __asm("rrx lcd35_data, lcd35_data");
  LCD35_D4 = apsr.b.C;
  __asm("rrx lcd35_data, lcd35_data");
  LCD35_D5 = apsr.b.C;
  __asm("rrx lcd35_data, lcd35_data");
  LCD35_D6 = apsr.b.C;
  __asm("rrx lcd35_data, lcd35_data");
  LCD35_D7 = apsr.b.C;
}

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

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

оптимальным вариантом для вас было бы наверное применение дисплея с SPI интерфейсом. Чтото типа ILI9341. У него на 12 мегагерцах запросто 10 полных отрисованных кадров в секунду получается без всяких бубнов. И гораздо все проще и с данными и с тактированием. Оно все на автомате. И всего 5 проводков. Но видимо уже поздно метаться

Сколько у вас сейчас кадров выходит в секунду таким способом?

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

Что-то я поторопился, асм не работает. Не все равно надо что-то переделывать, пока не знаю что именно. Кромсать плату... могу, завтра прикину по контактам, чтобы на один порт село.

SPI там имеется, но он скорее всего на тачскрин и/или сд-карту. Документа на плату нет, хз что к чему подведено.

ФПС не измерял, позже проверю.

Изменено пользователем Zhuk72
Ссылка на комментарий
Поделиться на другие сайты

Экран заполняется за 0.55335 секунды, т.е. меньше 2 fps :mellow:

Преобразование данных происходит меньше чем за 1 мкс.

Вот процедура отправки байта. Как здесь можно применить ДМА? Хотя... Сейчас подумаю.

Скрытый текст

 


void lcd35_sendbyte(unsigned char byte_out, unsigned char datacom)
{
  if(datacom == DTA) LCD35_DATA;
    else LCD35_CMD;
  LCD35_CS0;
  lcd35_setData(byte_out);
  lcd35_tx();
  LCD35_CS1;
}

void lcd35_tx(void)
{
// Transmit sequence
  LCD35_WR0;
// Master sends
  LCD35_WR1;
// Slave receives
}

void lcd35_setData(unsigned char lcd35_data)
{
  LCD35_D0 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D1 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D2 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D3 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D4 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D5 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D6 = (lcd35_data & 1);
  lcd35_data >>= 1;
  LCD35_D7 = (lcd35_data & 1);
}

 

 

 

P.S. Этот ТХ надо внутрь засунуть, вызов и возврат - лишнее. Раньше там еще задержки были, поэтому и выделил в отдельный код.

P.P.S. Ну вот, теперь меньше 0.5 секунды, 2 fps выжал.

Изменено пользователем Zhuk72
Ссылка на комментарий
Поделиться на другие сайты

SPI у этого дисплея конечно нет, а что куда идет написано белым по красному. 2fps это пешком быстрее. Лагать все будет, даже перерисовка простых спрайтов с легкой анимацией даже в участках. Как бы вроде и будет работать и вроде как и плавно, но при просмотре такой картинки будет какое то странное ощущение отвращения.

Попробуйте перепаять дороги. Не получится поднять fps выше 5 кадров, лучше заменить дисплей на более подходящий. Как говаривал мой дедушка - если чувствуешь, что чтото идет не так, лучше вовремя остановись и подумай

SPI дисплей гораздо проще и быстрее, и по ресурсам экономнее со всех сторон. Правда 3 дюйма врятли получится найти, максимум что я встречал - 2,7 кажется, или 2,4. Поменьше в общем

На сколько я помню у 401-ых камней больше никаких подходящих интерфейсов на эту тему нет

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

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

С SPI есть 2.8" (240*320) на 9341 и есть 3.5" (320*480) не понятно на чем, для Raspberry. Времени на ожидание заказа нет. Посмотрю сегодня нет ли чего на месту проживания.

Неужели такой скорости не хватит для того, чтобы раз в секунду отобразить 10 столбиков разной высоты?

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

можно просто посчитать на пальцах. Фрэймрэйт у вас есть, значит производительность в пикселях известна. Размеры ваших спрайтов известны. Простая арифметика. Если время отрисовки будет больше 0,1 секунды, будет уже не комфортно

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

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

Куплю на месте или закажу сегодня 2.8" SPI на всякий случай, а пока буду долбить что есть. Еще с Фурье разбираться надо, я в нем ни бум-бум.

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

да фурье это не так уж и сложно. Я когда-то давно разбирался, лет 8 назад. За день осилил. Главное принцип понять

Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух

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

Расписал адресацию столбцов, чтобы программно не преобразовывать, а сразу загружать в регистры и тут пришел к выводу, что мне нужно организовать указатель на массив функций. Одно из моих слабых мест в Си :( Массивов 10, в каждом по 4 функции.

Вызывающая функция выглядит примерно так:

void lcd35_setX(unsigned char column)
{
  unsigned char data_cnt = 4;
  
  set_colpag(SCOL); // send set_column_address command
  LCD35_CMD;
  do
  {
    *(*(func + column) + data_cnt);	// Это моя фантазия
    LCD35_WR0;// Master sent
    LCD35_WR1;// Slave recieved
    LCD35_DATA;
  } while(--data_cnt);
  LCD35_CS1;
  LCD35_CMD;
}

Указанное как "фантазия" и есть желаемое мной. Т.е. по индексу массива column [10] выбираются массивы func[4], вызываемые внутри цикла.

Как их объявить? Помогите пожалуйста.

 

Update.

Попробовал так. Объявил 2-мерный массив, компилятор не ругается.

void *col[10][4] = {{column1_1,column1_2,column1_3,column1_4},
                    {column2_1,column2_2,column2_3,column2_4},
                    {column3_1,column3_2,column3_3,column3_4},
                    {column4_1,column4_2,column4_3,column4_4},
                    {column5_1,column5_2,column5_3,column5_4},
                    {column6_1,column6_2,column6_3,column6_4},
                    {column7_1,column7_2,column7_3,column7_4},
                    {column8_1,column8_2,column8_3,column8_4},
                    {column9_1,column9_2,column9_3,column9_4},
                    {column10_1,column10_2,column10_3,column10_4}};

Слегка изменил вызов. Но вот как в нем этот массив использовать - не знаю.

void lcd35_setX(unsigned char column)
{
  unsigned char func;
  
  set_colpag(SCOL); // send set_column_address command
  LCD35_CMD;
  for(func = 0; func < 4; func++)
  {
    col[column][func]();		// на нее компилятор ругается
    LCD35_WR0;// Master sends
    LCD35_WR1;// Slave receives
    LCD35_DATA;    
  }
  LCD35_CS1;
  LCD35_CMD;
}

Сами элементы массива выглядят так:

void column1_1(void)
{
  GPIOA->BSRR = (BR8 | BR10 | BR9);
  GPIOB->BSRR = (BR10 | BR4 | BR5 | BR3);
  GPIOC->BSRR = BR7;
}

Остальные 39 такие же по форме, но со своими значениями.

 

Update number 2.

Изменил объявления массива на void (* col[10][4])(void); и вот такой вызов функции компилятор принял: (*col[column][func])();        Не знаю насколько это правильно.

В железе завтра проверю, надо еще кое-что дописать.

Изменено пользователем Zhuk72
Ссылка на комментарий
Поделиться на другие сайты

  • 1 месяц спустя...

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • Мне показалось, что я ответил на Ваш вопрос... но видимо не убедительно... хорошо, беру такой LOGO! 12/24RC   (6ED1 052-1MD00-OBA5), последний раз на него питание подавали в году так эдак в 2010_м... достал его из закромов, подал питание и программа стартанула в штатном режиме... единственно как и писал ранее часы сброшены до заводской установки... надеюсь теперь Вас убедит то, что девайс если сохранил программу 14 лет, то особых поводов у него нет, чтобы её сбрасывать в дальнейшем. 
    • Точно не могу сказать, не разбирал я не разу Лого, по факту должна сохраниться. Много чего разбирал, не было проблем при рассоединении этажерок.
    • Это только по одному плечу? По второму плечу нормально?
    • а ответ на вопрос темы от Вас будет? Т.е. сохранится ли рабочая программа при разъединении верхней и нижней плат?  Потому как если ответ однозначно положительный, то этот геморрой с самопальным шнурком мне нафиг не нужен. 
    • Всем привет, комрады!  Пользуюсь данным усилителем чуть больше 13 лет, все устраивает. Питается от ТС-180-2. Понадобилось заменить этот трансформатор на другой поменьше, думаю на торе заказать, а какой именно по характеристикам - пытаюсь разобраться. Стыдно признаться, ни разу не смотрел какие напряжения, какие токи в усилителе... собрал - включил и забыл. Сейчас придется разбираться.  Правильно ли понимаю что общая мощность транса = токи и напряжения каждой лампы, + накалы?  Тогда судя по даташитам, 6н1п на два канала - (250в*0,0075мА)*2 + (6,3в*0,6А)=3,75Вт+ 3,8Вт=~7,5Вт.  А 6п14п=(250в*0,048А+250В*0,005А+6,3В*0,76А) * 2 = (12Вт+1,25Вт+4,8Вт ) * 2 лампы = 18Вт * 2  = 36Вт. Хотя две лампы 6п14п питаются от одной обмотки 6,3в.  Итого меньше 50 Вт, ну и с запасом небольшим 60-80Вт.  А вот как указать в заказе? Схема питается 275в, то есть вторичку делать 200в, а ток?  То есть две выходных лампы уже 100мА, запас если делать как правило 10-20%, то примерно 200в * 120мА ?  НУ с накалом тут проще) Задача в том что нужно как можно менее габаритный трансформатор, увы, ТС-180 не влезает в новую конструкцию. Ну и для понимания, сейчас начну усилитель для наушников собирать, пригодится.    
    • Лучше не надо.  Буфер добавляет всего 6 копеечных деталей а надëжность и мощность увеличит в разы, и даст работать даже с низкоомными наушниками. Даже 32 Ом наушники один ОУ из JRC4558 не потянет. 
    • Какова площадь поверхности данного радиатора?
  • Похожий контент

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