Дисплей на ST7565 управляемый Arduino Due

5N62V
Offline
Зарегистрирован: 25.02.2016

Всем бобра! А так же с праздниками! :)

Короче, ХЕЛП!!!! :)

Есть у меня этот тудыть его в душу дисплей на контроллере ST7565 (а точнее на 2х таких контроллерах, т.к. дисплей 240х64), и ардуино Due. Соеденены по 8ми битному подключению 6800. Младший байт порта D - шина данных (правда я когда плату разводил умудрился старший бит на младший кинуть, и т.д., но это исправлено программно). Заставил дисплей работать на вывод информации. Но потом вычитал, что есть режим read/modify/wright - где МК сначала читает байт из графической памяти дисплея, потом можно его модифицировать, а потом вписать обратно, в ту же ячейку памяти. Это удобно когда объекты наползают один на другой - можно не заводить буфер в МК, а пользоваться памятью дисплея.  И вот я уже второй день бьюсь - не работает функция вычитывания, возвращает все время ноль, как я понимаю, т.к. объект который выводится вторым своими нулевыми пикселями затирает объект , который вывелся на дисплей ранее.

по идее работать должно так: в функцию вывода на дисплей "верхнего" объекта передаются координаты х,у,ширина и высота обекта, и указатель на сам битпам.  Фун-ция вывода:

void modify(uint8_t x, uint8_t y , uint8_t w, uint8_t h, const uint8_t * p) {
  uint16_t i = 0; bool right = false; bool cross = false; bool event = false;
  uint8_t data = 0;
  if (x > 119)right = true;
  else if ((x + w) > 119)cross = true;
  for (uint8_t page = 0; page < h / 8; page++) {
    writeCommand(0xB0 + y + page);//установка номера page (горизонтальная полоса в 8 пискселей)
    if (cross)event = false;
    writeCommand(0x10 + ((x - 120 * right) >> 4));//установка номера вертикального столбца
    writeCommand(0x00 + ((x - 120 * right) & 0x0F));//установка номера вертикального столбца
    writeCommand(0xE0);//установка режима read/modify/write
    for (uint8_t column = x; column < x + w; column++, i++) {//сбрасывается номер столбца при переходе границы
      if (column > 119) {
        if (cross && (!event)) {
          writeCommand(0xEE);
          writeCommand(0x10);
          writeCommand(0x00); 
          event = true;
          writeCommand(0xE0);
        }
        readData2();//первое вычитывание не считается, согласно мануалу
        data = readData2();//вычитывание байта из памяти 2го контроллера дисплея
        data |= pgm_read_byte_near((uint32_t)(p + i));//сложение с вычитанным байтом битмапа объекта
        writeData2(data);//запись байта во второй контроллер
      }
      else {
        readData1(); //первое вычитывание не считается, согласно мануалу
        data = readData1();//вычитывание байта из памяти 1го контроллера дисплея
        data |= pgm_read_byte_near((uint32_t)(p + i));//сложение с вычитанным байтом битмапа объекта
        writeData1(data);//запись байта в первый контроллер дисплея
      }
    }
    writeCommand(0xEE);//завершение режима read/modify/write
  }
}

и получается, собака, что readData1() и readData2() всегда возвращают нули. Собсно ф-ция чтения:

uint8_t readData1() {
  REG_PIOD_ODR |= 0xFF;//устанавливаем 0-8 биты на вход
  REG_PIOD_ODSR |= RW;//устанавливаем RW HIGH - #define RW (1<<9)//9bit port D
  REG_PIOA_ODSR &= ~ CS1;//устанавливаем CS1 LOW - CS1 #define (1<<5)//5bit port A
  delayMicroseconds(4);
  REG_PIOD_ODSR |= E;// устанавливаем E high - #define E (1<<8)//8bit port D
  delayMicroseconds(4);
  uint8_t data = (uint8_t)(REG_PIOD_PDSR & 0xFF);// читаем младший байт
  REG_PIOD_ODSR &= ~E;//  устанавливаем E low
  REG_PIOA_ODSR |= CS1;//устанавливаем CS1 HIGH
  REG_PIOD_ODSR &= ~RW;//устанавливаем RW LOW
  REG_PIOD_OER |= 0xFF;//устанавливаем 0-8 биты на выход
  uint8_t res = reverseBits(data);//инвертируем биты в байте
  return res;
}

фу-ция  reverseBits() тут ни при чем, она , когда идет вывод без вычитывания, работает правильно. 

Может кто чего увидит незамыленным глазом, или кто с подобным сталкивался? 

Глум без полезного смысла не приветствуется! ;)

5N62V
Offline
Зарегистрирован: 25.02.2016

Я так понимаю, задача слишком спицефическая? ;)