» » » Визуализация для микроконтроллера. Часть 1. OLED дисплей 0.96" (128х64) на SSD1306

 
 
 
15

Визуализация для микроконтроллера. Часть 1. OLED дисплей 0.96" (128х64) на SSD1306

Разместил erbol 24 августа 2016. Просмотров: 12 697

Добрый день, друзья!
Эта статья открывает цикл, посвящённый средствам визуального отображения информации.
Нами будут рассмотрены модули, в состав которых входят следующие дисплеи и управляющие контроллеры:
1. OLED дисплей на 0.96 дюйма (128×64 пикселей), контроллер SSD1306.
2. TFT дисплей на 1.8 дюйма (128×160 пикселей), контроллер ST7735.
3. TFT дисплей на 2.8 дюйма (240×320 пикселей), контроллер ILI9341.
4. TFT дисплей на 3.5 дюйма (320×480 пикселей), контроллер ILI9481.

Весь материал разбит на пять частей, в четырёх из которых изложена информация по модулям (технические параметры, подключение и инициализация, вывод на дисплей базового графического элемента — точки), а пятая содержит единую графическую библиотеку для описанных дисплеев.

Сама идея единой библиотеки и большинство приёмов её реализации позаимствованы из библиотеки Adafruit_GFX, а также отдельных работ её авторов — Лимор Фрид (Limor Fried) и Кевина Таунсенда (Kevin Townsend).
Моя скромная заслуга заключается в переносе кода с С++ на С, написании отдельных функций и выборочном переводе даташитов с целью более детального освещения особенностей работы модулей.

OLED дисплей на 0.96 дюйма (128×64 пикселей), контроллер SSD1306

Тема сегодняшней нашей беседы – вот такой модуль:

Основные характеристики OLED-модуля


• Размеры: 27мм х 27мм х 4.1 мм.
• Разрешение: 128х64 пикселя.
• Угол обзора: >160°.
• Цветность: чёрно-белый. В реальности «белый» пиксель может светиться голубым или, как на рисунке выше, жёлтым цветом, но это, как вы понимаете, не делает дисплей цветным.
• Энергопотребление: 0.08Вт при включённом дисплее.
• Рабочая температура: от – 30 до 70 градусов по Цельсию.
• Напряжение питания: 3В – 5В.
• Протокол обмена данными: I2c или SPI.

Назначение выводов

Для модуля с протоколом I2c:
• SCL, SDA – линии протокола. Подтягивающие резисторы уже встроены в модуль, поэтому соединение с микроконтроллером (МК) – напрямую.
• VCC, GND – линии питания.

Для модуля с протоколом SPI:
• SCK, MOSI – линии протокола. Тут каждый производитель старался, как мог, поэтому эти выводы могут иметь и другие названия – DO/DI, CLK/DIN и даже, как ни странно, SCL/SDA. Вывод MISO отсутствует по причине, о которой будет сказано ниже.
• CS – выбор чипа, аналог SS. Активный уровень – низкий.
• DC – выбор типа записываемого в SSD1306 слова – данные или команда.
• RES – аппаратный сброс. В прилагаемой библиотеке прописана функция программного сброса, так что, если вы ограничены в выводах микроконтроллера, можно соединить этот вывод с аналогичным пином МК либо подтянуть его к питанию.
• VCC, GND – линии питания.

Особенности протоколов обмена данными

Протокол SPI – стандартный, за исключением двух нюансов:
1. Чтение из модуля невозможно по причине отсутствия вывода MISO. Причина, по которой производители пошли на это, заключается, как мне кажется, в следующем. Единственная информация, которую можно извлечь из SSD1306 – включен дисплей или нет. Данные, согласитесь, не настолько бесценные, чтобы тратиться на организацию целой линии обмена.
2. В зависимости от состояния вывода DC записываемый в модуль байт будет интерпретироваться как команда (состояние «0») или данные (состояние «1»).

Функция записи команды, с учётом макроопределений, будет выглядеть так:
#define cbi(_byte, _bit)       _byte &= ~(1<<_bit)
#define sbi(_byte, _bit)       _byte |=  (1<<_bit)

void ssd1306_command(uint8_t command) 
{
    cbi(SSD_PORT, DC_pin); 
    cbi(SSD_PORT, CS_pin); 
    SPI_byte(command);
    sbi(SSD_PORT, CS_pin);   
}


А байт данных записывается следующим образом:
void ssd1306_data(uint8_t data) 
{
    sbi(SSD_PORT, DC_pin); 
    cbi(SSD_PORT, CS_pin); 
    SPI_byte(data);
    sbi(SSD_PORT, CS_pin);   
}


Для выяснения особенностей протокола I2c обратимся к следующему рисунку из прилагаемого даташита SSD1306:

Как видите, запись в модуль происходит как минимум тремя байтами.
Первый байт – сдвинутый на один бит влево адрес (0х3С) с добавленным битом выбора типа операции (чтение или запись). В интернете упоминается, что адрес SSD1306 может быть и 0x3D, поэтому, если ваш модуль не запускается, возможно, стоит попробовать поменять в программе его адрес.
Следующим идёт контрольный байт, шестой бит которого (D/C) определяет тип записываемого слова: команда или данные. По сути, этот бит – программный аналог вывода DC в модулях с протоколом SPI.
Третий байт – непосредственно команда или данные.
Таким образом, функции обмена обретают следующий вид:
#define SSD1306_ADDRESS            0x3C
#define DC_BIT                     6
#define CONTROL_BYTE_COMMAND       0 << DC_BIT  
#define CONTROL_BYTE_DATA          1 << DC_BIT 
#define WRITE                      0

void ssd1306_command(uint8_t command) 
{
    i2c_start();
    i2c_write((SSD1306_ADDRESS << 1) | WRITE); 
    i2c_write(CONTROL_BYTE_COMMAND);
    i2c_write(command);
    i2c_stop();  
}

void ssd1306_data(uint8_t data) 
{
    i2c_start();
    i2c_write((SSD1306_ADDRESS << 1) | WRITE); 
    i2c_write(CONTROL_BYTE_DATA);
    i2c_write(data);
    i2c_stop();  
}

Функция чтения для протокола I2c в библиотеке не прописана по соображениям, приведённым выше для объяснения отсутствия вывода MISO.

Система команд

Полный перевод таблиц команд выложен в архиве. Все команды условно разделены на шесть групп:
1. Базовые команды.
2. Команды прокрутки.
3. Команды адресации.
4. Команды аппаратной настройки.
5. Команды тайминга и схемы управления.
6. Команды ёмкостного умножителя.

Команды могут быть как однобайтными так и многобайтными, причем второй и последующие байты записываются как отдельные команды:
ssd1306_command(command_byte_1);   
ssd1306_command(command_byte_2);   
ssd1306_command(command_byte_3); 


Информация в переведённых таблицах изложена достаточно подробно и полно, поэтому остановлюсь на наиболее важных командах, которые нам пригодятся.

0хAE/0хAF – выключение/включение дисплея. Как только модуль подключается к питанию, SSD1306 готов принимать и исполнять команды, в том числе выводить изображение на дисплей. Однако само изображение вы не увидите, поскольку по сбросу/подаче питания выполняется команда 0хAE, т.е. дисплей выключен. Поэтому в функции инициализации модуля необходимо, среди прочего, прописать команду 0хAF.

0х81 – двухбайтная команда установки контрастности, значение которой определяется вторым байтом в диапазоне от 1 до 256.

0х20 – установка режима адресации. Эта команда определяет порядок вывода данных на дисплей: горизонтальный, вертикальный или постраничный. Более подробно об этом - чуть позже, а пока лишь скажу, что мы будем использовать режим горизонтальной адресации.

0х21/0х22 – установка адресов столбца/страницы. В более понятном выражении эти команды позволяют задать координаты пикселя, который вы хотите активировать.

А0/А1 - с точки зрения изображения на дисплее эти команды ответственны за отражение по горизонтали.

C0/C8 – определение порядка сканирования COM-выводов дисплея. Если проще – отражение по вертикали.

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

0x8D - включение/выключение ёмкостного умножителя. При включении дисплея без использования этой команды, изображение будет едва видимо, даже, если командой 0х81 выставить максимальное значение контрастности. Дело в том, что рабочее напряжение дисплея – от 7В до 15В. Поскольку подаваемого на выводы модуля напряжения (3В – 5В) не достаточно, в его состав включён емкостной умножитель, повышающий уровень напряжения до необходимого. По сбросу/подаче питания этот узел отключен, поэтому второй обязательной командой в функции инициализации модуля должна быть, помимо 0хAF, команда включения ёмкостного умножителя.

Вывод изображения на дисплей

Собственно, как только вывод DC (протокол SPI) или бит D/C контрольного байта (протокол I2c) выставлены в 1, записываемый в модуль байт будет выводиться на дисплей. Если быть более точным, мы с помощью функции ssd1306_data() отправляем байт в ОЗУ (GDDRAM), входящего в состав SSD1306, а далее данные автоматически выводятся на дисплей.

Давайте разберёмся, как именно происходит этот процесс.
В соответствии с количеством пикселей на дисплее ОЗУ содержит 128х64 бит, разделенных на восемь страниц по 128х8 бит или 128 байт в каждой. В случае настроек по сбросу/подаче питания данные из ОЗУ выводятся на дисплей в следующем порядке:
Визуализация для микроконтроллера. Часть 1. OLED дисплей 0.96" (128х64) на SSD1306

А комбинация команд 0хА1 и 0хС8 меняет порядок вывода таким образом:

Каждому из 128 байтов в странице ОЗУ соответствует вертикальная черта шириной 1 и высотой 8 пикселей в области дисплея, ограниченной на рисунке прямоугольником с соответствующей надписью. Отсчёт адреса столбцов ведётся слева-направо, а порядок расположения битов байта – сверху-вниз. Более наглядно сказанное поясняет рисунок из даташита:

Здесь выполнены следующие действия: соответствующими командами заданы столбец 4 (SEG4) и страница 2 (PAGE2), а затем с записано число 01000001 (65 – в десятичном исчислении). Часть кода, обеспечивающая этот процесс, выглядит для режимов горизонтальной или вертикальной адресации так:
//записываем команду установки адреса столбца
ssd1306_command(0х21);
  //начальный адрес столбца 
  ssd1306_command(4);
  //конечный адрес столбца, в данном случае он совпадает с начальным 
  ssd1306_command(4);
//записываем команду установки адреса страницы
ssd1306_command(0х22);
  //начальный адрес страницы 
  ssd1306_command(2);
  //конечный адрес страницы, в данном случае он совпадает с начальным 
  ssd1306_command(2);
//записываем число 65
ssd1306_data(65);

По исполнению вы получите два светящихся пикселя в заданном месте дисплея:

На примере записи одного байта данных трудно уловить смысл понятий «режим адресации», «начальный адрес» и «конечный адрес», а они будут играть в дальнейшем очень важную роль. Поэтому, рассмотрим вариант последовательной записи нескольких байтов подряд.

В состав SSD1306 входят счётчики адресов столбцов и страниц, текущее значение которых и определяет адрес в ОЗУ (читай – координаты на дисплее), по которому будет записан байт данных. Каждое обращение к GDDRAM приводит к автоматическому инкременту того или иного счётчика, а заданные нами начальный и конечный адреса определяют, начиная с какого и до какого значения будет происходить счёт.

Выбирая же режим адресации, мы определяем порядок работы и взаимодействия счётчиков.
• Для режима горизонтальной адресации при каждом исполнении функции ssd1306_data() увеличивается на единицу значение счётчика адреса столбца. По достижении заданного конечного значения счётчик адреса столбца сбрасывается в начальное значение, а счётчик адреса страницы увеличивается на единицу. После достижения счётчиком адреса страницы заданного конечного значения оба счётчика сбросятся в начальные значения и процесс пойдёт по второму кругу.

• Для режима вертикальной адресации, наоборот, увеличивается на 1 значение счётчика адреса страницы. После его заполнения следует сброс в начальное значение, инкремент счётчика адреса столбца и так далее.

• Для режима постраничной адресации предусмотрен только счётчик адреса столбца, то есть все действия происходят в пределах одной выбранной страницы. Кроме того, в этом режиме не предусмотрен конечный адрес столбца, так что рост значения счётчика продолжается до значения 127 (конец страницы), а затем, в отличие от двух других режимов, не сбрасывается в начальное значение, а обнуляется.

Для наглядности изложенного приведу части кода и полученные на дисплее результаты для всех трёх режимов адресации.
#define HORIZONTAL_ADDRESSING       0x00

  // выбираем режим горизонтальной адресации 
  ssd1306_command(0x20);
      ssd1306_command(HORIZONTAL_ADDRESSING);

  // пределы счёта для счётчика столбцов – от 64 до 127 
  ssd1306_command(0x21);  
      ssd1306_command(64);
      ssd1306_command(127);

  // пределы счёта для счётчика страниц – от 3 до 4
  ssd1306_command(0x22);  
      ssd1306_command(3);
      ssd1306_command(4);


  // выводим 65 вертикальных чёрточек по 8 пикселей на дисплей
  for(int i = 0; i < 65; i++)
    {
      ssd1306_data(255);      
    }



#define VERTICAL_ADDRESSING       0x01

  // выбираем режим вертикальной адресации 
  ssd1306_command(0x20);
      ssd1306_command(VERTICAL_ADDRESSING);

  // пределы счёта для счётчика столбцов – от 64 до 65 
  ssd1306_command(0x21);  
      ssd1306_command(64);
      ssd1306_command(65);

  // пределы счёта для счётчика страниц – от 3 до 7
  ssd1306_command(0x22);  
      ssd1306_command(3);
      ssd1306_command(7);


  // выводим 6 вертикальных чёрточек по 8 пикселей на дисплей
  for(int i = 0; i < 6; i++)
    {
      ssd1306_data(255);      
    }



#define PAGE_ADDRESSING       0x02
#define COLUMN_NUMBER         64
#define PAGE_NUMBER           3

  // выбираем режим постраничной адресации 
  ssd1306_command(0x20);
      ssd1306_command(PAGE_ADDRESSING);

  // младшая тетрада начального адреса столбца
  ssd1306_command(0x00 | (COLUMN_NUMBER & 0x0F));  
  // старшая тетрада начального адреса столбца
  ssd1306_command(0x10 | (COLUMN_NUMBER >> 4));  
  
  //начальный адрес страницы
  ssd1306_command(0xB0 | PAGE_NUMBER);  

  // выводим 65 вертикальных чёрточек по 8 пикселей на дисплей
  for(int i = 0; i < 65; i++)
    {
      ssd1306_data(255);      
    }


Перейдём к прорисовке базового элемента – точки. Как вы поняли, конструктивные особенности SSD1306 не дают нам возможность задавать отдельную строку на дисплее, а лишь страницу. Во-первых, из-за этого мы не можем объединить единой библиотекой этот модуль с другими, которые оперируют координатами пикселя - столбец/строка (или – х/у). Во-вторых, это – просто неудобно и непривычно.
Используем следующие конструкции для определения из координаты «у» номера страницы:
  uint8_t page;
  
   if(y < 8)
    {
      page = 0;
    }
   else if (y >= 8)
    {
      page = (int)(y/8);       
    }

и строки:
y&7

Тогда вывести точку в нужное место дисплея можно так:
#define BLACK       0
#define WHITE       1

//х – от 0 до 127, у – от 0 до 63
void draw_pixel(uint8_t x, uint8_t y, uint8_t color)
{
  uint8_t page;
  if(y < 8)
    {
      page = 0;
    }
   else if (y >= 8)
    {
      page = (int)(y/8);       
    }
  ssd1306_command(0x21);  
      ssd1306_command(x);
      ssd1306_command(x);

  ssd1306_command(0x22);  
      ssd1306_command(page);
      ssd1306_command(page);
  
  if(color == WHITE)
    {
      ssd1306_data(1 << (y&7));
    }
  else if(color == BLACK)
    {
      ssd1306_data(0 << (y&7));
    }  
}  

На этом статью можно было бы считать завершённой, если бы не одно «но» - мы не можем поменять состояние одного пикселя, не затронув остальные семь, связанные с ним. Используя функцию draw_pixel() в приведённом виде мы будем гасить на дисплее 7 ни в чём не повинных точек.

Чтобы этого не происходило, необходимо не только каким-то образом изменить функцию, но и, до вхождения в неё, знать состояние пикселей – 0 или 1. В масштабе всего дисплея мы должны в любой момент знать текущее состояние всех 128х64 пикселей или 128х8 байт памяти. Поскольку извлечь эту информацию из SSD1306, как вы помните, невозможно, придётся создать массив соответствующей размерности.
#define SSD1306_LCDWIDTH       128
#define SSD1306_LCDHEIGHT       64

uint8_t buffer[SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT/8];

Создание массива порождает новый вопрос – как оптимально, с точки зрения кода, увязать порядковый номер элемента массива с координатами 8-пиксельной черты на дисплее? Создатели библиотеки Adafruit_GFX использовали простой и изящный приём, приняв во внимание следующее:
1. При режиме горизонтальной адресации сдвиг координат на дисплее происходит слева-направо и сверху-вниз, так же, как и при последовательной выборке элементов из массива.
2. Размеры 128х64 пикселя позволяют незаметно для человеческого глаза прорисовывать каждый раз весь дисплей.

В итоге прорисовку точки будут обеспечивать две функции:
//эта функция меняет состояние соответствующего бита 
//в элементе массива, определяемого координатами х/у
void draw_pixel(int16_t x, int16_t y, uint16_t color) 
{
  switch (color) 
    {
      case WHITE:   buffer[x+ (y/8)*SSD1306_LCDWIDTH] |=  (1 << (y&7)); break;
      case BLACK:   buffer[x+ (y/8)*SSD1306_LCDWIDTH] &= ~(1 << (y&7)); break; 
    }
}

//а эта последовательно выбирает байты из массива и отправляет их в ОЗУ SSD1306
void ssd1306_draw_display(void) 
{
  ssd1306_command(SSD1306_COLUMNADDR);
  ssd1306_command(0);   
  ssd1306_command(SSD1306_LCDWIDTH-1); 
  ssd1306_command(SSD1306_PAGEADDR);
  ssd1306_command(0); 
  ssd1306_command(7); 

  #if defined I2C_INTERFACE
    i2c_start();
    i2c_write((SSD1306_ADDRESS << 1) | WRITE); 
    i2c_write(CONTROL_BYTE_DATA);
    for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) 
      {
        i2c_write(buffer[i]);
      }
    i2c_stop();

  #elif defined SPI_INTERFACE
    sbi(SSD_PORT, DC_pin); 
    cbi(SSD_PORT, CS_pin); 
    for (uint16_t i=0; i<(SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8); i++) 
      {
        SPI_byte(buffer[i]);
      }
    sbi(SSD_PORT, CS_pin);     
  #endif
}


Структура и содержание библиотеки SSD1306

Библиотека состоит из 8 файлов. Приведу их краткое содержание:
1. main.c – подключает необходимые для работы библиотеки, инициализирует модуль и выводит на дисплей изображение. Какое именно, вы узнаете, запустив программу.
2. main.h – выбор протокола обмена (SPI или I2c) и типа сброса (программный или аппаратный). Библиотека пригодна к использованию для модулей с обоими вариантами протокола и сброса, поэтому для выбора подходящих вам параметров раскомментируйте соответствующие строки в этом файле.
3. i2c.c – содержит функции программного протокола I2c. Обычно я пользуюсь аппаратным вариантом. Но, хотелось, чтобы библиотека была полезна как можно большему кругу людей, поэтому я воспользовался кодом из этой статьи Avinash Gupta. Вы можете заменить содержимое этого файла тем кодом, которому больше доверяете и обычно используете, обеспечив лишь соответствие названий функций.
4. i2c.h – назначение выводов МК, участвующих в протоколе I2c.
5. spi.c – функции программного SPI. Так же, как и в случае с I2c, можете заменить их на свои.
6. spi.h – назначение выводом МК, к которым подключается модуль с одноимённым протоколом обмена.
7. ssd1306.с – функции, непосредственно обеспечивающие работу модуля. Кроме тех, что уже упомянуты в статье, здесь вы найдёте функции инициализации, аппаратного и программного сброса, полной очистки дисплея, выбора ориентации изображения на экране, а также, для желающих организовать бегущую строку, функции прокрутки.
8. ssd1306.h – определение параметров дисплея (цвета, размеры), макроопределения всех используемых команд контроллера. Здесь же объявлен массив buffer[], который развёрнут по причине, указанной в п.1.

Файлы

Релиз 2. 14-09-2016 обновлена библиотека. В main.c подключение фалов библиотеки не через h-файлы, как было, а через с-файлы, как принято в большинстве компиляторов. Кроме того явно прописано подключение стандартной библиотеки string.h
ssd1306_kod.7z | Файл 3,33 Kb загружен 22 раз.

Релиз 1:
kod.7z | Файл 3,22 Kb загружен 32 раз.

Перевод на русский таблиц команд SSD130:
perevod-tablic-komand-ssd1306-datagor.ru.7z | Файл 58,05 Kb загружен 34 раз.

Даташит на контроллер дисплея SSD1306:
ssd1306_datashit.7z | Файл 1,19 Mb загружен 30 раз.

Пожалуй, на этом всё, конец первой части.
Продолжение следует!
Ербол (erbol)
Актобе, Казахстан
Профиль erbol
Мне 50 лет. Родился и вырос в г. Актюбинск (ныне - Актобе), Казахстан. Женат, воспитываю четверых прекрасных детей.

С программированием и электроникой имею может и не отдаленные, но весьма эпизодические отношения: в далекие и бурные 90-е годы аж прошлого века посчастливилось участвовать в автоматизации экспериментальной установки с использованием микропроцессорного комплекта КР580.

А пару лет назад мои сорванцы вдруг заинтересовались микроконтроллерами. Пришлось из дальних уголков памяти вытаскивать свои старые познания и стряхивать с них пыль.
 

Понравилось? Палец вверх!

  • всего лайков: 55

13 сентября 2016 изменил Datagor. Добавлен архив с переводом таблиц команд.

Поделись с друзьями!

Связанные материалы:


Схема на Датагоре. Новая статья Визуализация для микроконтроллера. Часть 3. TFT дисплей 2.8" (240х320) на ILI9341... Битва за урожай закончена, можно продолжить повествование. Полноцветный TFT-дисплей 240×320...
Схема на Датагоре. Новая статья Программная реализация протокола SPI на AVR в CodeVisionAVR... Всем коллегам и согражданам привет! Увлёкся я изучением протоколов. Про реализацию протокола I2C...
Схема на Датагоре. Новая статья Визуализация для микроконтроллера. Часть 2. TFT дисплей 1.8" (128х160) на ST7735... Следующий из рассматриваемых нами модулей обладает полноцветным дисплеем под управлением...
Схема на Датагоре. Новая статья Программная реализация протокола I2C на AVR в CodeVisionAVR... Пару лет назад, изучая Atmega8, я захотел программно реализовать работу с устройствами на шине i2c,...
Схема на Датагоре. Новая статья Беспроводной канал связи 2,4 ГГц на базе трансивера nRF24L01+ от Nordic Semiconductor. Часть 3... Wireless Transceiver Module NRF24L01+ 2.4GHz, 4 шт. на Али Приветствую всех настоящих и будущих...
Схема на Датагоре. Новая статья Беспроводной канал связи 2,4 ГГц на базе трансивера nRF24L01+ от Nordic Semiconductor. Часть 1... Доброго вам дня, уважаемые граждане и гости Датагор.ру - этого замечательного сообщества...
Схема на Датагоре. Новая статья Вторая жизнь лампового радиоприемника Philips 592LN (Голландия, 1947). Часть 5... В этой части статьи речь пойдет:  — о предварительном усилителе и его питании,  — о питании...
Схема на Датагоре. Новая статья Вторая жизнь лампового радиоприемника Philips 592LN (Голландия, 1947). Часть 4. Модуль BlueTooth OVC3860... Привет, датагорцы! В этой части моего повествования речь пойдёт о модуле BlueTooth OVC3860 (далее...
Схема на Датагоре. Новая статья Несколько функций для програмной реализации протокола I2C на AVR... Добрый день, дорогие друзья! Решил поделиться с вами несколькими функция для работы по протоколу...
Схема на Датагоре. Новая статья Библиотека для sPlan 7.0 в старом стиле: радиолампы и основные элементы по мотивам С. Комарова... Недавно я поднял важную тему в своей статье «О принципиальном подходе в рисовании принципиальных...
Схема на Датагоре. Новая статья Elect_60: программа микроконтроллерного управления внешними устройствами от ПК... Многие наши коллеги желающие создать микроконтроллерное устройство, управляемое от ПК сталкиваются...
Схема на Датагоре. Новая статья Проект DMX512. Микроконтроллер управляет профессиональным шоу. Ч.1... DMX512 (англ. Digital Multiplex) - стандарт, описывающий метод цифровой передачи данных между...
<
  • Гражданин
24 августа 2016 12:19

Иван Гаврилов / Discover

Цитата
  • С нами с 17.08.2009
  • Ушёл в реал Пользователь offline
  • 38 комментариев
  • 15 публикаций
 
  • +2
Ербол, просто замечательно. Как и прежде, всё разжевано и разложено по полочкам.
Мы очень помогаем друг-другу создавая такие библиотеки. Использование хорошо документированной библиотеки очень сильно ускоряет получения результата.
Примерно неделю назад, я рассматривал данный индикатор для своего будущего проекта. Нужен маленький не дорогой и информативный индикатор. А тут, смотрю - готовая библиотека smile
Еще, у меня в закромах валяется индикатор на ILI9341, буду ждать библиотеку.
Ербол, еще раз спасибо за Ваши труды.

<
  • Главный редактор
24 августа 2016 13:34

Игорь Петрович Котов / Datagor

Цитата
  • С нами с 25.02.2011
  • Ушёл в реал Пользователь offline
  • 1 648 комментариев
  • 261 публикация
 
  • 0
Старичкам библиотеки увеличивают скорость разработки, а новичкам - скорость понимания и освоения.
Ерблолу наши благодарности. drinks

<
  • Гражданин
24 августа 2016 14:35

Ербол / erbol

Цитата
  • С нами с 11.12.2014
  • Ушёл в реал Пользователь offline
  • 59 комментариев
  • 9 публикаций
 
  • 0
Цитата: Discover
Ербол, просто замечательно. Как и прежде, всё разжевано и разложено по полочкам.
Мы очень помогаем друг-другу создавая такие библиотеки. Использование хорошо документированной библиотеки очень сильно ускоряет получения результата.


Спасибо, Иван! smile Согласен, обмен информацией двигает прогресс и делает мир лучше. А знания, которые ты оставляешь при себе, ни с кем не делясь, рано или поздно устаревают и становятся никому не нужными handshake

Цитата: Datagor
Старичкам библиотеки увеличивают скорость разработки, а новичкам - скорость понимания и освоения.

Игорь, пользуясь случаем хочу поблагодарить за нелёгкий редакторский труд! drinks

<
  • Гражданин
26 августа 2016 05:44

Радик / galrad

Цитата
  • С нами с 23.08.2011
  • Ушёл в реал Пользователь offline
  • 84 комментария
  • 12 публикаций
 
  • +1
Автору статьи - Респект! drinks
Подобных статей совсем не много, большинство из них описывают даташиты и дают краткие примеры, с которыми еще нужно сидеть и разбираться. Для многих радиолюбителей, изучающих микроконтроллеры, переход от сегментных индикаторов к графическим индикаторам проходит, можно сказать "болезненно", и связанно это именно с дефицитом системной литературы по работе с графическими дисплеями. Наиболее частые вопросы:
1.Как зажигать отдельные пиксели или группу пикселей?
2.Как формируется статическая и динамическая картинка?
3.Как вывести алфавитно-цифровую информацию на графическом дисплее?
4.Как определить координаты выводимой информации?
5.Как сделать бегущую картинку (строку)?
6.Как повернуть картинку или заставить её вращаться?
7.Как управлять яркостью свечения пикселей?
Это наиболее частые вопросы, возникающие на форумах, конечно их значительно больше!
Побольше бы таких статей!

<
  • Гражданин
26 августа 2016 09:21

Ербол / erbol

Цитата
  • С нами с 11.12.2014
  • Ушёл в реал Пользователь offline
  • 59 комментариев
  • 9 публикаций
 
  • +1
Спасибо, Радик! handshake
Видимо сказывается, что текст статьи - суть лекции, которые я писал для своих детей, стараясь по этой причине разложить все на "молекулы" smile
Отдельная благодарность за очерченный круг вопросов! Они очень помогут при определении структуры и содержания 5-й части drinks

<
  • Подписчик
31 августа 2016 10:28

Игорь / StalKer-NightMan

Цитата
  • С нами с 15.03.2012
  • Ушёл в реал Пользователь offline
  • 92 комментария
  • 1 публикация
 
  • 0
Ух, Ербол!!!
Как круто, слов нет почти все уже все сказали. Просто восхищаюсь как толково написано!!!
Спасибо, Ербол.
Когда же я доберусь до подобных исследований....

<
  • Гражданин
31 августа 2016 12:49

Ербол / erbol

Цитата
  • С нами с 11.12.2014
  • Ушёл в реал Пользователь offline
  • 59 комментариев
  • 9 публикаций
 
  • 0
Спасибо, Игорь!!! handshake
Могу присоединиться к Вам на пути к подобным исследованиям drinks

<
  • Гражданин
7 сентября 2016 20:59

Александр / SAI

Цитата
  • С нами с 27.11.2010
  • Ушёл в реал Пользователь offline
  • 10 комментариев
  • 0 публикаций
 
  • 0
Добрый День, скажите как можно подключить два таких дисплея к atmega328 возможна ли программная смена адреса одного дисплея ?

<
  • Гражданин
7 сентября 2016 22:51

Ербол / erbol

Цитата
  • С нами с 11.12.2014
  • Ушёл в реал Пользователь offline
  • 59 комментариев
  • 9 публикаций
 
  • 0
Добрый вечер, Александр. О программной смене в даташите ничего не сказано. Но, на оборотной стороне есть перемычка выбора адреса

<
  • Гражданин
8 сентября 2016 14:44

Александр / SAI

Цитата
  • С нами с 27.11.2010
  • Ушёл в реал Пользователь offline
  • 10 комментариев
  • 0 публикаций
 
  • 0


правильно понял, такой дисплей?
а перемычки это резисторы смена так?


<
  • Гражданин
8 сентября 2016 15:42

Ербол / erbol

Цитата
  • С нами с 11.12.2014
  • Ушёл в реал Пользователь offline
  • 59 комментариев
  • 9 публикаций
 
  • 0
На моем модуле всего 5 резисторов, из них 1 - смена адреса. Судя по всему на Вашем 2 резистора (R3 и R4) отвечают за адрес

<
  • Главный редактор
8 сентября 2016 16:07

Игорь Петрович Котов / Datagor

Цитата
  • С нами с 25.02.2011
  • Ушёл в реал Пользователь offline
  • 1 648 комментариев
  • 261 публикация
 
  • 0
Ербол, вот ваш модуль. О каких элементах вы говорите?


Вижу на вашем модуле всего 4 резистора, не 5. Два из них BS0, BS1 - это перемычки выбора протокола.
Пин 6-й модуля это "CS" - выбор чипа, активный ноль.

На модуле Александра тоже 2 перемычки R3, R4 и они вероятнее всего тоже для выбора протокола.

<
  • Гражданин
8 сентября 2016 17:03

Ербол / erbol

Цитата
  • С нами с 11.12.2014
  • Ушёл в реал Пользователь offline
  • 59 комментариев
  • 9 публикаций
 
  • 0
Игорь, судя по надписям и количеству выводов это - модуль с протоколом SPI, а у Александра - с i2c. На моём (который с i2c) 5 резисторов. Я скинул изображение на ftp (не знаю как тут прикреплять sad )


<
  • Гражданин
9 сентября 2016 09:28

Ербол / erbol

Цитата
  • С нами с 11.12.2014
  • Ушёл в реал Пользователь offline
  • 59 комментариев
  • 9 публикаций
 
  • 0
Игорь, присмотрелся повнимательней. Ваш модуль - универсальный: работает и по SPI, и по I2c в зависимости от комбинации перемычек. На фото - вариант 4-х проводной SPI. Из таблички на модуле мне не ясно, при распайке перемычек для I2c выбор "команда/данные" будет осуществляться битом DC, как в статье или выводом D/C модуля. Если выводом, то код для I2c надо будет корректировать

<
  • Кандидат
13 апреля 2017 00:13

Игорь / igor_6945176

Цитата
  • С нами с 3.04.2017
  • Ушёл в реал Пользователь offline
  • 1 комментарий
  • 0 публикаций
 
  • +1
Привет!
Команда 0х21 (согласно даташиту) ограничитель области. Там четко написано"начало" и "конец". Другими словами, эта команда устанавливает рабочую область байт в строках (от такого то байта и до такого то). Команда 0х22 делает тоже самое но для строк (от такой строки и до такой).

Эти две команды позволяют создавать "окна" не затрагивая остальные области экрана. Например: для создания всплывающего окна меню с прокруткой в любую сторону, без воздействия на остальную часть экрана. адресация же байт в самой строке (согласно тому же даташиту) имеет старший полубайт и младший (10-1F и 00-0F соответственно).

Говоря иначе: каждая строка разбита на сегменты по 16 байт в каждом. команда 10-1F устанавливает номер сегмента (1-16), а команда 00-0F конкретный байт в этом сегменте. Такой способ адресации делает очень удобным вывод текста с символами кратными 8ми (8х8,8х16,16х16 ит.д.)

НО! 16 сегментов по 16 байт делают 256 байт, а наш экранчик = 127 байт. Понятно что SSD1306 (при таком раскладе) способен работать с экранами в 256хХХ. По каким причинам разработчики не внесли ограничения остается только гадать (забыли, технически не возможно и т.п.) но при адресации это стоит учитывать.
Удачи.

Добавление комментария


Налетай! Паяльники, станции, жала с доставкой
  • smilelolbyewinkyahoocoollaughing
    crazybadcryingsadirefulsickstraight
    ballooncakegooddrinksmailbombsun
    nightrainstarscolddashguitar-manhandshake
    musicnegativenopardonshoksleepunknown
    wackoyawnblushbullyhashsmokingwhew
Скопируйте текст вашего комментария на случай неверного ответа на контрольный вопрос.