OLED SSD1306

JurisG
Offline
Зарегистрирован: 28.03.2014

Добрый день!

Пытаюсь запустить OLED2864 (чип SSD1306, I2C). В качестве платы использую CipKIT MAX32, но программа на стандартной библиотеке Wire. В результате начальной инициализации появляется "звездное небо" и все. Вывести данные на экран не получается. Может кто сталкивался с этой проблемой.

// Начальная инициализация дисплея
#include <Wire.h>

int DC = 30;
int RES = 31;
int CS = 32;
int Com_adr = 0x3C;
int Data_adr = 0x3D;

int Data [8] = {0x81,0x81,0xFF,0x19,0x29,0x49,0x86,0x80};

void setup()
{
  pinMode (DC, OUTPUT);
  pinMode (RES, OUTPUT);  
  pinMode (CS, OUTPUT);
  
   digitalWrite (DC, HIGH);
  digitalWrite (DC, LOW);
  
  digitalWrite (CS, LOW); // enable chip
  
  digitalWrite (RES, HIGH);  //Reset
  delay (100);
  digitalWrite (RES, LOW);
  delay (100);
  digitalWrite (RES, HIGH);
  delay (100);
 
  Wire.begin(); // join i2c bus  

  Wire.beginTransmission(Com_adr); //Internal
  Wire.send(0xAE);
  
  Wire.send(0x00);
  Wire.send(0x10);

  Wire.send(0x40);

  Wire.send(0x81);
  Wire.send(0xCF);

  Wire.send(0xA1);

  Wire.send(0xA6);

  Wire.send(0xA8);
  Wire.send(0x3F);

  Wire.send(0xD3);
  Wire.send(0x00);

  Wire.send(0xD5);
  Wire.send(0x80);

  Wire.send(0xD9);
  Wire.send(0xF1);

  Wire.send(0xDA);
  Wire.send(0x12);

  Wire.send(0xDB);
  Wire.send(0x30);

  Wire.send(0x8D);
  Wire.send(0x14);
  
  Wire.send(0xAF);
  Wire.endTransmission();    // stop transmitting
  delay (200);
  
  
  delay (200);
  digitalWrite (DC, HIGH);
  delay (10);
 
 Wire.beginTransmission(Data_adr);
  for (int j=0; j<20; j++)
  {
  for (int i=1; i<8; i++)
    {
      Wire.send(Data[i]);
    }
  }
  Wire.endTransmission();  
  
  delay (5);
  digitalWrite (DC, LOW);
}



void loop()
{
    
  delay(500);
}

 

JurisG
Offline
Зарегистрирован: 28.03.2014

Все, проблему решил.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Кто то будет искать, найдет тему и будет переспрашивать. Сделайте доброе дело, поделитесь решением.

 

JurisG
Offline
Зарегистрирован: 28.03.2014

В форуме, разве что, могу выложить текст программы, а более подробно надо статьей. На этом сайте сторонние авторы могут выкладывать статьи?

// Начальная инициализация дисплея и вывод данных
// Юрис Гризанс
// 2014


#include <Wire.h> // Подключение стандартной библиотеки I2C

/* Подключение для случая ChipKit MAX32:

Vcc --> 3,3V
GND --> GND
CS  --> GND или 3,3V
RES --> 31 (можно и другой контакт)
D/C --> GND (Disp_adr_1 = 0x3C) или 3,3B (Disp_adr_1 = 0x3D)
SDA --> 20 (для MAX32 фиксированно)
SCL --> 21 (для MAX32 фиксированно)

*/

const int RES = 31; // Вывод дисплея RES подключен к 31 выводу MAX32
const int Disp_adr_1 = 0x3C; // Адрес дисплея на шине I2C. Если D/C подключить к 3,3В, то адрес 0x3D.

int Data [8] = {0x81,0x81,0xFF,0x19,0x29,0x49,0x86,0x80}; // Для тестирования: буква "R"

byte Ekran [128][8]; // Это массив, который полностью копируется в дисплей 
                    // Число в скобках указывает на колличество ячеек. В данном случае, например, 128 ячеек с адресацией от 0 до 127.



void Init_Disp (int Disp_adr) //   *********  НАЧАЛЬНАЯ ИНИЦИАЛИЗАЦИЯ *******
{
  
  
  Wire.beginTransmission(Disp_adr); // Открытие сессии с устройством по адресу Disp_adr (генерирует сигнал START)
                                    // (некоторый команды необязательны, т.к. имеют выбранное значение после RESET)
  
  Wire.send(0xAE); // Выключить дисплей
  
  Wire.send(0x00); // Установка начального столбца для вывода
  Wire.send(0x10);

  Wire.send(0x40); // Установка начальной строки в RAM

  Wire.send(0x81); // Установка контрастности
  Wire.send(0xCF); // От 1 до 256 (0х01 - 0х100)

  Wire.send(0xA0); // Развертка: А0 - справа/налево; А1 - слева/направо.

  Wire.send(0xA6); // А6 - нормальное изображение (лог.1 в RAM - светится пиксель на экране); А7 - инверсное.

  Wire.send(0xA8); // Multiplex ratio
  Wire.send(0x3F); // от 16 до 64

  Wire.send(0xD3); // Смещение изображения на дисплее (Offset)
  Wire.send(0x00);

  Wire.send(0xD5); // Частота обновления экрана
  Wire.send(0x80);

  Wire.send(0xD9); // DC/DC преобразователь
  Wire.send(0xF1); // 0х22 - Vcc подается извне; 0xF1 - внутренний

  Wire.send(0xDA); // Конфигурация COM
  Wire.send(0x12);

  Wire.send(0xDB); // установка Vcomh(влияет на яркость)
  Wire.send(0x30); // 0x00 - 0,65Vcc; 0x20 - 0,77Vcc; 0x30 - 0,83Vcc

  Wire.send(0x8D); // Управление внутренним преобразователем
  Wire.send(0x14); // 0х10 - отклычить (Vcc внешнее); 0х14 - включить (внутренний DC/DC)
  
  Wire.send(0x20); // Установить вариант адресации RAM
  Wire.send(0x00); // 0x00 - горизонтальная с переходом на следующую страницу

  Wire.send(0xAF);// Включить дисплей  
  Wire.endTransmission();    // Окончание сессии (генерирует сигнал STOP)
  
  delay (200);
}



void Send_data (int Disp_adr) // Упрощенный вывод (одна сессия - один байт)
{
      
  for (int y=0; y<=7; y++)
  {
    for (int x=0; x<=127; x++)
    {
      Wire.beginTransmission(Disp_adr); // Начало сессии (сигнал СТАРТ и адрес устройства)
      Wire.send (0x40); // Передача контрольного байта
      Wire.send(Ekran[x][y]); // Передача очередного байта из массива
      Wire.endTransmission(); // Окончание сессии
    }
  }
      
}


void Send_data_2 (int Disp_adr) // Более быстрый вывод данных массива на экран
{
  
  
 for (int y=0; y<=7; y++)
 {
    Wire.beginTransmission(Disp_adr);
    Wire.send (0x40);
    for (int x=0; x<=20; x++) // Байты данных группируются примерно по 20
    {
      Wire.send(Ekran[x][y]);
    }
    Wire.endTransmission();
  
    Wire.beginTransmission(Disp_adr);
    Wire.send (0x40);
    for (int x=21; x<=40; x++)
    {
      Wire.send(Ekran[x][y]);
    }
    Wire.endTransmission();
  
    Wire.beginTransmission(Disp_adr);
    Wire.send (0x40);
    for (int x=41; x<=60; x++)
    {
      Wire.send(Ekran[x][y]);
    }
    Wire.endTransmission();
  
    Wire.beginTransmission(Disp_adr);
    Wire.send (0x40);
    for (int x=61; x<=80; x++)
    {
      Wire.send(Ekran[x][y]);
    }
    Wire.endTransmission();
    
    Wire.beginTransmission(Disp_adr);
    Wire.send (0x40);
    for (int x=81; x<=100; x++)
    {
      Wire.send(Ekran[x][y]);
    }
    Wire.endTransmission();
    
    Wire.beginTransmission(Disp_adr);
    Wire.send (0x40);
    for (int x=101; x<=127; x++)
    {
      Wire.send(Ekran[x][y]);
    }
    Wire.endTransmission();
 }
  
      
}



void setup()
{
   
  pinMode (RES, OUTPUT);  // Вывод RES работает как ВЫХОД
  
  digitalWrite (RES, HIGH); // Процедура перезапуска дисплея
  delay (100);
  digitalWrite (RES, LOW);
  delay (100);
  digitalWrite (RES, HIGH);
  delay (100);
 
 
  Wire.begin(); // Активация шины I2C (MAX32 включается как МАСТЕР)
  
  Init_Disp (Disp_adr_1); // Начальная инициализация дисплея(см. выше)
 
  Send_data(Disp_adr_1); // Очистка экрана (т.к. пока массив пустой)
  
 
 
 //  ----- Следующий блок просто для тестирования (в некоторые места массива записывает букву "R") -------
 // -----------------------------------------------------------------------------------------------------
  for (int i=0; i<=7; i++)
  {
    Ekran[i][0]=Data[i];
  }
    
  for (int i=0; i<=7; i++)
  {
    Ekran[i+120][0]=Data[i];
  }
  
  for (int i=0; i<=7; i++)
  {
    Ekran[i+120][3]=Data[i];
  }
  
  for (int i=0; i<=7; i++)
  {
    Ekran[i][3]=Data[i];
  }
  
  for (int i=0; i<=7; i++)
  {
    Ekran[i][7]=Data[i];
  }
  
  for (int i=0; i<=7; i++)
  {
    Ekran[i+120][7]=Data[i];
  }
 // ------------------------------------------------------------------------------------
  
  
  Send_data(Disp_adr_1); // Копирование содержимого массива на экран
  
   
  
  Wire.beginTransmission(Disp_adr_1); // ОТДЕЛЬНАЯ СЕССИЯ ДЛЯ ВКЛЮЧЕНИЯ ПРОКРУТКИ
                                      // Все переданный байты - КОМАНДЫ
      Wire.send (0x27); // Scroll Setup
      Wire.send (0x00); // Dummy byte
      Wire.send (0b00000000); // B
      Wire.send (0b00000111); // C
      Wire.send (0b00000111); // D
      Wire.send (0x00); // Dummy byte
      Wire.send (0xFF); // Dummy byte
      Wire.send (0x2F); // Activatre scroll
   Wire.endTransmission();  
      
      
   
}



void loop()
{
    
  
}

 

acckyiboxxx
Offline
Зарегистрирован: 14.03.2016

Пытаюсь подключить такой дисплей к 16-й меге и столкнулся с аналогичной проблемой, и так как используется не ардуино ваш код использовать не могу, сторонние библиотеки так-же не устраивают ибо ни одна из найденных ну умеет работать на прерываниях аппаратного TWI , отсюда вопрос - какое колдунство требуется дабы все заработало ?