Перейти к содержанию
    

пытаюсь понять, как работать с этим контроллером (дисплей 128х160 WinStar). главное, что меня интересует: могу ли я использовать имеющуюся на борту контроллера память в качестве буферной для графики? ее вроде гораздо больше, чем нужно для одного экрана, хочу сделать видимую и фоновую страницы, чтобы пока смотрим на видимую, рисовать в фоновой, а потом резко поменять их местами.

 

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да можно

 

Суть в следующем - назначаете адрес графики допустим на ноль. Отображается страница с нулевого адреса.

Считаете, что следующая (фоновая) страница начинается с (128х160/8)

Рисуете там с помощью write или write auto

Назначаете адрес графики на (128х160/8)

Теперь фоновая страница начинается с нуля. Рисуете там

 

Важно.

Не забудьте назначить и почистить область текста и шрифта. А также правила наложения одного на другое. Контроллер знатный - легко прошивается шрифтом в основных однобайтовых кодировках - так что текст лучше выводить нативно (много быстрее получится) чем заморочиваться в отрисовкой в графику.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

большое спасибо! я примерно так и думал.

 

еще вопрос, если не затруднит: поясните мне, что такое Graphic Area? я так понимаю, Graphic Home - это как раз начало графической страницы, а Area что такое?

 

в других контроллерах была возможность задать "окно" в пределах графической области, и тогда последовательный вывод данных построчно заполнял эту область переходя к очередной строке при достижении правого края (или другого края - это тонкости). а в данном контроллере что-то снова мутное написано...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Этот контроллер может работать с разными размерами экрана. Я, например, использовал его в режиме 128х64.

Так вот Graphic Area это в зависимости от контекста либо текущая (отображаемая на экран) область памяти, либо значение в байтах одной строки пикселей.

 

Про второе подробнее - у экрана формат отображения - неупакованный битмап, т.е. фактически рисуем на компе bmp и посылаем его данные прямо в контроллер. Ближе к делу - первый байт области это первые 8 горизонтальных точек в строке (у большинства контроллеров это таки первые точки восьми строк). Таким образ для моего 128х64 - GraphicsArea (182/8=16 байт). для Вашего 128х160 - (160/8=20 байт)

 

Технически, я бы мог задать graphicsArea и в 20 - реально отображалось бы все равно 128. Но переход на новую строку происходил бы по смещению 20 - лазеечка для организации горизонтального скролинга (правда, довольно бестолковая - ибо попиксельного скрола все равно не получается)

 

Это, конечно, если я ничего не путаю. Уже года два как его не касался.

Изменено пользователем Alex A. Mihaylov

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

первый байт области это первые 8 горизонтальных точек в строке (у большинства контроллеров это таки первые точки восьми строк). Таким образ для моего 128х64 - GraphicsArea (182/8=16 байт). для Вашего 128х160 - (160/8=20 байт)
сразу очередной вопрос: первые точки - имеется ввиду левый верхний угол дисплея? а если я для своего дисплея задам GraphicArea = 10, и буду выводить сплошным потоком 0xFF - у меня зальется левая половина дисплея? что-то вот этот момент я не улавливаю...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тоже имеются траблы с этим контроллером. Точнее - RA6963 от Raio, но читал, что он полностью совместим с тошибовским.

Дисплей - WG24064A.

Для начала приведу часть кода инициализации:

uint32_t i;
// здесь настройка портов и сброс
    lcd_write_data (0);
    lcd_write_data (0);
    lcd_send_cmd (0x40); // Set Text Home Address

    lcd_write_data (30);
    lcd_write_data (0);
    lcd_send_cmd (0x41); // Set Text Area

    lcd_write_data (0x00);
    lcd_write_data (0x08);
    lcd_send_cmd (0x42); // Set Graphic Home Address

    lcd_write_data (30);
    lcd_write_data (0);
    lcd_send_cmd (0x43); // Set Graphic Area

    lcd_send_cmd (0x81); // Internal CG ROM mode, EXOR mode
    lcd_send_cmd (0x98); // Text off, graphic on, cursor off

После инициализации выполняю такой цикл:

lcd_write_data (0x00);
lcd_write_data (0x08);
lcd_send_cmd (0x24); // указатель адреса на "Graphic Home Address"
for (i = 0; i < 1920; i++) {
    lcd_write_data (0x00);
    lcd_send_cmd (0xC0); // посылаем байт данных, авто-инкремент указателя адреса 
};

По идее, после выполнения этого кода экран должен полностью очиститься, но на деле не совсем так, последние несколько(вроде бы 64) точек последней строки остаются заполненными случайными значениями.

Если медленно выполнять запись "пустых" байтов и следить за происходящим, то видно, что на подходе к концу текущей стираемой строки(т.е. данная строка еще не стерлась полностью, осталось достаточно много), начинает стираться следующая за ней строка! Ума не приложу, что за фигня происходит.

Да и просто после этой "недоочистки" если попробовать записать байт в произвольное место, то, скажу кратко - на экране отображается не то, что должно быть.

Ну и пара небольших вопросов:

Понятия "курсор" в отношении данного дисплея действительно лишь в текстовом режиме?

Не совсем понятно, зачем нужен Offset регистр, что это за смещение? Если использовать только графический режим, можно ли вообще не трогать этот регистр?

Также не ясно, какую память выбрать - Internal CG ROM, или External CG RAM.

Пересмотрел достаточно исходников, вроде как у меня все аналогично, но проблема откуда-то появилась...

И да, даташит:

RA6963.pdf

Изменено пользователем ohmjke

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Блиин, кто бы мог подумать, вся эта ерунда была оказывается из-за того, что пин FS(font select) висел в воздухе, поэтому поочередно выбирались разные размеры шрифтов. Я как-то даже сразу и не подумал подцепить его куда-нибудь, наверное, предположил, что есть подтяжка по умолчанию.

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

Ура! :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не могу понять, из-за чего происходит искажение.

Видно в начале видео, на 3 и 5 секундах.

В памяти МК буфер, раз в секунду передаю его в память дисплея.

http://youtu.be/-NpJY1v_lI8

Изменено пользователем ohmjke

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не могу понять, из-за чего происходит искажение.

Видно в начале видео, на 3 и 5 секундах.

В памяти МК буфер, раз в секунду передаю его в память дисплея.

http://youtu.be/-NpJY1v_lI8

 

На 14-й странице мануала написано про необходимость проверять статус перед выдачей команд. Делаете?

 

If a status check is not carried out in this state before the next command is sent, there is

the possibility that command or data will not be received.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На 14-й странице мануала написано про необходимость проверять статус перед выдачей команд. Делаете?

Да, делаю.

Просто что странно - то все изображение выводится идеально, то с искажениями, в среднем соотношение 50/50.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, делаю.

Просто что странно - то все изображение выводится идеально, то с искажениями, в среднем соотношение 50/50.

Вставьте задержку микросекунд на 10..20 на установление данных на сигналах перед выдачей стробов.

Да, не лтишне было бы выложить исходник проекта (или той функции, что зовётся lcd_write_data и lcd_send_cmd вместе с вызываемыми внутри их функциями.

Изменено пользователем Genadi Zawidowski

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не уверен в расчетах, так как неизвестно сколько выполняется итерация цикла, но, по-моему, от таких задержек стало еще хуже.

Ниже исходники модуля(без задержек после вывода данных на шину).

#include "lcd.h"

uint8_t lcd_buffer [LCD_HEIGHT][LCD_WIDTH / 8];

extern void lcd_init (void) {
uint32_t i;
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN;

CONTROL_GPIO->CRL &= ~GPIO_CRL_CNF5 & ~GPIO_CRL_CNF6 & ~GPIO_CRL_CNF7 & ~GPIO_CRL_MODE5 & ~GPIO_CRL_MODE6 & ~GPIO_CRL_MODE7;
CONTROL_GPIO->CRH &= ~GPIO_CRH_CNF8 & ~GPIO_CRH_MODE8 & ~GPIO_CRH_CNF9 & ~GPIO_CRH_MODE9;

CONTROL_GPIO->CRL |= GPIO_CRL_MODE5_0 | GPIO_CRL_MODE5_1 | GPIO_CRL_MODE6_0 | GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_0 | GPIO_CRL_MODE7_1;
CONTROL_GPIO->CRH |= GPIO_CRH_MODE8_0 | GPIO_CRH_MODE8_1 | GPIO_CRH_MODE9_0 | GPIO_CRH_MODE9_1;

DATA_GPIO->CRL &= ~GPIO_CRL_CNF0 & ~GPIO_CRL_CNF1 & ~GPIO_CRL_CNF2 & ~GPIO_CRL_CNF3 \
			& ~GPIO_CRL_CNF4 & ~GPIO_CRL_CNF5 & ~GPIO_CRL_CNF6 & ~GPIO_CRL_CNF7 \
			& ~GPIO_CRL_MODE0 & ~GPIO_CRL_MODE1 & ~GPIO_CRL_MODE2 & ~GPIO_CRL_MODE3 \
			& ~GPIO_CRL_MODE4 & ~GPIO_CRL_MODE5 & ~GPIO_CRL_MODE6 & ~GPIO_CRL_MODE7;
DATA_GPIO->CRL |= GPIO_CRL_MODE0_0 | GPIO_CRL_MODE0_1 | GPIO_CRL_MODE1_0 | GPIO_CRL_MODE1_1 \
			| GPIO_CRL_MODE2_0 | GPIO_CRL_MODE2_1 | GPIO_CRL_MODE3_0 | GPIO_CRL_MODE3_1 \
			| GPIO_CRL_MODE4_0 | GPIO_CRL_MODE4_1 | GPIO_CRL_MODE5_0 | GPIO_CRL_MODE5_1 \
			| GPIO_CRL_MODE6_0 | GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_0 | GPIO_CRL_MODE7_1;

CONTROL_GPIO->BSRR = CHIPEN_SET | RD_SET | WR_SET | RESET_CLEAR;
for (i = 0; i < 0xFFFF; i++);
CONTROL_GPIO->BSRR = RESET_SET;

lcd_write_data (GRAPHIC_HOME_ADRESS & 0xFF);
lcd_write_data (GRAPHIC_HOME_ADRESS >> 8);
lcd_send_cmd (SET_GRAPHIC_HOME_ADRESS);

lcd_write_data (GRAPHIC_AREA);
lcd_write_data (0x00);
lcd_send_cmd (SET_GRAPHIC_AREA);

lcd_write_data (TEXT_HOME_ADRESS & 0xFF);
lcd_write_data (TEXT_HOME_ADRESS >> 8);
lcd_send_cmd (SET_TEXT_HOME_ADRESS);

lcd_write_data (TEXT_AREA);
lcd_write_data (0x00);
lcd_send_cmd (SET_TEXT_AREA);

lcd_send_cmd (MODE_SET | MODE_SET_OR | MODE_SET_INT_CG);
lcd_send_cmd (DISPLAY_MODE | DISPLAY_MODE_TEXT_OFF_GRAPHIC_ON);
};

extern void lcd_refresh (void) { 
uint_fast16_t i;
uint8_t *ptr = &(lcd_buffer [0][0]);
lcd_write_data (GRAPHIC_HOME_ADRESS & 0xFF);
lcd_write_data (GRAPHIC_HOME_ADRESS >> 8);
lcd_send_cmd (SET_ADRESS_POINTER);
lcd_send_cmd (SET_DATA_AUTO_WRITE);
for (i = 0; i < (LCD_HEIGHT * (LCD_WIDTH / 8)); i++) {
	lcd_auto_write_data (*ptr);
	ptr++;	
};
lcd_send_cmd (AUTO_RESET);
};

extern void lcd_send_cmd (uint8_t cmd) {
uint32_t i;
DATA_GPIO->CRL &= ~GPIO_CRL_CNF0 & ~GPIO_CRL_CNF1 & ~GPIO_CRL_CNF2 & ~GPIO_CRL_CNF3 \
			& ~GPIO_CRL_CNF4 & ~GPIO_CRL_CNF5 & ~GPIO_CRL_CNF6 & ~GPIO_CRL_CNF7 \
			& ~GPIO_CRL_MODE0 & ~GPIO_CRL_MODE1 & ~GPIO_CRL_MODE2 & ~GPIO_CRL_MODE3 \
			& ~GPIO_CRL_MODE4 & ~GPIO_CRL_MODE5 & ~GPIO_CRL_MODE6 & ~GPIO_CRL_MODE7;
DATA_GPIO->CRL |= GPIO_CRL_CNF0_0 | GPIO_CRL_CNF1_0 | GPIO_CRL_CNF2_0 | GPIO_CRL_CNF3_0 \
			| GPIO_CRL_CNF4_0 | GPIO_CRL_CNF5_0 | GPIO_CRL_CNF6_0 | GPIO_CRL_CNF7_0;
do {
	CONTROL_GPIO->BSRR = CHIPEN_CLEAR | RD_CLEAR | CHOOSE_CODE;
	for (i = 0; i < 5; i++);
	CONTROL_GPIO->BSRR = CHIPEN_SET | RD_SET;
} while ((DATA_GPIO->IDR & 0x03) != 0x03);
DATA_GPIO->CRL &= ~GPIO_CRL_CNF0 & ~GPIO_CRL_CNF1 & ~GPIO_CRL_CNF2 & ~GPIO_CRL_CNF3 \
			& ~GPIO_CRL_CNF4 & ~GPIO_CRL_CNF5 & ~GPIO_CRL_CNF6 & ~GPIO_CRL_CNF7 \
			& ~GPIO_CRL_MODE0 & ~GPIO_CRL_MODE1 & ~GPIO_CRL_MODE2 & ~GPIO_CRL_MODE3 \
			& ~GPIO_CRL_MODE4 & ~GPIO_CRL_MODE5 & ~GPIO_CRL_MODE6 & ~GPIO_CRL_MODE7;
DATA_GPIO->CRL |= GPIO_CRL_MODE0_0 | GPIO_CRL_MODE0_1 | GPIO_CRL_MODE1_0 | GPIO_CRL_MODE1_1 \
			| GPIO_CRL_MODE2_0 | GPIO_CRL_MODE2_1 | GPIO_CRL_MODE3_0 | GPIO_CRL_MODE3_1 \
			| GPIO_CRL_MODE4_0 | GPIO_CRL_MODE4_1 | GPIO_CRL_MODE5_0 | GPIO_CRL_MODE5_1 \
			| GPIO_CRL_MODE6_0 | GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_0 | GPIO_CRL_MODE7_1;
DATA_GPIO->ODR &= ~0xFF;
DATA_GPIO->ODR |= cmd;
CONTROL_GPIO->BSRR = CHIPEN_CLEAR | WR_CLEAR | CHOOSE_CODE;
for (i = 0; i < 5; i++);
CONTROL_GPIO->BSRR = CHIPEN_SET | WR_SET; 	
};

extern void lcd_write_data (uint8_t data) {
uint_fast8_t i;
DATA_GPIO->CRL &= ~GPIO_CRL_CNF0 & ~GPIO_CRL_CNF1 & ~GPIO_CRL_CNF2 & ~GPIO_CRL_CNF3 \
			& ~GPIO_CRL_CNF4 & ~GPIO_CRL_CNF5 & ~GPIO_CRL_CNF6 & ~GPIO_CRL_CNF7 \
			& ~GPIO_CRL_MODE0 & ~GPIO_CRL_MODE1 & ~GPIO_CRL_MODE2 & ~GPIO_CRL_MODE3 \
			& ~GPIO_CRL_MODE4 & ~GPIO_CRL_MODE5 & ~GPIO_CRL_MODE6 & ~GPIO_CRL_MODE7;
DATA_GPIO->CRL |= GPIO_CRL_CNF0_0 | GPIO_CRL_CNF1_0 | GPIO_CRL_CNF2_0 | GPIO_CRL_CNF3_0 \
			| GPIO_CRL_CNF4_0 | GPIO_CRL_CNF5_0 | GPIO_CRL_CNF6_0 | GPIO_CRL_CNF7_0;
do {
	CONTROL_GPIO->BSRR = CHIPEN_CLEAR | RD_CLEAR | CHOOSE_CODE; 
	for (i = 0; i < 5; i++);
	CONTROL_GPIO->BSRR = CHIPEN_SET | RD_SET; 
} while ((DATA_GPIO->IDR & 0x03) != 0x03);
DATA_GPIO->CRL &= ~GPIO_CRL_CNF0 & ~GPIO_CRL_CNF1 & ~GPIO_CRL_CNF2 & ~GPIO_CRL_CNF3 \
			& ~GPIO_CRL_CNF4 & ~GPIO_CRL_CNF5 & ~GPIO_CRL_CNF6 & ~GPIO_CRL_CNF7 \
			& ~GPIO_CRL_MODE0 & ~GPIO_CRL_MODE1 & ~GPIO_CRL_MODE2 & ~GPIO_CRL_MODE3 \
			& ~GPIO_CRL_MODE4 & ~GPIO_CRL_MODE5 & ~GPIO_CRL_MODE6 & ~GPIO_CRL_MODE7;
DATA_GPIO->CRL |= GPIO_CRL_MODE0_0 | GPIO_CRL_MODE0_1 | GPIO_CRL_MODE1_0 | GPIO_CRL_MODE1_1 \
			| GPIO_CRL_MODE2_0 | GPIO_CRL_MODE2_1 | GPIO_CRL_MODE3_0 | GPIO_CRL_MODE3_1 \
			| GPIO_CRL_MODE4_0 | GPIO_CRL_MODE4_1 | GPIO_CRL_MODE5_0 | GPIO_CRL_MODE5_1 \
			| GPIO_CRL_MODE6_0 | GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_0 | GPIO_CRL_MODE7_1;
DATA_GPIO->ODR &= ~0xFF;
DATA_GPIO->ODR |= data;
CONTROL_GPIO->BSRR = CHIPEN_CLEAR | WR_CLEAR | CHOOSE_DATA; 
for (i = 0; i < 5; i++);
CONTROL_GPIO->BSRR = CHIPEN_SET | WR_SET; 
};

extern void lcd_auto_write_data (uint8_t data) {
uint_fast8_t i;
DATA_GPIO->CRL &= ~GPIO_CRL_CNF0 & ~GPIO_CRL_CNF1 & ~GPIO_CRL_CNF2 & ~GPIO_CRL_CNF3 \
			& ~GPIO_CRL_CNF4 & ~GPIO_CRL_CNF5 & ~GPIO_CRL_CNF6 & ~GPIO_CRL_CNF7 \
			& ~GPIO_CRL_MODE0 & ~GPIO_CRL_MODE1 & ~GPIO_CRL_MODE2 & ~GPIO_CRL_MODE3 \
			& ~GPIO_CRL_MODE4 & ~GPIO_CRL_MODE5 & ~GPIO_CRL_MODE6 & ~GPIO_CRL_MODE7;
DATA_GPIO->CRL |= GPIO_CRL_CNF0_0 | GPIO_CRL_CNF1_0 | GPIO_CRL_CNF2_0 | GPIO_CRL_CNF3_0 \
			| GPIO_CRL_CNF4_0 | GPIO_CRL_CNF5_0 | GPIO_CRL_CNF6_0 | GPIO_CRL_CNF7_0;
do {
	CONTROL_GPIO->BSRR = CHIPEN_CLEAR | RD_CLEAR | CHOOSE_CODE;
	for (i = 0; i < 5; i++);
	CONTROL_GPIO->BSRR = CHIPEN_SET | RD_SET; 
} while ((DATA_GPIO->IDR & 0x08) != 0x08);
DATA_GPIO->CRL &= ~GPIO_CRL_CNF0 & ~GPIO_CRL_CNF1 & ~GPIO_CRL_CNF2 & ~GPIO_CRL_CNF3 \
			& ~GPIO_CRL_CNF4 & ~GPIO_CRL_CNF5 & ~GPIO_CRL_CNF6 & ~GPIO_CRL_CNF7 \
			& ~GPIO_CRL_MODE0 & ~GPIO_CRL_MODE1 & ~GPIO_CRL_MODE2 & ~GPIO_CRL_MODE3 \
			& ~GPIO_CRL_MODE4 & ~GPIO_CRL_MODE5 & ~GPIO_CRL_MODE6 & ~GPIO_CRL_MODE7;
DATA_GPIO->CRL |= GPIO_CRL_MODE0_0 | GPIO_CRL_MODE0_1 | GPIO_CRL_MODE1_0 | GPIO_CRL_MODE1_1 \
			| GPIO_CRL_MODE2_0 | GPIO_CRL_MODE2_1 | GPIO_CRL_MODE3_0 | GPIO_CRL_MODE3_1 \
			| GPIO_CRL_MODE4_0 | GPIO_CRL_MODE4_1 | GPIO_CRL_MODE5_0 | GPIO_CRL_MODE5_1 \
			| GPIO_CRL_MODE6_0 | GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_0 | GPIO_CRL_MODE7_1;
DATA_GPIO->ODR &= ~0xFF;
DATA_GPIO->ODR |= data;
CONTROL_GPIO->BSRR = CHIPEN_CLEAR | WR_CLEAR | CHOOSE_DATA;
for (i = 0; i < 5; i++);
CONTROL_GPIO->BSRR = CHIPEN_SET | WR_SET;
};

 

#ifndef __LCD_H
#define __LCD_H

#define STM32F10X_MD_VL
#include "stm32f10x.h"
#define SYSCLK_FREQ (24000000UL)

#define CONTROL_GPIO (GPIOB)
#define DATA_GPIO (GPIOA)

#define WR_SET (GPIO_BSRR_BS8)
#define	WR_CLEAR (GPIO_BSRR_BR8)
#define RD_SET (GPIO_BSRR_BS7)
#define	RD_CLEAR (GPIO_BSRR_BR7)
#define CHIPEN_SET (GPIO_BSRR_BS6)
#define	CHIPEN_CLEAR (GPIO_BSRR_BR6)
#define CHOOSE_CODE (GPIO_BSRR_BS5)
#define	CHOOSE_DATA (GPIO_BSRR_BR5)
#define RESET_SET (GPIO_BSRR_BS9)
#define	RESET_CLEAR (GPIO_BSRR_BR9)

#define LCD_HEIGHT (64)
#define LCD_WIDTH (240)

#define FONT_SIZE (8)

#define	GRAPHIC_HOME_ADRESS (0x2000UL)
#define GRAPHIC_AREA (LCD_WIDTH / 8)
#define TEXT_HOME_ADRESS (0x0000UL)
#define TEXT_AREA (LCD_WIDTH / FONT_SIZE)

#define SET_TEXT_HOME_ADRESS (0x40)
#define SET_GRAPHIC_HOME_ADRESS (0x42)
#define	SET_TEXT_AREA (0x41)
#define	SET_GRAPHIC_AREA (0x43)

#define SET_ADRESS_POINTER (0x24)
#define DATA_WRITE_AND_INCREMENT_ADP (0xC0)
#define SET_DATA_AUTO_WRITE (0xB0)
#define AUTO_RESET (0xB2)

#define	MODE_SET (0x80)
#define MODE_SET_OR (0x00)
#define	MODE_SET_EXOR (0x01)
#define	MODE_SET_AND (0x03)
#define	MODE_SET_ATTRIBUTE (0x04)
#define	MODE_SET_INT_CG (0x00)
#define	MODE_SET_EXT_CG (0x08)

#define	DISPLAY_MODE (0x90)
#define	DISPLAY_MODE_TEXT_ON_GRAPHIC_OFF (0x04)
#define	DISPLAY_MODE_TEXT_OFF_GRAPHIC_ON (0x08)
#define	DISPLAY_MODE_TEXT_ON_GRAPHIC_ON (0x0C)
#define	DISPLAY_MODE_CURSOR_ON_BLINK_OFF (0x02)
#define	DISPLAY_MODE_CURSOR_ON_BLINK_ON (0x03)

extern uint8_t lcd_buffer [LCD_HEIGHT][LCD_WIDTH / 8];

extern void lcd_refresh (void);
extern void lcd_init (void);
extern void lcd_send_cmd (uint8_t cmd);
extern void lcd_write_data (uint8_t data);
extern void lcd_auto_write_data (uint8_t data);

#endif

 

Кстати, использование обычного режима записи данных (не auto), ничего не меняет.

extern void lcd_refresh (void) { 
    uint_fast16_t i;
    uint8_t *ptr = &(lcd_buffer [0][0]);
    lcd_write_data (GRAPHIC_HOME_ADRESS & 0xFF);
    lcd_write_data (GRAPHIC_HOME_ADRESS >> 8);
    lcd_send_cmd (SET_ADRESS_POINTER);
    for (i = 0; i < (LCD_HEIGHT * (LCD_WIDTH / 8)); i++) {
        lcd_write_data (*ptr);
        lcd_send_cmd (DATA_WRITE_AND_INCREMENT_ADP);
        ptr++;    
    };
};

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

То, что стало хуже - не наводит на размышления? В документе на контроллер нет слов про ограничения по минимальной скорости.

После установки стробов внесите задержки - и не такие циклы, как у Вас, которые выкидываются при оптимизации.

 

DATA_GPIO->ODR &= ~0xFF;    
/* тут поставить задержку */
DATA_GPIO->ODR |= cmd;    
/* тут поставить задержку */
CONTROL_GPIO->BSRR = CHIPEN_CLEAR | WR_CLEAR | CHOOSE_CODE;    
/* тут поставить задержку */
CONTROL_GPIO->BSRR = CHIPEN_SET; 
/* тут поставить задержку */
CONTROL_GPIO->BSRR = WR_SET; 
/* тут поставить задержку перед снятием строба */

 

Функция задержки хоть такая:

void _delay_us(int timeUS)
{
    const int top = timeUS * 175 / (CPU_FREQ / 1000000); 
    //
    volatile int n;
    for (n = 0; n < top; ++ n)
    {
    }
}

Изменено пользователем Genadi Zawidowski

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пробовал по-всякому - ничего не помогает. Может ли это быть просто браком?

Экранировал зад платы, подключал контур к земле - безрезультатно.

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

Изменено пользователем ohmjke

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пробовал по-всякому - ничего не помогает. Может ли это быть просто браком?

Покажите тестовый проект.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...