SSD1322

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

SSD1322

Сообщение mks_r » 06 сен 2016, 13:09

Здравствуйте.
Использую дисплей UG-5664ASWEF01 (256x64) с драйвером SSD1322 и микроконтроллер Fujitsu MB96F696RB. Интерфейс SPI 4-wire для организации взаимодействия. Передача информации осуществляется асинхронно через прерывание из очереди длиной 1024 байта.

Код: Выделить всё
/** инициализация таблицы градаций яркости */
static void lcd_set_gray_scale(void)
{
   unsigned char cnt = 0;
   unsigned char step = 0x0C;
   unsigned char max_step = 0xB4;
   spi_write(CMD, 0xB8); /** таблица градаций яркости */
   for (cnt = step; cnt <= max_step; cnt += step)
      spi_write(DTA, cnt);
   spi_write(CMD, 0x00); /** разрешить работу таблицы градаций яркости */
}

static void lcd_set_col(unsigned char start, unsigned char end)
{
   spi_write(CMD, 0x15); /** Set Column Address */
   spi_write(DTA, start); /** начальный адрес */
   spi_write(DTA, end); /** конечный адрес */
}

static void lcd_set_row(unsigned char start, unsigned char end)
{
   spi_write(CMD, 0x75); /** Set Row Address */
   spi_write(DTA, start); /** начальный адрес */
   spi_write(DTA, end); /** конечный адрес */
}

static void lcd_set_start_line(unsigned char start)
{
   spi_write(CMD, 0xA1);
   spi_write(DTA, start);
}

static void lcd_set_wr_ram(void)
{
   spi_write(CMD, 0x5C); /** Разрешает микроконтроллеру записать данные в RAM */
}

static void lcd_current_control(unsigned char val)
{
   spi_write(CMD, 0xC7); // Master Contrast Current Control
   spi_write(DTA, (val > 0x0F) ? 0x0F : val);
}

/** очистка дисплея */
static void lcd_clr(void)
{
   unsigned int i = 0, j = 0;
   lcd_set_col(0x1C, 0x5B); /** 112 SEG до 367 SEG = 112 SEG / 4 до 367 SEG / 4 = 0x1C - 0x5B */
   lcd_set_row(0x00, 0x3F);
   
   for (i = 0; i < 64; i++)
   {
      lcd_set_wr_ram();
      for (j = 0; j < 128; j++)
         spi_write(DTA, 0x00);
   }
}

/** зарисовка дисплея */
static void lcd_fill(void)
{
   unsigned int i = 0, j = 0;
   lcd_set_col(0x1C, 0x5B); /** 112 SEG до 367 SEG = 112 SEG / 4 до 367 SEG / 4 = 0x1C - 0x5B */
   lcd_set_row(0x00, 0x3F);

   for (i = 0; i < 64; i++)
   {
      lcd_set_wr_ram();
      for (j = 0; j < 64; j++)
      {
         spi_write(DTA, 0xFF);
         spi_write(DTA, 0xFF);
      }
   }
}

/** сетка */
static void lcd_grid(void)
{
   unsigned int x = 0, y = 0;
   lcd_set_col(0x1C, 0x5B); /** 112 SEG до 367 SEG = 112 SEG / 4 до 367 SEG / 4 = 0x1C - 0x5B */
   lcd_set_row(0x00, 0x3F);
   
   for (y = 0; y < 64; y++)
   {
      lcd_set_wr_ram();
      for (x = 0; x < 128; x++)
         spi_write(DTA, (y & 0x01) ? 0xF0 : 0x0F);
   }
}

/** список команд инициализации дисплея */
void lcd_init(void)
{
   spi_write(CMD, 0xAB); /** 0xAB - внутренний регулятор Vdd, 0x01 - разрешить работу внутреннего регулятора для VDD */
   spi_write(DTA, 0x01);

   spi_write(CMD, 0xFD); /** Set Command Lock */
   spi_write(DTA, 0x12); /** разблокировка */

   spi_write(CMD, 0xB3); // Set Front Clock Divider / Oscillator Frequency
   spi_write(DTA, 0xD0); // = reset / 1100b

   spi_write(CMD, 0xCA); // Set MUX Ratio
   spi_write(DTA, 0x3F); // = 63d = 64MUX

   spi_write(CMD, 0xA2); // Set Display Offset
   spi_write(DTA, 0x00); // = RESET

   spi_write(CMD, 0xA1); // Set Display Start Line
   spi_write(DTA, 0x00); // = register 00h

   spi_write(CMD, 0xA0); // Set Re-map and Dual COM Line mode
   spi_write(DTA, 0x14); // 10= Reset except Disable Nibble Re-map, Scan from COM[N-1] to COM0, where N is the Multiplex ratio
   spi_write(DTA, 0x11); // 01= Reset except Disable Dual COM mode (MUX = 63)

   spi_write(CMD, 0xB5); // Set GPIO
   spi_write(DTA, 0x00); // = GPIO0, GPIO1 = HiZ, Input Disabled

   spi_write(CMD, 0xB4); // Display Enhancement A
   spi_write(DTA, 0xA0); // = Enable external VSL
   spi_write(DTA, 0xB5); // = Normal (reset)

   spi_write(CMD, 0xC1); // Set Contrast Current
   spi_write(DTA, 0x9F); // = 0x7F - default

   spi_write(CMD, 0xC7); // Master Contrast Current Control
   spi_write(DTA, 0x0F);

   spi_write(CMD, 0xB9); /** Сбрасывает таблицу градаций яркости в состояние по умолчанию (линейная таблица с нарастанием яркости от GS0 до GS1) */

   spi_write(CMD, 0xB1); // Set Phase Length
   spi_write(DTA, 0xE2); // 0xE2= Phase 1 period (reset phase length) = 5 DCLKs, Phase 2 period (first pre-charge phase length) = 14 DCLKs

   spi_write(CMD, 0xD1); // Display Enhancement B
   spi_write(DTA, 0xA2); // 0xA2 = Normal (default); 0x82 = reserved
   spi_write(DTA, 0x20); // 0x20 = as-is

   spi_write(CMD, 0xBB); // Set Pre-charge voltage
   spi_write(DTA, 0x1F); // 0x17 = default; 0x1F = 0.60*Vcc (spec example)

   spi_write(CMD, 0xB6); // Set Second Precharge Period
   spi_write(DTA, 0x08); // 0x08 = 8 dclks (default)

   spi_write(CMD, 0xBE); // Set VCOMH
   spi_write(DTA, 0x07); // 0x04 = 0.80*Vcc (default); 0x07 = 0.86*Vcc (spec example)

   spi_write(CMD, 0xA9); // Exit Partial Display // команда выключает режим отображения части экрана

   spi_write(CMD, 0xA6); // Set Display Mode = Normal Display
}

При активации передачи данных по шине SPI выставляю Chip Select в 0 на время всей передачи данных/команд и в зависимости от типа передаваемой информации перед началом передачи очередного байта выставляю D/C#.
http://microsin.net/adminstuff/hardware/ssd1322-oled-controller.html

В семплах на данный драйвер ф-ция lcd_set_wr_ram() вызывается до циклов единожды (lcd_clr, lcd_fill, lcd_grid), но у меня в таком случае выводится только одна строка, а все остальные данные игнорируются. Поэтому выполняю lcd_set_wr_ram() каждый раз при переходе на следующую строку. Возможно я делаю что-то не так что приходится каждый раз разрешать запись в RAM дисплея?

В функции lcd_grid() предполагается, что на дисплее каждая строка в зависимости от её четности будет выводится 0x0F или 0xF0 соответственно, тем самым создавая сетку, но при выводе падает практически до минимума контрастность и яркость пикселей. На дисплее отображается частично сетка и частично сбитые по координатам пикселы. Возможно что-то не учтено, подскажите, пожалуйста.
mks_r
 
Сообщения: 2
Зарегистрирован: 06 сен 2016, 11:29

Re: SSD1322

Сообщение elmot » 06 сен 2016, 20:31

у интерфейса SPI есть четыре режима, по каким фронтам и уровням сигналов работать. Обычно глючащий spi - это криво выставленный режим.
https://en.wikipedia.org/wiki/Serial_Pe ... _and_phase
Аватара пользователя
elmot
 
Сообщения: 5691
Зарегистрирован: 10 ноя 2011, 12:02
Откуда: Turku, Finland
Skype: elmot73
прог. языки: Java и все-все=все
ФИО: Илья

Re: SSD1322

Сообщение mks_r » 07 сен 2016, 12:07

elmot, спасибо за ответ.
Использую режим CPOL = 0 и CPHA = 0.
Нашел проблему, связанную с передачей данных. Например, заместо 2 байт передается 8, пытаюсь решить этот косяк.
Спасибо.
Вложения
mode_spi.JPG
Режим SPI
mks_r
 
Сообщения: 2
Зарегистрирован: 06 сен 2016, 11:29

Re: SSD1322

Сообщение Angel71 » 07 сен 2016, 12:19

для таких ситуаций ничего лучше даталоггера не придумали.
Аватара пользователя
Angel71
 
Сообщения: 10668
Зарегистрирован: 18 апр 2009, 22:18


Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 17