Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
#Круги добра
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Я хочу получать рассылки с лучшими постами за неделю
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
Создавая аккаунт, я соглашаюсь с правилами Пикабу и даю согласие на обработку персональных данных.
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam
Пикабу Игры +1000 бесплатных онлайн игр Поднимайтесь как можно выше по дереву, собирайте цветы и дарите их близким.
Вас ждут уникальные награды и 22 выгодных промокода!

Пикаджамп

Аркады, Казуальные, На ловкость

Играть

Топ прошлой недели

  • dec300z dec300z 11 постов
  • AlexKud AlexKud 43 поста
  • DashaAshton DashaAshton 7 постов
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

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

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Помощь Кодекс Пикабу Команда Пикабу Моб. приложение
Правила соцсети О рекомендациях О компании
Промокоды Биг Гик Промокоды Lamoda Промокоды МВидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня
0 просмотренных постов скрыто
26
techn0man1ac
techn0man1ac
9 лет назад
Arduino & Pi

Первое что вывел, когда научился выводить кириллицу на LCD дисплее⁠⁠

Первое что вывел, когда научился выводить кириллицу на LCD дисплее Arduino, Lcd дисплей, Кириллица, Вывод, Mrподелкинц, Hd47780, Мат

Первое что вывел, когда научился выводить кириллицу на LCD дисплее, который её не поддерживает.


Библиотека LiquidCrystalRus тут:

https://github.com/mk90/LiquidCrystalRus

Показать полностью
[моё] Arduino Lcd дисплей Кириллица Вывод Mrподелкинц Hd47780 Мат
28
9
STARTS
STARTS
9 лет назад

Atmega8 + lcd через шину i2c и датчик температуры)⁠⁠

Всем доброго времени суток) Решил поделиться своими успехами в программировании мк atmega8) Подключил lcd через шину i2c, которая позволяет управлять lcd, используя лишь 2 провода) При чем имеется возможность программного включения и отключения подсветки) 

Atmega8 + lcd через шину i2c и датчик температуры) Avr, Микроконтроллеры, Lcd дисплей, Программирование, Atmega8, Хобби, Радиоэлектроника, Длиннопост

Использовал макетку, со стороны кажется что тут нихрена не 2 провода под lcd и не 1 провод под датчик температуры, но на самом деле это так) Просто вставлены еще провода программирования)

Atmega8 + lcd через шину i2c и датчик температуры) Avr, Микроконтроллеры, Lcd дисплей, Программирование, Atmega8, Хобби, Радиоэлектроника, Длиннопост

Сзади виден программатор usbasp, с помощью которого и программируется данный мк)

Atmega8 + lcd через шину i2c и датчик температуры) Avr, Микроконтроллеры, Lcd дисплей, Программирование, Atmega8, Хобби, Радиоэлектроника, Длиннопост

Спасибо, что просмотрели мой пост) Я еще новичок в этом нелегком деле и только начинаю все изучать) 

Показать полностью 3
[моё] Avr Микроконтроллеры Lcd дисплей Программирование Atmega8 Хобби Радиоэлектроника Длиннопост
27
16
Dionisnation
Dionisnation
9 лет назад

ПОДКЛЮЧЕНИЕ ДИСПЛЕЯ NOKIA 1616 НА ПРИМЕРЕ LPC1343⁠⁠

ПОДКЛЮЧЕНИЕ ДИСПЛЕЯ NOKIA 1616 НА ПРИМЕРЕ LPC1343 Много букв, Код, Technobrother, Lcd дисплей, Nokia, Avr, Своими руками, Длиннопост

Дисплей с подсветкой, имеет разрешение 128х160 пикселей и глубину цвета 18 бит. Размеры примерно 28х36мм. шлейф имеет 12 контактных площадок (1-я и 12-я не подключены) с шагом 0.5мм. Логика вся работает от 3.3В и лучше не завышать. От 5В скорее всего сгорит. На подсветку надо около 7В.

UPD: По правильному на питание цифровой схемы надо подать 1.8В и на аналоговую 2.7В, но всё прекрасно работает и от одного источника 3.3В (уже пол года не сгорело ничего), по даташитам это напряжение в пределах допустимого. Так же в комментариях отмечено что появились дисплеи с 3В подсветкой, мне на днях похоже такой же попался, имейте это ввиду.


Работа с дисплеем аналогична работе с Nokia 6100 (статей на эту тему предостаточно) по тому глубоко вдваться не стану, а сконцентрируюсь на различиях.


Отмечу что мне попадалось 2 разновидности дисплеев, но оба работают с данным кодом. Различить их можно по форме шлейфа. Шлейф в форме буквы T — хороший дисплей, верх будет со стороны шлейфа. Если же шлейф просто прямоугольный выходит, то со стороны шлейфа у вас будет низ и ужасно тусклая подстветка. Не знаю, то ли мне бракованный дисплей попался, толи они все такие. На счет подсветки и качества соврал. Промывал от канифоли плату спиртом, в итоге просто слои рассеивателей и поляризаторов разошлись. Не давайте спиртного дисплею, он спивается быстро! :)


Как подключить


В моём варианте работает следующая схема включения:

ПОДКЛЮЧЕНИЕ ДИСПЛЕЯ NOKIA 1616 НА ПРИМЕРЕ LPC1343 Много букв, Код, Technobrother, Lcd дисплей, Nokia, Avr, Своими руками, Длиннопост

Важно! на данной схеме учтены только «подключенные» выводы, крайние в счет не берутся. Таким образом 1-й вывод на схеме соответствует 2-му на дисплее. 10 вывод схемы — 11-му на дисплее.


Взаимодействие


Данный дисплей, как и большенство других цветных Nokia, для взаимодействия использует интерфейс SPI 9 бит. Возможно взаимодействие в режимах 0 и 3 (если память не изменяет). Успешно работает на скоростях 4Мб/с и 9Мб/с, больше проверять не стал. Линия данных на самом деле у дисплея двунаправленная и по ней можно считать такую информацию как ID контроллера в дисплее, но мы её быдем использовать только для записи.


Старший бит является признаком данных: для команды он равен 0, для данных 1. младшие 8 бит содержат либо сами данные, либо код команды.


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


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


И так, получается следующий набор функций (для LPC1343)

void SPI_init() { // Раздел 13.2 UM10375


// Reset SSP (пункт 4)


LPC_SYSCON->PRESETCTRL &= ~(1<<0); // "маска" сброса SSP


LPC_SYSCON->PRESETCTRL |= (1<<0); // 1 в бит RST_SSP_0



// Enable AHB clock to the SSP domain. (пункт 2)


LPC_SYSCON->SYSAHBCLKCTRL |= (1<<11);



// Divide by 1 (SSPCLKDIV also enables to SSP CLK) (пункт 3)


LPC_SSP->CPSR = 0; // отключим тактирование (а то мало ли)



// Set P0.9 to SSP MOSI


LPC_IOCON->PIO0_9 &= ~(7<<0);


LPC_IOCON->PIO0_9 |= (1<<0); // использовать как вывод MOSI


LPC_IOCON->PIO0_9 |= IOCON_COMMON_MODE_PULLUP;



// Set 2.11 to SSP SCK (0.6 and 0.10 can also be used)


LPC_IOCON->SCKLOC = 1; // SCK на вывод 2.11


LPC_IOCON->PIO2_11 &= ~(7<<0); // сброс текущей функции порта ввода-вывода


LPC_IOCON->PIO2_11 |= (1<<0); // использовать как вывод SCK


LPC_IOCON->PIO2_11 |= IOCON_COMMON_MODE_PULLUP;



// Set P0.2/SSEL to GPIO output and high


LPC_IOCON->PIO0_2 &= ~(7<<0); // сброс текущей функции порта ввода-вывода


LPC_IOCON->PIO0_2 |= (1<<0); // использовать как вывод SSEL (можно обычным GPIO как 0)


LPC_IOCON->PIO0_2 |= IOCON_COMMON_MODE_PULLUP;


LPC_GPIO0->DIR |= 1<<2;


LPC_GPIO0->DATA |= 1<<2;



// If SSP0CLKDIV = DIV1 -- (PCLK / (CPSDVSR X [SCR+1])) = (72,000,000 / (2 x [3 + 1])) = 9.0 MHz


LPC_SSP->CR0 = ( (8<<0) // Размер данных 1000 - 9 бит


| (0<<4) // Формат фрейма 00 - SPI


| (0<<6) // Полярность 0 - низкий уровень между фреймами


| (0<<7) // Фаза 0 - по нарастанию


| (3<<8) // Делитель частоты шины на бит


) ;



// Clock prescale register must be even and at least 2 in master mode


LPC_SSP->CPSR = 2; // пердделитель 2-254 (кратно 2)



// Enable device and set it to master mode, no loopback (разрешаем работу)


LPC_SSP->CR1 = ( (0<<0) // 0 - Loop Back Mode Normal


| (1<<1) // Разрешение работы 1 - разрешено


| (0<<2) // Режим ведущий-ведомый 0 - мастер


);


}



void SPI_send(uint16_t value) {


while ((LPC_SSP->SR & ((1<<1) | (1<<4))) != (1<<1)); // если буффер передачи не переполнен и устройство не занято


LPC_SSP->DR = value;


}



// Вспомогательные макросы


#define LCD_send(x) SPI_send(x)


#define LCD_command(cmd) LCD_send(cmd)


#define LCD_data(data) LCD_send(0x0100|(uint8_t)(data))



void LCD_reset(void) {


// Настройка для вывода Reset дисплея


LPC_IOCON->PIO0_8 &= ~(7<<0); // сброс текущей функции порта ввода-вывода


LPC_IOCON->PIO0_8 |= IOCON_COMMON_MODE_PULLUP;


LPC_GPIO0->DIR |= 1<<8;


LPC_GPIO0->DATA |= 1<<8;


// Настройка для вывода Select


LPC_IOCON->PIO0_2 &= ~(7<<0); // Временно отключаем спецфункцию вывода выбора SPI


delayms(100);


// Сброс дисплея


LPC_GPIO0->DATA &= ~(1<<2); // ncs = 0


LPC_GPIO0->DATA &= ~(1<<8); // nrst = 0


delayms(100);


LPC_GPIO0->DATA |= 1<<8; // nrst = 1


LPC_GPIO0->DATA |= 1<<2; // ncs = 1


delayms(100);


// Возврат спецфункции


LPC_IOCON->PIO0_2 |= (1<<0); // использовать как вывод SSEL


}

В этих функциях по сути собран весь аппаратно-зависимый код. именно по этой причине функция LCD_reset включена сюда, хотя правильнее её описать в следующем разделе. Я использовал «фоновый вывод данных», так функция SPI_send сначала ожидает окончания вывода предидущего байта (9 бит), затем помещает очередной байт (9 бит) на вывод и возвращается не ожидая завершения операции вывода.


Важно: Линию выбора дисплея CS обязательно надо периодически освобождать, иначе вывода никакого не будет, получите просто белый экран. У меня используется полностью аппаратный контроль.


Инициализация дисплея


Идем по пути найменьшего сопротивления, и одалживаем у тов. Rossum’а код для работы с дисплеями Nokia из проекта NokiaSuperBreakout. Не беда что нашего дисплея нет в перечислении, берём тот что соответствует диспею 132х160 контроллер SPFD54124B.


Данный код настраивает дисплей на 16-битный индексный режим вывода, в итоге получаем формат BGR 5-6-5. по биту глубины на R и B мы теряем, но зато получаем возможность передавать только 2 бата на один пиксель, взамен 3-х в 18битном режиме.


Перед инициализацией надо не забыть сбросить дисплей (иногда критично).

const uint16_t init_lcd1616ph[] = {


0xBA, 0x107, 0x115, // Data Order


0x25, 0x13F, // Contrast


0x11, // Sleep Out


0x13, // Display Normal mode



0x37,0x100, // VSCROLL ADDR


0x3A,0x105, // COLMOD pixel format 4=12,5=16,6=18


0x29, // DISPON


0x20, // INVOFF


0x13 // NORON


};



void LCD_init()


{


const uint16_t *data = &init_lcd1616ph[0];


uint16_t size = sizeof(init_lcd1616ph)/sizeof(init_lcd1616ph[0]);


while(size--) {


LCD_send(*data++);


}


LCD_command(0x2D);


int i;


for (i = 0; i < 32; i++)


LCD_data(i<<1);


for (i = 0; i < 64; i++)


LCD_data(i);


for (i = 0; i < 32; i++)


LCD_data(i<<1);


delay(100);


m_lcdResetClip();


EndDraw();


SetFont(0);


}

Про m_lcdResetClip, EndDraw и SetFont потом.


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



Вывод графики



Принцип вывода у всех встреченных мной дисплеев один. Вначале передается команда выбора диапазона строк, затем диапазона столбцов, после чего попиксельно выводятся пиксели в получившееся окно. Таким образом для вывода изображения в области [ x1:y1, x2:y2 ] надо передать следующую последовательность:


[PASET] [y1] [y2] [CASET] [x1] [x2] [RAMWR] [pixel_1] [pixel_2]… [pixel_N]


Однако, в отличии от 6100 дисплей для 1616 каждая из величин координат (x1, x1, y1, y2) имеет 2-хбайтовый размер, не смотря на то, что старший байт всегда нулевой. Контроллер дисплея сам будет переносить «курсор» вывода в окне на следующую строку вывода, при достижении правой границ окна. Направление заполнения слева-направо, сверху вниз. Удобно. Ну и немаловажный фактор: левый верхний угол имеет координату x:y = 2:1.


Таким образом получаем что на операцию вывода требуется передать 11 служебных байт плюс 2хN байт данных. Естественно получаем что выгоднее выводить прямогольными областями по несколько пикселей за раз.


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

// Nokia1616


#define displayOffsetX 2


#define displayOffsetY 1


#define displayWidth 128


#define displayHeight 160



#define RGB(r, g, b) (((uint32_t)(R))|((uint32_t)(g)<<8)|((uint32_t)(b)<<16))


#define RECT_set(rect, l, t, r, b) { (rect).left = (l); (rect).top = (t); (rect).right = (R); (rect).bottom = (b); }



// Описание переменных


RECT m_lcdBound; // Установленная для вывода область


POINT m_lcdOutput; // Очередная позиция для вывода


RECT m_lcdClip; // Размеры области отсечения


uint8_t m_lcdClipOutput; // Активны ли отсечения в текущей итерации вывода



uint32_t BeginDraw(int16_t left, int16_t top, uint16_t width, uint16_t height)


{


int16_t right = left + width - 1;


int16_t bottom = top + height - 1;


if( left >= m_lcdClip.left && top >= m_lcdClip.top && right <= m_lcdClip.right && bottom <= m_lcdClip.bottom ) { // RectInRect


// область вывода полностью видима, используем "быстрый" вывод без проверок отсечения


m_lcdClipOutput = 0;


} else {


// область вывода частично либо полностью невидима на дисплее, используем вывод с проверкой отсечений


m_lcdClipOutput = 1;


m_lcdOutput.x = left;


m_lcdOutput.y = top;


RECT_set(m_lcdBound, left, top, right, bottom);


if(left < m_lcdClip.left) left = m_lcdClip.left; // ClipRect


if(top < m_lcdClip.top) top = m_lcdClip.top;


if(right > m_lcdClip.right) right = m_lcdClip.right;


if(bottom > m_lcdClip.bottom) bottom = m_lcdClip.bottom;


}


if( left > right || top > bottom ) { // IsRectValid


// область не видна на дисплее, завершаем вывод


EndDraw();


return 0;


}


uint32_t count;


// Устанавливаем "виртуальные" границы вывода


LCD_command(0x2A); //LCD_command(CASETP);


count = right - left + 1;


left += displayOffsetX;


right += displayOffsetX;


LCD_data(left>>8);


LCD_data(left);


LCD_data(right>>8);


LCD_data(right);


// Диапозон строк


LCD_command(0x2B); //LCD_command(PASETP);


count *= (bottom - top + 1);


top += displayOffsetY;


bottom += displayOffsetY;


LCD_data(top>>8);


LCD_data(top);


LCD_data(bottom>>8);


LCD_data(bottom);


LCD_command(0x2C); //LCD_command(RAMWR);


// Возвращаем количество видимых пикселей


return count;


}



void EndDraw()


{


m_lcdClipOutput = 1;


m_lcdBound.right = m_lcdBound.left - 1; // SetRect


}



void NextPoint(uint32_t color)


{


// Надо ли проверять отсечения при выводе


if( m_lcdClipOutput ) {


int16_t x = m_lcdOutput.x;


int16_t y = m_lcdOutput.y;


// учит.отсеч.


//if(!m_lcdClip.width /* || !m_lcdClip.height */) return;


if(m_lcdBound.right < m_lcdBound.left) { // IsRectValid вывод недоступен


return;


}


// Смещение на следующую позицию вывода


if( m_lcdOutput.x >= m_lcdBound.right ) {


// Если в конце строки - переходим на следующую


m_lcdOutput.x = m_lcdBound.left;


if( m_lcdOutput.y >= m_lcdBound.bottom ) {


// Если последняя точка, переходим в начало (или можно завершить вывод вызовом EndDraw)


m_lcdOutput.y = m_lcdBound.top;


} else {


m_lcdOutput.y++;


}


} else {


m_lcdOutput.x++;


}


if(!(x >= m_lcdClip.left && x <= m_lcdClip.right && y >= m_lcdClip.top && y <= m_lcdClip.bottom) ) { // PtInRect


return;


}


}


// точка будет видимой


uint8_t r = color;


uint8_t g = color>>8;


uint8_t b = color>>16;


LCD_data((r&0xF8)|(g>>5));


LCD_data(((g<<3)&0xE0)|(b>>3));


}

Данные функции являются «дисплей ориентированными» и могут быть изменены для работы с другим дисплеем (естественно не забыв и про функцию инифиализации).


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


В функции настройки отображения я прибавляю смещение начала координат, что позволяет мне не запоминать с каким именно дисплеем я работаю. С той же целью для цвета используется 32-битное значение, по 8 бит на компоненту, и 8 бит прозапас и для выравнивания.


Функция вывода очередной точки NextPoint должна выполнить некоторые проверки и расчеты, тут нам позволит хорошо ускорить процесс использование фонового вывода на дисплей: пока по SPI передаются данные, мы проводим свои проверки для следующей точки.


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


Ну и для завершения картины средства для работы с отсечениями:

typedef struct _tagPOINT {


int16_t x;


int16_t y;


} POINT, *PPOINT;



typedef struct _tagRECT {


int16_t left;


int16_t top;


int16_t right;


int16_t bottom;


} RECT, *PRECT;



void m_lcdSetClip(const RECT *r)


{


// Проверяем на видимость отсечения


RECT_set(m_lcdClip, r->left, r->top, r->right, r->bottom);


// Устанавливаем "абсолютное" ограничение для вывода c усечением до границ дисплея


if(m_lcdClip.left < 0) m_lcdClip.left = 0; // ClipRect


if(m_lcdClip.top < 0) m_lcdClip.top = 0;


if(m_lcdClip.right >= displayWidth) m_lcdClip.right = displayWidth - 1;


if(m_lcdClip.bottom >= displayHeight) m_lcdClip.bottom = displayHeight - 1;


// Is clip valid


if(m_lcdClip.bottom < m_lcdClip.top || m_lcdClip.right < m_lcdClip.left) { // IsRectValid


// invalid clip region


RECT_set(m_lcdClip, 0, 0, -1, -1);


}


}



void m_lcdResetClip()


{


RECT_set(m_lcdClip, 0, 0, displayWidth - 1, displayHeight - 1);


}

Примитивы


Самое простое пожалуй это закрасить область одним цветом.

void Fill(int16_t left, int16_t top, uint16_t width, uint16_t height, uint32_t color)


{


uint32_t count;


count = BeginDraw(left, top, width, height); // Функция возвращает количество видивых пикселей в установленной области вывода.


m_lcdClipOutput = 0; // Принудительно меняем функцию вывода, выводим только необходимое количество пикселей


while(count--) {


NextPoint(color);


}


EndDraw();


}



void Clear(uint32_t color)


{


Fill(0, 0, displayWidth, displayHeight, color);


}



void Pixel(int16_t x, int16_t y, uint32_t color)


{


Fill(x, y, 1, 1, color);


}

А проверяется всё это дело так:

SPI_init();


LCD_reset();


LCD_init();


Clear(0x00000000);


Fill(10, 20, 30, 40, 0x00FF00FF);

Показать полностью 2
Много букв Код Technobrother Lcd дисплей Nokia Avr Своими руками Длиннопост
22
breadgreen
breadgreen
9 лет назад

Замена дисплея Nokia E52 Slow mo⁠⁠

[моё] Nokia E52 Замена экрана Ремонт Lcd дисплей Видео
0
MasterSglaza
MasterSglaza
10 лет назад

Хорошо, что придумали LCD мониторы.⁠⁠

Муху можно курсором сгонять.
Lcd дисплей Муха Текст
4
3
BelkaVduple
BelkaVduple
10 лет назад

Интересно почему?⁠⁠

Умер монитор сегодня, не включается, отрыл старенький моник 99 года, плоский CRT, модель CTX какой то. так вот работает, правда изображение прыгает, видимо лампа стабилизации уже дохлая, но работает, монику 16 лет, а сдох моник которому 3 года, прогресс не стоит на месте.
[моё] Монитор Crt Lcd дисплей Смерть Жив Текст
15
1
Enkwen
Enkwen
10 лет назад

Реакция монохромного дисплея на попытку его прожечь увеличительным стёклышком⁠⁠

Сложно найти человека, который не пытался что-то поджечь, сфокусировав солнечные лучи с помощью лупы. А что выйдет, если то же проделать с цифрами на дисплее?
[моё] Жилой комплекс Lcd дисплей Солнце Издевательство Эксперимент Видео
8
1
GuRu321
GuRu321
10 лет назад

LCD телевизор, как это работает?⁠⁠

Продолжаем тему интересного об обыденном.
Как это сделано Телевизор Lcd дисплей Факты Видео
0
Посты не найдены
О нас
О Пикабу Контакты Реклама Сообщить об ошибке Сообщить о нарушении законодательства Отзывы и предложения Новости Пикабу Мобильное приложение RSS
Информация
Помощь Кодекс Пикабу Команда Пикабу Конфиденциальность Правила соцсети О рекомендациях О компании
Наши проекты
Блоги Работа Промокоды Игры Курсы
Партнёры
Промокоды Биг Гик Промокоды Lamoda Промокоды Мвидео Промокоды Яндекс Директ Промокоды Отелло Промокоды Aroma Butik Промокоды Яндекс Путешествия Постила Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии