имеется такой вот дисплей SP14Q002-A, весьма себе замечательный и еще и размеров приличных
даташит
https://datasheet.octopart.com/SP14Q002 ... 835662.pdf
дисплей подключен так
Arduino Due -> (LCD Display)
D2 -> (CP)
D3 -> (LOAD)
D4 -> (FRAME)
D5 -> (DISP_OFF)
D6 -> (D0)
D7 -> (D1)
D8 -> (D2)
D9 -> (D3)
т.к. в программировании я особо не силен, уже несколько дней пытаюсь застравить чат жпт и дипсик помочь мне с этим делом.
В итоге имеем 2 скетча, но картинка форматируется неверно
Код: Выделить всё
// ----------
// Arduino Due -> 4-bit LCD Display
// Исправленный порядок бит, тестовые паттерны
// ----------
// Пины подключения
#define CP_PIN 2
#define LOAD_PIN 3
#define FRAME_PIN 4
#define DISP_OFF_PIN 5
#define D0_PIN 6
#define D1_PIN 7
#define D2_PIN 8
#define D3_PIN 9
// Разрешение дисплея
#define X_RES 320
#define Y_RES 240
#define BYTES_PER_LINE 80 // 4 пикселя на байт
// Прямой доступ к портам
#define PORT_CP (g_APinDescription[CP_PIN].pPort->PIO_ODSR)
#define PORT_LOAD (g_APinDescription[LOAD_PIN].pPort->PIO_ODSR)
#define PORT_FRAME (g_APinDescription[FRAME_PIN].pPort->PIO_ODSR)
#define PORT_D0 (g_APinDescription[D0_PIN].pPort->PIO_ODSR)
#define PORT_D1 (g_APinDescription[D1_PIN].pPort->PIO_ODSR)
#define PORT_D2 (g_APinDescription[D2_PIN].pPort->PIO_ODSR)
#define PORT_D3 (g_APinDescription[D3_PIN].pPort->PIO_ODSR)
#define MASK_CP (g_APinDescription[CP_PIN].ulPin)
#define MASK_LOAD (g_APinDescription[LOAD_PIN].ulPin)
#define MASK_FRAME (g_APinDescription[FRAME_PIN].ulPin)
#define MASK_D0 (g_APinDescription[D0_PIN].ulPin)
#define MASK_D1 (g_APinDescription[D1_PIN].ulPin)
#define MASK_D2 (g_APinDescription[D2_PIN].ulPin)
#define MASK_D3 (g_APinDescription[D3_PIN].ulPin)
// ----------
// Frame buffer
uint8_t frameBuffer[Y_RES][BYTES_PER_LINE];
// ----------
// Мини-задержка ~150ns
inline void shortDelay() {
asm volatile(
"nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"
);
}
// Быстрый тактовый импульс CP
inline void pulseCP() {
PORT_CP &= ~MASK_CP;
shortDelay();
PORT_CP |= MASK_CP;
shortDelay();
}
// Быстрый импульс LOAD H->L
inline void pulseLOAD() {
PORT_LOAD &= ~MASK_LOAD;
shortDelay();
PORT_LOAD |= MASK_LOAD;
shortDelay();
}
// ----------
// Работа с пикселями
void setAllBlack() {
for (int y = 0; y < Y_RES; y++)
for (int x = 0; x < BYTES_PER_LINE; x++)
frameBuffer[y][x] = 0x00;
}
// Установка пикселя с правильным порядком бит
void setPixel(int x, int y, bool state) {
if (x < 0 || x >= X_RES || y < 0 || y >= Y_RES) return;
int byteIndex = x / 4;
int bitPosition = 3 - (x % 4); // D0 = старший бит первого пикселя
if (state) frameBuffer[y][byteIndex] |= (1 << bitPosition);
else frameBuffer[y][byteIndex] &= ~(1 << bitPosition);
}
// ----------
// Тестовые паттерны
void drawGrid() {
setAllBlack();
// Вертикальные линии каждые 32 пикселя
for (int x = 0; x < X_RES; x += 32)
for (int y = 0; y < Y_RES; y++)
setPixel(x, y, true);
// Горизонтальные линии каждые 32 пикселя
for (int y = 0; y < Y_RES; y += 32)
for (int x = 0; x < X_RES; x++)
setPixel(x, y, true);
// Угловые маркеры
setPixel(0, 0, true);
setPixel(X_RES-1, 0, true);
setPixel(0, Y_RES-1, true);
setPixel(X_RES-1, Y_RES-1, true);
// Центральный крест
for (int x = X_RES/2-16; x < X_RES/2+16; x++)
setPixel(x, Y_RES/2, true);
for (int y = Y_RES/2-16; y < Y_RES/2+16; y++)
setPixel(X_RES/2, y, true);
}
void drawPatternTest() {
for (int y = 0; y < Y_RES; y++)
for (int x = 0; x < X_RES; x++)
setPixel(x, y, ((x/7 + y/8) % 2) == 0);
}
// ----------
// Отправка 4 бит на D0-D3
void send4Bits(uint8_t data) {
if (data & 0x01) PORT_D0 |= MASK_D0; else PORT_D0 &= ~MASK_D0;
if (data & 0x02) PORT_D1 |= MASK_D1; else PORT_D1 &= ~MASK_D1;
if (data & 0x04) PORT_D2 |= MASK_D2; else PORT_D2 &= ~MASK_D2;
if (data & 0x08) PORT_D3 |= MASK_D3; else PORT_D3 &= ~MASK_D3;
pulseCP();
}
// ----------
// Отправка кадра
void displayFrame() {
PORT_FRAME |= MASK_FRAME; // FRAME высокий для первой строки
shortDelay();
for (int y = 0; y < Y_RES; y++) {
for (int x = 0; x < BYTES_PER_LINE; x++)
send4Bits(frameBuffer[y][x]);
pulseLOAD(); // фиксация линии
if (y == 0) PORT_FRAME &= ~MASK_FRAME;
}
}
// ----------
// Arduino setup
void setup() {
pinMode(CP_PIN, OUTPUT);
pinMode(LOAD_PIN, OUTPUT);
pinMode(FRAME_PIN, OUTPUT);
pinMode(DISP_OFF_PIN, OUTPUT);
pinMode(D0_PIN, OUTPUT);
pinMode(D1_PIN, OUTPUT);
pinMode(D2_PIN, OUTPUT);
pinMode(D3_PIN, OUTPUT);
PORT_CP |= MASK_CP;
PORT_LOAD |= MASK_LOAD;
PORT_FRAME &= ~MASK_FRAME;
digitalWrite(DISP_OFF_PIN, HIGH);
// Выберите тестовый паттерн
drawGrid();
//drawPatternTest();
}
// ----------
// Arduino loop
void loop() {
displayFrame(); // непрерывное обновление
}
формирует тестовые паттерны сетку и шахматку
но работает неочень и выглядит вот так
сетка не совсем сетка
и шахматка не совсем шахматка
и 2й скетч пытается выводить надпись hello world
Код: Выделить всё
// ----------
// Arduino Due -> 4-bit LCD Display
// HELLO WORLD жирным шрифтом, корректное отображение
// ----------
#define CP_PIN 2
#define LOAD_PIN 3
#define FRAME_PIN 4
#define DISP_OFF_PIN 5
#define D0_PIN 6
#define D1_PIN 7
#define D2_PIN 8
#define D3_PIN 9
#define X_RES 320
#define Y_RES 240
#define BYTES_PER_LINE 80 // 4 пикселя на байт
#define PORT_CP (g_APinDescription[CP_PIN].pPort->PIO_ODSR)
#define PORT_LOAD (g_APinDescription[LOAD_PIN].pPort->PIO_ODSR)
#define PORT_FRAME (g_APinDescription[FRAME_PIN].pPort->PIO_ODSR)
#define PORT_D0 (g_APinDescription[D0_PIN].pPort->PIO_ODSR)
#define PORT_D1 (g_APinDescription[D1_PIN].pPort->PIO_ODSR)
#define PORT_D2 (g_APinDescription[D2_PIN].pPort->PIO_ODSR)
#define PORT_D3 (g_APinDescription[D3_PIN].pPort->PIO_ODSR)
#define MASK_CP (g_APinDescription[CP_PIN].ulPin)
#define MASK_LOAD (g_APinDescription[LOAD_PIN].ulPin)
#define MASK_FRAME (g_APinDescription[FRAME_PIN].ulPin)
#define MASK_D0 (g_APinDescription[D0_PIN].ulPin)
#define MASK_D1 (g_APinDescription[D1_PIN].ulPin)
#define MASK_D2 (g_APinDescription[D2_PIN].ulPin)
#define MASK_D3 (g_APinDescription[D3_PIN].ulPin)
uint8_t frameBuffer[Y_RES][BYTES_PER_LINE];
// ----------
// Мини-задержка ~150ns
inline void shortDelay() {
asm volatile("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n");
}
// Быстрый тактовый импульс CP
inline void pulseCP() {
PORT_CP &= ~MASK_CP;
shortDelay();
PORT_CP |= MASK_CP;
shortDelay();
}
// Быстрый импульс LOAD H->L
inline void pulseLOAD() {
PORT_LOAD &= ~MASK_LOAD;
shortDelay();
PORT_LOAD |= MASK_LOAD;
shortDelay();
}
// ----------
// Работа с пикселями
void setAllBlack() {
for (int y = 0; y < Y_RES; y++)
for (int x = 0; x < BYTES_PER_LINE; x++)
frameBuffer[y][x] = 0x00;
}
void setPixel(int x, int y, bool state) {
if (x < 0 || x >= X_RES || y < 0 || y >= Y_RES) return;
int byteIndex = x / 4;
int bitPosition = 3 - (x % 4); // D0 = старший бит первого пикселя
if (state) frameBuffer[y][byteIndex] |= (1 << bitPosition);
else frameBuffer[y][byteIndex] &= ~(1 << bitPosition);
}
// ----------
// Отправка 4 бит на D0-D3
void send4Bits(uint8_t data) {
if (data & 0x01) PORT_D0 |= MASK_D0; else PORT_D0 &= ~MASK_D0;
if (data & 0x02) PORT_D1 |= MASK_D1; else PORT_D1 &= ~MASK_D1;
if (data & 0x04) PORT_D2 |= MASK_D2; else PORT_D2 &= ~MASK_D2;
if (data & 0x08) PORT_D3 |= MASK_D3; else PORT_D3 &= ~MASK_D3;
pulseCP();
}
// ----------
// Отправка кадра
void displayFrame() {
PORT_FRAME |= MASK_FRAME;
shortDelay();
for (int y = 0; y < Y_RES; y++) {
for (int x = 0; x < BYTES_PER_LINE; x++)
send4Bits(frameBuffer[y][x]);
pulseLOAD();
if (y == 0) PORT_FRAME &= ~MASK_FRAME;
}
}
// ----------
// Жирный шрифт 16x16, горизонтальные байты для LCD
// Каждая строка = 16 бит, потом разбиваем на 4-битные пиксели
// Для примера: только буквы HELLO WORLD и пробел
const uint16_t font_H[16] = {
0b1111000111110001,
0b1111000111110001,
0b1111000111110001,
0b1111000111110001,
0b1111111111111111,
0b1111111111111111,
0b1111000111110001,
0b1111000111110001,
0b1111000111110001,
0b1111000111110001,
0b1111000111110001,
0b1111000111110001,
0b1111000111110001,
0b1111000111110001,
0b1111000111110001,
0b1111000111110001
};
const uint16_t font_E[16] = {
0b1111111111111111,
0b1111111111111111,
0b1111000000000000,
0b1111000000000000,
0b1111111111111110,
0b1111111111111110,
0b1111000000000000,
0b1111000000000000,
0b1111000000000000,
0b1111000000000000,
0b1111111111111111,
0b1111111111111111,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000
};
const uint16_t font_L[16] = {
0b1111000000000000,
0b1111000000000000,
0b1111000000000000,
0b1111000000000000,
0b1111000000000000,
0b1111000000000000,
0b1111000000000000,
0b1111000000000000,
0b1111000000000000,
0b1111000000000000,
0b1111111111111111,
0b1111111111111111,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000
};
const uint16_t font_O[16] = {
0b0111111111111110,
0b1111111111111111,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111111111111111,
0b0111111111111110,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000
};
const uint16_t font_W[16] = {
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111000000001111,
0b1111001100111111,
0b1111001100111111,
0b1111010010111111,
0b1111010010111111,
0b1111100001111111,
0b1111100001111111,
0b1111000000001111,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000
};
const uint16_t font_R[16] = {
0b1111111111111000,
0b1111111111111100,
0b1111000000001110,
0b1111000000000111,
0b1111000000000111,
0b1111111111111100,
0b1111111111111000,
0b1111001000000000,
0b1111000100000000,
0b1111000010000000,
0b1111000001111000,
0b1111000001111100,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000
};
const uint16_t font_D[16] = {
0b1111111111110000,
0b1111111111111000,
0b1111000000011100,
0b1111000000001100,
0b1111000000000110,
0b1111000000000110,
0b1111000000000110,
0b1111000000000110,
0b1111000000001100,
0b1111000000011000,
0b1111111111111000,
0b1111111111110000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000
};
const uint16_t font_space[16] = {0};
// ----------
// Рисуем символ на LCD
void drawChar16x16_LCD(int x0, int y0, const uint16_t* bitmap) {
for (int y = 0; y < 16; y++) {
for (int x = 0; x < 16; x++) {
bool pixel = bitmap[y] & (1 << (15 - x));
setPixel(x0 + x, y0 + y, pixel);
// Жирный: дублируем пиксель справа
setPixel(x0 + x + 1, y0 + y, pixel);
}
}
}
// ----------
// Рисуем строку HELLO WORLD
void drawHelloWorld_LCD(int x0, int y0) {
const uint16_t* chars[] = {font_H, font_E, font_L, font_L, font_O, font_space,
font_W, font_O, font_R, font_L, font_D};
int px = x0;
for (int i = 0; i < 11; i++) {
drawChar16x16_LCD(px, y0, chars[i]);
px += 18; // шаг между символами
}
}
// ----------
// Setup & loop
void setup() {
pinMode(CP_PIN, OUTPUT);
pinMode(LOAD_PIN, OUTPUT);
pinMode(FRAME_PIN, OUTPUT);
pinMode(DISP_OFF_PIN, OUTPUT);
pinMode(D0_PIN, OUTPUT);
pinMode(D1_PIN, OUTPUT);
pinMode(D2_PIN, OUTPUT);
pinMode(D3_PIN, OUTPUT);
PORT_CP |= MASK_CP;
PORT_LOAD |= MASK_LOAD;
PORT_FRAME &= ~MASK_FRAME;
digitalWrite(DISP_OFF_PIN, HIGH);
setAllBlack();
drawHelloWorld_LCD(50, 100); // координаты для центрирования
}
void loop() {
displayFrame();
}
ну и тут с отображением все не так как надо
и + ко всему картинка и там и там дико мерцает
подскажите как пофиксить
