Поищите скетчи по запросу SED1520, раз уж сами написать ну никак. Хотя дисплей то очень примитивный в плане управления. Неужто без скетчей ноги дергать не сможете?
Да, дисплейчик довольно старенький и похож на давно известный KS0107 для WG12864. Ныне с появлением OLED-ов и LCD на интерфейсах SPI и I2C эти старые контроллеры теряют популярность.
Организация дисплея - постраничная, 4 страницы по вертикали, по 8 строк в каждой, младший бит в байте отображается вверху (со стороны выводов). По горизонтали дисплей поделен на две половины от 0 до 60 и от 61 до 121 столбец. Эти половины управляются раздельно пинами CS1 и CS2 соответственно.
Интерфейс - 8-битная шина данных/команд, линия A0 переключения "команды/данные" (0 - команды, 1 - данные), линия R/W (чтение/запись), которую можно не использовать, повесив еёйную на землю, и два вывода CS1 и CS2 для записи в левую и в правую половины дисплея (неактивный уровень - 1, запись по переходу из 1 в 0). Пин RESET соедините с ногой сброса микроконтроллера, отдельно управлять ресетом дисплея не нужно. В версии "Е" дисплея есть пин E, его можно соединить с +5V. Пин CL внешнего осциллятора не задействуется.
Переключаете пин A0 в режим приема команд или данных, выводите на 8-битную шину байт команды или данных, выводы CS1 или CS2 переводите из 1 в 0, затем возвращаете обратно в 1.
Когда передаете команды, дергаете одновременно обе CS1 и CS2, управляя одновременно двумя половинками дисплея. Когда записываете данные для картинки, дергаете CS1 для левой половины (X = от 0 до 60) или CS2 для правой половины (X = от 61 до 121).
Инициализация дисплея очень проста и фактически состоит из одного лишь включения. Для этого нужно подать в обе половины команду 0xAF (для выключения - 0xAE).
После команды включения на дисплее появятся случайно зажженные пиксели, поскольку содержимое GRAM не обнуляется. Если ничего не видно, покрутите резистор контраста, подключенный к пину 3 (Vo).
Графическую информацию дисплей принимает при установленном в 1 входе A0 (команды/данные). После каждого принятого байта инкрементируется счетчик столбцов. Счетчик страниц не инкрементируется, поэтому текущую страницу (page) нужно выставлять вручную командой Set Page Address. Всего есть 4 страницы по вертикали (от 0 до 3), по 8 строк в каждой. Принятый байт отображает 8 пикселей по вертикали в текущей странице и столбце, младшим битом вверх (в сторону контактов модуля). По достижении конца столбцов (61 столбец), нужно установить счетчик столбцов снова в 0.
При полной перерисовке кадра вначале выставляете страницу 0 и столбец 0 в обеих половинах дисплея одновременно. Затем переключаете A0 на режим данных и начинаете побайтно передавать графические данные сначала в левую половину дисплея от 0 до 60 столбца, дергая CS1, затем продолжаете в правую половину дисплея столько же, дергая CS2.
Затем командами устанавливаете страницу 1, столбец 0 в обоих половинах одновременно, дергая одновременно CS1 и CS2 и повторяете вывод графических данных. И так все четыре страницы.
Максимальная частота передачи в дисплей (дергания CS1, CS2) - 1 МГц, что навряд ли будет превышено на медленной тормознутой Ардуине.
Поскольку я не работаю с Ардуиной и не знаю, как там всё устроено, то выложу просто порядок действий (написано для STM32). Макросами обозначены действия с пинами (переключение 0/1) и вывод байта выходной порт.
Управление интерфейсом связи:
- Код:
/** ----------
* @brief Посылка команды в дисплей.
* @details Команда записывается одновременно в обе половины дисплея.
* @param cmd - код команды
*/
void SED1520_IO_SendCmd(uint8_t cmd)
{
A0_CMD() // переход в режим команд (A0 = 0)
DATA_OUT(cmd) // вывод байта в шину данных
CSC_SEL() // CS1, CS2 -\_
CSC_DESEL() // CS1, CS2 _/-
A0_DATA() // завершение режима команд (F0 = 1)
}
/** ----------
* @brief Посылка данных в дисплей.
* @details Байт данных записывается по выбору в первую или вторую
* половину дисплея.
* @param byte - байт данных
* @param part - выбранная часть дисплея (0 - первая, 1 - вторая)
* @note Предполагается, что пин A0 уже переведен в состояние 1 ("данные")
*/
void SED1520_IO_SendData(uint8_t byte, uint8_t part)
{
DATA_OUT(byte); // вывод байта в шину данных
if(part == 0)
CS1_SEL() // CS1 -\_
else
CS2_SEL() // CS2 -\_
CSC_DESEL() // CS1, CS2 _/-
}
Управление дисплеем:
- Код:
#define POWER_CRTL 0xAE // команда управления питанием
#define SET_STARTLINE 0xC0 // команда установки стартовой линии
#define SET_PAGE 0xB8 // команда установки текущей страницы
/** ----------
* @brief Вкл/выкл дисплея.
* @param on - признак включения (0/1)
*/
void SED1520_Power(uint8_t on)
{
SED1520_IO_SendCmd(POWER_CRTL | on);
}
/** ----------
* @brief Установка стартовой линии кадра.
* @param line - номер линии
*/
void SED1520_SetStartLine(uint8_t line)
{
SED1520_IO_SendCmd(SET_STARTLINE | (line & 0x1F));
}
/** ----------
* @brief Установка номеров страницы и столбца
* @param page - страница (0 - 3)
* @param column - столбец (0 - 60)
*/
void SED1520_SetPageAndColumn(uint8_t page, uint8_t column)
{
if(column > 60) column = 0;
SED1520_IO_SendCmd(SET_PAGE | (page & 0x03));
SED1520_IO_SendCmd(column);
}
/** ----------
* @brief Вывод полного кадра в дисплей
* @param *buf - указатель на буфер данных
*/
void SED1520_FullUpdate(uint8_t *buf)
{
/* цикл постранично */
for(uint8_t page = 0; page <= 3; page++)
{
/* установка текущей страницы, нулевой столбец */
SED1520_SetPageAndColumn(page, 0);
/* вывод в первую половину столбцов */
for (uint8_t x = 0; x < 61; x++)
{
SED1520_IO_SendData(*buf, 0);
buf++;
}
/* вывыо во вторую половину столбцов */
for (uint8_t x = 0; x < 61; x++)
{
SED1520_IO_SendData(*buf, 1);
buf++;
}
}
}
Ну и собственно, включить и вывести подготовленный кадр:
- Код:
SED1520_Power(1);
SED1520_FullUpdate((uint8_t*)demo);