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

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

Alex A. Mihaylov
Да можно

Суть в следующем - назначаете адрес графики допустим на ноль. Отображается страница с нулевого адреса.
Считаете, что следующая (фоновая) страница начинается с (128х160/8)
Рисуете там с помощью write или write auto
Назначаете адрес графики на (128х160/8)
Теперь фоновая страница начинается с нуля. Рисуете там

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

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

в других контроллерах была возможность задать "окно" в пределах графической области, и тогда последовательный вывод данных построчно заполнял эту область переходя к очередной строке при достижении правого края (или другого края - это тонкости). а в данном контроллере что-то снова мутное написано...
Alex A. Mihaylov
Этот контроллер может работать с разными размерами экрана. Я, например, использовал его в режиме 128х64.
Так вот Graphic Area это в зависимости от контекста либо текущая (отображаемая на экран) область памяти, либо значение в байтах одной строки пикселей.

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

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

Это, конечно, если я ничего не путаю. Уже года два как его не касался.
ARV
Цитата(Alex A. Mihaylov @ Jan 17 2012, 13:29) *
первый байт области это первые 8 горизонтальных точек в строке (у большинства контроллеров это таки первые точки восьми строк). Таким образ для моего 128х64 - GraphicsArea (182/8=16 байт). для Вашего 128х160 - (160/8=20 байт)
сразу очередной вопрос: первые точки - имеется ввиду левый верхний угол дисплея? а если я для своего дисплея задам GraphicArea = 10, и буду выводить сплошным потоком 0xFF - у меня зальется левая половина дисплея? что-то вот этот момент я не улавливаю...
ohmjke
Тоже имеются траблы с этим контроллером. Точнее - 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.
Пересмотрел достаточно исходников, вроде как у меня все аналогично, но проблема откуда-то появилась...
И да, даташит:
ohmjke
Блиин, кто бы мог подумать, вся эта ерунда была оказывается из-за того, что пин FS(font select) висел в воздухе, поэтому поочередно выбирались разные размеры шрифтов. Я как-то даже сразу и не подумал подцепить его куда-нибудь, наверное, предположил, что есть подтяжка по умолчанию.
Собственно, остальные вопросы тоже отпадают, т.к. пока искал решение своей проблемы прочитал один хороший документ по этому контроллеру и со всем разобрался.
Ура! biggrin.gif
ohmjke
Не могу понять, из-за чего происходит искажение.
Видно в начале видео, на 3 и 5 секундах.
В памяти МК буфер, раз в секунду передаю его в память дисплея.
http://youtu.be/-NpJY1v_lI8
Genadi Zawidowski
Цитата(ohmjke @ May 29 2012, 17:41) *
Не могу понять, из-за чего происходит искажение.
Видно в начале видео, на 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.
ohmjke
Цитата(Genadi Zawidowski @ May 30 2012, 00:25) *
На 14-й странице мануала написано про необходимость проверять статус перед выдачей команд. Делаете?

Да, делаю.
Просто что странно - то все изображение выводится идеально, то с искажениями, в среднем соотношение 50/50.
Genadi Zawidowski
Цитата(ohmjke @ May 30 2012, 04:22) *
Да, делаю.
Просто что странно - то все изображение выводится идеально, то с искажениями, в среднем соотношение 50/50.

Вставьте задержку микросекунд на 10..20 на установление данных на сигналах перед выдачей стробов.
Да, не лтишне было бы выложить исходник проекта (или той функции, что зовётся lcd_write_data и lcd_send_cmd вместе с вызываемыми внутри их функциями.
ohmjke
Не уверен в расчетах, так как неизвестно сколько выполняется итерация цикла, но, по-моему, от таких задержек стало еще хуже.
Ниже исходники модуля(без задержек после вывода данных на шину).
CODE

#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;
};


CODE

#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++;    
    };
};
Genadi Zawidowski
То, что стало хуже - не наводит на размышления? В документе на контроллер нет слов про ограничения по минимальной скорости.
После установки стробов внесите задержки - и не такие циклы, как у Вас, которые выкидываются при оптимизации.

Код
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)
    {
    }
}
ohmjke
Пробовал по-всякому - ничего не помогает. Может ли это быть просто браком?
Экранировал зад платы, подключал контур к земле - безрезультатно.
Повторюсь, как я считаю, нужно обязательно учитывать тот факт, что искажение изображения происходит не постоянно, а, в среднем, в половине случаев.
Genadi Zawidowski
Цитата(ohmjke @ Sep 5 2012, 15:19) *
Пробовал по-всякому - ничего не помогает. Может ли это быть просто браком?

Покажите тестовый проект.
ohmjke
Сегодня наконец-то нашел косяк - видимо, один из разрядов порта оказался пробитым на землю, соответственно, он всегда выдавал на линию chip_enable ноль. Повесил на другой пин - теперь всё отлично! Я безмерно рад rolleyes.gif
Все манипуляции с задержками были проведены зря, ибо сейчас всё работает совсем без них.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.