Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт мар 22, 2018 19:13:03

а какова максимальная скорость вывода графики ST7920 на весь экран в режиме SPI?
в смысле сколько "кадров" в секунду...

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт мар 22, 2018 21:13:01

Думается, те же ~20 кадров в секунду будут, что и при параллельном интерфейсе. Тут не протокол ограничивает скорость. Нужно (из опыта) выжидать около 50мкс после операции записи (в даташите будет даже больше, надо смотреть). А за это время данные любым протоколом загнать не проблема.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Пт мар 23, 2018 05:17:01

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

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт июл 19, 2018 07:52:23

Оказалось кстати на него не так уж и сложно рисовать. Здесь есть подробная инструкция http://tehnopage.ru/vyvod-kartinki-na-displey-128x64

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт авг 30, 2018 22:58:10

Тоже сделал либу для данного дисплея с использованием экранного буфера в ОЗУ - 1 кб.
С выводом текста, вертикальных и горизонтальных линий, а так же выводом картинок.
Вывод в дисплей - по параллельному интрефейсу, отправка в таймере каждые 50 мкс.
И столкнулся буквально сегодня с тормозным дисплеем.
Так дисплей отказался рисовать картинку нормально при паузе в 50 мкс между отправками.... Нормально завелся аж при 68 мкс....
Хотя предыдущий работал без артефактов на 37 мкс паузах.... Вот такие пироги

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Сб сен 07, 2019 16:51:13

goldenandy писал(а):Тоже сделал либу для данного дисплея с использованием экранного буфера в ОЗУ - 1 кб.
А ее можно где-нибудь увидеть?

goldenandy писал(а):И столкнулся буквально сегодня с тормозным дисплеем.
Так дисплей отказался рисовать картинку нормально при паузе в 50 мкс между отправками.... Нормально завелся аж при 68 мкс....
Хотя предыдущий работал без артефактов на 37 мкс паузах.... Вот такие пироги
Ну, так не зря в ДШ заявлено 72 мкс - при такой паузе изготовитель гарантирует работоспособность. А все, что меньше - типичный оверклок, может и заработать, но не обязано.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Сб ноя 30, 2019 02:30:48

Озадачился я с этим экранчиком, уж прям не знаю как быть.
Захотелось мне поделку, да с экраном помордастее. Остановившись на обычном ЖК, выбрал китайский как относительно недорогой за 6уе ST7920 12864 93х70мм(видимые 72х40мм).
Не без недостатков, уж очень большой, но по фоткам видно можно обпилить лишнее.
Решил всётаки заказать(по очередной распродаже, раньше всё равно денег не было, на прошлых другим барахлом закупился).
Ну и чтоб время не терять вспомнил о протеусе.

Под дня потратил чтоб заставить работать библиотеку. Как оказалось LCD12864A.dll md5: 86BE444AA4B60E359C29CD9F066E5979 с Proteus 8 не работает вообще, после этоже и нагуглилось.
Были подозрения что есть и другие версии, но начал перебирать архивы и контрольные суммы, и библиотека всётаки одна и работает только в 7 версии.

Тут я попытался купить этот экран в росии, но обломался, их нет. Тыкаясь по гуглу, магазины с подобным так и не нашлись. Разок натыкался, но на синий, оно мне не надо.

Забросив это на пару недель, поставил Proteus 7.10 (что оказалось не так то просто, комп к этому был не готов).
Имея 3 примера с разных сайтов, они начали работать как надо, выдавая картинку на экран в симуляторе.
Накидал схемку на ардуино U8glib_Arduino-1.19.1, там где к экрану 3 проводка, и облом, экран не кажет.
Подумал на кривой код, но я же готовый пример впихнул. Присмотрелся, а в примерах соединение параллельное.
Получается что этот симулятор мало того что только в старой версии проги работает, так ещё и только в паралельном режиме.

Как это паралелить я уже не знаю, выдрать какие ноги цеплять из исходника, мне както не очень удавалось. Даже не знаю может ли U8glib так работать, на гуглокоде ничего толком не понять, и вообще этот ресурс давно закрыт.
Попытки нагуглить готовое под ардуину тоже не нашлись.

Может коты подскажут как разрулить.
Проще всего подождать экран и живьём.
Но хотелось бы уже с чегото начать, хотябы рисовать значки.
Если можно тем же способом подключить паралельно для симулятора, а потом просто чуть подправить код освободив ноги, то вариант сгодился бы, да не знаю как.
Можно было и параллельный режим оставить, наверняка он быстрее, а я всё равно хочу несколько МК поставить, а этим только экран таскать.

В итоге всё упирается в то, что экран показывает мусор и библиотека вылетает

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Сб янв 04, 2020 19:28:05

:shock:

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт апр 09, 2020 17:31:27

Ребята, а никто не пытался либу Вадиматорчика в кокосе запустить?

Добавлено after 4 hours 51 minute 51 second:
Интересует возможность использования HAL, так как большая часть проекта написано на HAL.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт авг 06, 2020 00:30:10

Народ, игрался я с этим индикатором, решил поделиться опытом новичка (пробую на зуб и STM32 и графические экраны, от нокии 3310, от семена А52 и этот вот), может кому пригодиться
1: к вопросу о количестве кадров: на STM32f103 самопальной библиотеке (не без кусков кода уважаемого Вадиматоричика) с программным SPI получилось 25 FPS с учетом того, что часть времени тратится на сбор информации с АЦП (мои хотелки).
2; на скорость работы контроллера экрана можно влиять - в даташите временные интервалы задержек сигналов не просто указаны, а указаны с поправкой на частоту работы самого ST7920 - а именно 540кГц. при этом есть график зависимости тактовой частоты контроллера от задающего резистора. при 5В питания должен быть впаян 33кОм. вся штука в том, что мой экран с Али пришел с резистором 27кОм, но когда я ткнул в эти цепи осциллографом, то увидел что там всего 408кГц. наши братья из Китая опять что-то нахитрили. В итоге я впаял резюк на 20кОм и частота выросла до 460кГц. по затратам времени на отрисовку всего экрана (а мерял я программно счетчиком тактов ядра МК STM32) без мусора на экране смог построить картинку не за 2,3 миллиона тактов как сначала а уже за 1,8 миллиона (частота МК 56МГц). дальше подымать частоту ST7920 не пробовал, хотя по даташиту максимальная частота контроллера экрана 600кГц. при текущей скорости обновления уже мылятся пиксели.
еще одна засада с этим экраном: хотя он и работает с сигналами STM32 - 3,3В, при этом от питания в 3,3В работать отказался, пока я 5В не подал, думал что с Али прислали труп. (при этом тогда еще про замену резистора и не помышлял). хотя по даташиту на ST7920 питание от 2,7В. такой вот небольшой опыт.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Вс фев 28, 2021 20:46:44

goldenandy писал(а):Тоже сделал либу для данного дисплея с использованием экранного буфера в ОЗУ - 1 кб.
А ее можно где-нибудь увидеть?

Обещанного три года ждут :)
Посему - некропостинг - лучше поздно, чем никогда.

st7920.h
Спойлер
Код:
#ifndef _DISPLAYDRIVER_7920_BLOCK_
#define _DISPLAYDRIVER_7920_BLOCK_

   /*****************************************************************************************
   Драйвер для взаимодействия с дисплеем на контроллере ST7920
   Особенность данного контроллера - пауза между посылками команд и слов данных.
   Согласно документации - пауза 72 мкс.
   По факту на некоторых дисплеях можно добиться работоспособности вплоть до 35мкс.
   Для минимизации потребления процессорного времени алгоритм отправки данных
   в дисплей реализован через периодический вызов процедуры внутренней синхронизации
   с периодичностью 72мкс. От основной программы требуется только периодический вызов
   процедуры синхронизации, например, из прерывания таймера. Остальные действия по отправке
   данных на экран будут прозрачны для основной программы.
   *****************************************************************************************/
   
   /*****************************************************************************************
   ВНИМАНИЕ! В данном драйвере отсутствуют процедуры физического общения с дисплеем!
   Эти процедуры должны быть описаны отдельно.
   Это 2 процедуры - одна отвечает за управлением пином RST дисплея,
   вторая - за отправку одного или двух байт данных/команды в дисплей.
   Как будет реализована такая отправка - ногодрыгом, через аппаратный SPI на ожиданиях/прерываниях/DMA
   и т.д. - драйвер не знает.
   Для работы с дисплеем предоставлены 2 процедуры - очистки дисплея и включения/выключения пикселя.
   Вся остальная работа выполняется в процедуре обслуживания, которую необходимо вызывать из
   основноай программы с периодичностью 72мкс.
   *****************************************************************************************/
   
   #include <stdint.h>

   //_____
   /******** Процедуры физического взаимодействия МК с дисплеем     ********/
   /******** Процедуры должны быть реализованы в основной программе ********/
   
   extern void ST7920_setResetLevel(uint8_t resetLevel);
   // установка уровня Reset. При инициализации железа начальный уровень - высокий.
   
   extern void ST7920_sendData(uint8_t dataBuf[], uint8_t count, uint8_t dataFlag);
   // Установка флага данные/команда (dataFlag), отправка count байт данных из буфера dataBuf в дисплей
   // _____
   // Параллельное подключение дисплея    
   // (Вывод PSB через 4к7 подключен к питанию)
   // ----------
   // 1. На линии RS выставляется признак данных/команды - флаг dataFlag (1-данные, 0-команда)
   // 2. Линия R/W прижата к общему прводу, мы данные из дисплея не читаем
   // 3. Через время не менее 10 нс* строб E переводится в 1.
   // 4. На выводах D0-D7 выставляются данные.
   // 5. Через не менее чем через 140 нс после поднятия строб E переводится в 0.
   //   При этом данные на D0-D7 должны присутствовать на шине не менее чем за 40нс до опускания строба.
   // 6. После опусания строба данные на шине и сигнал R/S должны присутствовать без изменений еще 20 нс
   // _____
   // Последовательное подключение дисплея
   // (Вывод PSB подключен к общему проводу)
   // ----------
   // Линия RS выступает как сигнал CS - Chip select,  idle-уровень - низкий, активный - высокий.
   // Линия E остается сигналом строба (CLK), активный уровень низкий, idle - высокий
   // Линия R/W - данные (DATA).
   // Данные считвываются с линии DATA в момент перехода CLK из низкого уровня в высокий.
   // AVR.SPI:
   //   SPCR.CPOL=1 (SCK is high when idle, Leading edge is falling), 
   //   SPCR.CPHA=1 (Sample on trailing edge)
   // Первый такт CLK должен начинаться не ранее чем через 60 нс* после активации CS.
   // Сигнал CS снимается не ранее, чем через 60 нс после заднего фронта CLK
   // Байт данных передается в дисплей за 24 такта CLK (передача 3х байт)
   // Период сигнала CLK - не менее 600 нс ( 1.66(6) МГц), длительность низкого и высокого уровней - не менее 300 нс
   // Данные на линии DATA должны быть выставлены минимум за 40 нс до перехода CLK из низкого в высокий уровень
   // и должны там удерживаться еще не менее 40нс
   // 1. Выставить высокий уровень CS.
   // 2. Последовательно передать 3 байта:
   //   2.1. Первый байт: 1 1 1 1 1 RW DC 0
   //      DC - признак данных или команды, 1-данные, 0-команда
   //      RW - 0-запись данных (мы данные из дисплея не читаем)
   //      Итого: 0xF8 - для команды, 0xFA - для данных
   //   2.2. Второй байт: D7 D6 D5 D4 0 0 0 0
   //   2.3. Третий байт: D3 D2 D1 D0 0 0 0 0
   // 3. Выставить низкий уровень CS.
   // _____
   // * 1 такт AVR при 8 МГц = 125 нс, при 16 МГц = 62,5 нс
   // ** SPI clock - проверялось  на 1, 1.125, 1.25, 1.5, 1.75 МГц. На 2МГц завелось с мусором, на 2.25 МГц не завелось.
   
   
   //_____
   /******** Процедуры управления дисплеем ********/
   
   void ST7920_init(void);
   // Установка флага необходимости сброса и инициализации дисплея.
   // Сампроццесс сброса и инициализации пройдет в процессе периодических вызовов процедуры внутренней синхронизации

   void ST7920_reInit(uint8_t clearRAM);
   // Установка флага необходимости переинициализации контроллера дисплея без подачи сигнала сброса.
   // Очиста видеопамяти - опционально
   
   void ST7920_sync(void);
   // Процедура внутренней синхронизации, должна вызываться с периодичностью 72 мкс.
   
   uint8_t ST7920_getIdleFlag(void);
   // процедура проверки статуса обновления, возвращает 1, если все данные на дисплее обновлены.
   
   //_____
   /******** Процедуры вывода графики ********/

   void ST7920_clearDisplay(void);
   // очистка видеопамяти
   
   void ST7920_putPixel(uint8_t x, uint8_t y, uint8_t color);
   // вывод пикселя в видеопамять. color ==1 - пиксель будет зажжен, ==0 - погашен
   
#endif    //_DISPLAYDRIVER_7920_BLOCK_


st7920.c
Спойлер
Код:
#include "st7920.h"
#include <string.h>

typedef enum {
   dpOff = 0,
   dpReset1,
   dpReset2,
   dpInit1,
   dpInit2,
   dpInit3,
   dpScanChanges,
   dpSetRow,
   dpSendCol,
   dpSendData
   } displayPhaseType;
   
// режимы дисплея
static volatile displayPhaseType displayPhase = dpOff;

// организация видеопамяти - 32 строки по 16 слов.
// Итого 256*32 - как принято в архитектуре ST7920
// При этом левый блок 128*32 - верняя часть реального дисплея, правый - нижняя часть.
// так сделано для оптимизации вывода, ибо он должен происходить максимально быстро.
static volatile uint16_t videoram[32][256/16];

// массив флагов с признаками необходимости обновления обновления
static volatile uint8_t updateFlags[32];

// просто константы
static const uint8_t masks[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
   
// флаг наличия обновлений
static volatile uint8_t needUpdate = 0;

#define AS_DATA      1
#define AS_COMMAND   0   

void ST7920_init(void){
   displayPhase = dpReset1;
}

void ST7920_reInit(uint8_t clearRAM){
   if (clearRAM) memset((void*)videoram, 0x00, sizeof(videoram));
   memset((void*)updateFlags, 0xFF, sizeof(updateFlags));
   displayPhase = dpInit1;
}


void ST7920_sync(void){
   static uint16_t delay = 0;
   static uint8_t data[2];
   static uint8_t row = 0;
   static uint8_t col = 0;
   if (delay) {
      delay--;
      return;
   }
   switch (displayPhase) {
      case dpOff:
         return;
         //break;
      case dpScanChanges:
         if ( !needUpdate ) return;
         if ( row == 0 ) needUpdate = 1;
         while (row<32) {
            if (updateFlags[row]) {
                  // нужно обновлять данные в дисплей....
                  col = 0;
                  displayPhase = dpSetRow;
                  updateFlags[row] = 0;
                  break;
               }
            row++;
         }   // while row < 32
         if (displayPhase == dpScanChanges) {
            if (row == 32) {
               row = 0;
               if (needUpdate==1) needUpdate = 0;
            }
            break;
         } // if (displayPhase == dpScanChanges)
         // break; - тут брейк не нужен, мы нашли неотправленные данные и едем их отправлять
      case dpSetRow:
      case dpSendCol:
         if (displayPhase == dpSetRow) data[0] = 0x80 | row;
         else data[0] = 0x80; // col == 0
         ST7920_sendData(data, 1, AS_COMMAND);
         displayPhase++;
         break;
      case dpSendData:
         data[0] = ((uint16_t)videoram[row][col])>>8;
         data[1] = videoram[row][col] & 0xFF;
         ST7920_sendData(data, 2, AS_DATA);
         col++;
         if (col==16) displayPhase = dpScanChanges; // если дошагали до конца строки - возвращаемся к сканированию.
         break;
      case dpReset1:
         memset((void*)videoram, 0x00, sizeof(videoram));
         memset((void*)updateFlags, 0xFF, sizeof(updateFlags));
         needUpdate = 2;
         ST7920_setResetLevel(0);
         delay = 1000; // 72 ms   - 1000 * 72 us = 72 ms
         displayPhase++;
         break;
      case dpReset2:
         ST7920_setResetLevel(1);
         delay = 50; // 3.6 ms   - 50 * 72 us = 3.6 ms
         displayPhase++;
         break;
      case dpInit1:
      case dpInit2:
      case dpInit3:
         switch ((uint8_t)displayPhase) {
         case dpInit1:
            data[0] = 0x30; // Standard mode
            break;
         case dpInit2:
            data[0] = 0x01; // Clear text display
            break;
         case dpInit3:
            data[0] = 0x36; // Enter extended mode
            break;
         }
         ST7920_sendData(data, 1, AS_COMMAND);
         delay = 100;  //100 * 72 us = ~7.2 ms   
         displayPhase++;
         row = 0;
         col = 0;
         break;
   } // switch (displayPhase)
}


void ST7920_clearDisplay(void){
   // очистка видеопамяти
   memset((void*)videoram, 0x00, sizeof(videoram));
   memset((void*)updateFlags, 0xFF, sizeof(updateFlags));
   needUpdate = 2;
}
   
void ST7920_putPixel(uint8_t x, uint8_t y, uint8_t color){
   uint16_t xMask;
   uint8_t xIndex;
   if (x > 127 || y > 63) return;
   y &= 0x3F;
   xIndex = x/16;
   x = 15-(x & 0x0F);
   if (y>31) xIndex += 8;
   y &= 0x1F;
   xMask = masks[x & 0x07];
   if (x>7) xMask <<= 8;
   uint16_t vRam = videoram[y][xIndex];
   if (color) videoram[y][xIndex] |= xMask;
   else videoram[y][xIndex] &= ~xMask;
   if (vRam == videoram[y][xIndex]) return;
   updateFlags[y] = 1;
   needUpdate = 2;
}

uint8_t ST7920_getIdleFlag(void){
   return needUpdate==0 || displayPhase==dpOff;
}


И некоторые размышлизмы по подключению - вот тут...

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт апр 15, 2021 12:35:51

Подскажите, пожалуйста, а как можно вывести символ или строку шрифтом 8х8 (например, из font8x8.h Вадиматоричик`а) без использования буфера? Что-то никак не допру, как это сделать...

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт апр 15, 2021 16:12:19

Pretender, выодить построчно, по одному байту. Каждый раз задавая адрес.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт апр 15, 2021 21:08:51

Подскажите, пожалуйста, а как можно вывести символ или строку шрифтом 8х8 (например, из font8x8.h Вадиматоричик`а) без использования буфера? Что-то никак не допру, как это сделать...

Без буфера слишком хлопотно. Индикатор заполняется фрагментами строк по 16 бит, это шире символа 8х8, придется зачитывать фрагмент строки из индикатора и «сливать» с изображением, которое уже присутствует. ST7920 позволяет зачитать буфер только в параллельном режиме.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Чт апр 15, 2021 22:06:28

lizard66, в последовательном тоже можно читать вроде бы. Во всяком случае, бит чтения-записи там есть.
Каждый байт команды/данных в последовательном режиме отправляется тремя байтами. И первый байт как раз и содержит биты-указатели, команда или данные идут и чтение или запись производится : 1 1 1 1 1 RW DC 0
Но читать, а потом писать - это геморно. При том, что еще и дисплей тормозной, одну команду или байт данных пережевывает минимум 70 (а то и все 80-90) микросекунд. Если по последовательному протоколу слать, то тактовую выше 1.666 МГц вроде нельзя подавать.
Я тестировал - 1.75 МГц он еще проглотил, а на 2 МГц уже пошли артефакты.
Если в применении к АВРкам, то тут грустно. Аппаратный СПИ при тактовой 8 МГц - это или 1, или 2 МГц. Нам подходит только 1 МГц.
Либо ставить на АВР кварц 12 МГц. Тогда СПИ можно на 1.5 МГц раскочегарить.
В результате эти циклы чтения-записи будут отбирать на ожидания вагон времени. И для основной программы останется ресурсов всего ничего.

Pretender,
Уж лучше (если это мега 8, у которой всего 1 кб ОЗУ) - выделить себе буфер на 8 строк пикселей, принтануть шрифт в этот буфер и потом выплюнуть буфер в дисплей.
Вот тут - http://avrprog.blogspot.com/2013/12/lcd ... 920-8.html есть описание представления памяти и команды.
Ну и плюс я для себя собрал в одном месте нюансы по подключению. Ибо не покидают меня эти дисплеи. Вроде распихал в всякие изделия, ан нет, еще один лежит.

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Пт апр 16, 2021 09:11:53

GoldenAndy, у меня тренировочный PIC16F877A c 368 байт ОЗУ и доступна она не вся, а 96 байт только :) Т.е. в принципе, если работать с таким дисплеем, нужно подбирать под него подходящий МК с достаточным для буфера объемом ОЗУ...

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Пт апр 16, 2021 09:36:39

Pretender, ну смотрите.
Память дисплея представлена в виде массива 32 строки по 256 пикселей, сгруппированых по 16 пикселей.
Есть 2 команды, установить вертикальный адрес, установить горизонтальный адрес.
И если вертикальный адрес произвольно устанавливается на любую строку (0..31), то на горизонтальный адрес устанавливается только кратный 16. Ибо на установку горизонтального адреса отведено 4 бита на всю строку из 256 пикселей.
При этом если горизонтальный адрес от 0 до 7 - данные попадают в верхнюю часть дисплея, если от 8 до 15 - то на 32 пикселя ниже (см. описание представления памяти дисплея).
Т.е. если выводить последовательно строку на дисплей и дальше забыть, что вы ее вывели - можете выводить сразу по два символа. Если нужно вывести один символ - то вы можете его вывести, но в позицию по горизонтали, кратную 16 пикселям.
Как по мне - если дисплей чисто для текста, то сделать буфер 16 байт - для строки символов. Печатать в него, а потом выводить буфер на дисплей построчно. Или, если есть возможность, взять МК чуть потолще. Ибо 368 байт ОЗУ - это грустно на данное время.
(Хотя и сам в основном делаю устройства на тех контроллерах, которые уже куплены, а не те, что идеально подходят под задачу)

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Пт апр 16, 2021 10:10:44

Что-то не пойму. Вот функция вывода картинки на дисплей из массива, записанного в память программ (работает нормально у меня)

Спойлер
Код:
void GLCD_display(unsigned char code *addr)
{
   int i,j;
//*******display top half screen
   for(i=0;i<32;i++)              //
    {
      TransferData((0x80 + i),0); //SET   VERTICAL ADDRESS
      TransferData(0x80,0);       //SET   HORIZONTAL ADDRESS
      for(j=0;j<16;j++)
       {
         TransferData(*addr,1);
         addr++;
       }
    }
//*******display bottom half screen
   for(i=0;i<32;i++)              //
    {
      TransferData((0x80 + i),0); //SET VERTICAL ADDRESS
      TransferData(0x88,0);       //SET HORIZONTAL ADDRESS
      for(j=0;j<16;j++)
       {
         TransferData(*addr,1);
         addr++;
       }
    }
}

Получается, горизонтальный адрес кратен 8. Как-то с адресацией не совсем понятно. Попробую воспользоваться вашим советом...

Или, если есть возможность, взять МК чуть потолще. Ибо 368 байт ОЗУ - это грустно на данное время.


Согласен :) Возможность есть заменить на другой. Просто к этой плате разработки был пример от китайцев как работать с этим дисплеем в текстовом режиме. А весь интерес работать с ним именно в графическом режиме, получается. В процессе разбора стало понятно, почему с данным МК китайцы привели пример только в текстовом режиме :)

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Пт апр 16, 2021 10:46:27

нет, горзонтальный адрес кратен 16 пикселям. Просто засылка данных побайтово идет. Что параллельная шна 8 бит, что последовательная работает с байтом.
Смотрите.
Установка горзонтального адреса - команда 1000АААА - тут АААА - 4 бта выбора горз. адреса, от 0 до 15 (0..F). И эти 0..15 охватывают все 256 пикселей. Т.е. 1 единичка гориз. адреса отвечает за 16 пикселей. Первые 128 пикселей (адрес 0..7 - верхняя часть дисплея), вторые (8..15) -нижняя.
СпойлерИзображение

Ваш тестовый код.
Сначала идет установка вертикального адреса (выбор строки - от 0 до 31).
Потом TransferData(0x80,0); //SET HORIZONTAL ADDRESS
0х80 == 10000000 - стартуем с нулевого блока пикселей.
И засылаем туда 16 байт данных - 128 бит. Как раз верхняя строчка. Если засылать без смены адреса дальше - то следующая информация появится в не в нулевой, а в трицать второй строке. Это нам пока не надо, ибо под такой вывод надо хитро готовить картинку.
Переходим к первой строке и таке далее, 32 строки по 128 бит.
Второй цикл.
Все тоже самое, но горизонтальный адрес устанавливается
TransferData(0x88,0); //SET HORIZONTAL ADDRESS
0х88 == 10001000 - стартуем с восьмого блока пикселей.
1 блок - 16 пикселей. 8*16 = 128. Т.е. мы будем слать данные в нулевую строку, но со 128-й позиции. А это, согласно модели дисплея - нижний блок дисплея. И так - 32 раза.

----
Вдогонку. Я предпочитаю с дисплеями, у которых пиксель занимает меньше байта, работать через промежуточный буфер. Ибо, зажечь пиксель, не имея информации о соседях - тяжело. Практыческы нэвазможно ©
И так сложилось, что первые поделия были на АТМеге32, где памяти 2 кб, а потом на СТМках... (там удобнее реализовывать физическое взаимодействие по ДМА).
Так что все же лучше остановиться на буфере. Тогда там можно рисовать линии, фигуры и т.д.
СпойлерИзображение

Re: Графический дисплей LCD 12864 (128x64 пикселя) на ST7920

Пт апр 16, 2021 11:04:52

Вот, теперь понятно стало... Я вот, кстати, ваши записи изучал, было бы это там сразу - не было бы подобных вопросов... Спасибо!

Ибо, зажечь пиксель, не имея информации о соседях - тяжело.

Так вот тоже еще проблема - если вывести этот небольшой буфер, а как погасить остальную область экрана?
Ответить