Димон Безпарольный 2 19 июня, 2019 Опубликовано 19 июня, 2019 (изменено) · Жалоба Для LCD размером 160х128 при глубине цвета требуется 40КБ RAM. При этом буфер делаю unsigned short int размером 128х160. Можно взять глубину цвета 8 бит. Т.е. буфер будет unsigned char и потребуется 20кб. Это тоже работает. Но на малых контроллерах (L151) есть необходимость тоже запускать подобные LCD (других нет). При этом хотелось бы сделать буфер размером 4 бита и самому выбирать одно из 16 значений цветов. И 1 бит. И вот тут я на трансляции адресов закипел. Может кто подскажет литературу или пример где можно посмотреть как это делается? В SSD1309 делается так: if (color == WHITE) buffer[x+ (y/8)*SSD1306_LCDWIDTH] |= (1 << (y&7)); else buffer[x+ (y/8)*SSD1306_LCDWIDTH] &= ~(1 << (y&7)); Но здесь сложнее. Здесь приходится еще и разгребать буфер перед записью в LCD. Заранее спасибо. Изменено 19 июня, 2019 пользователем Димон Безпарольный Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 19 июня, 2019 Опубликовано 19 июня, 2019 · Жалоба В подобных ситуациях делаю иначе - при записи в видео-буфер данные преобразую на ходу (тексты, картинки), а уже другая задача периодически гонит эти готовые данные в LCD, это позволяет использовать DMA при нужде. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 49 19 июня, 2019 Опубликовано 19 июня, 2019 · Жалоба void write_buffer(x,y,color){ buffer[(x+y*WIDTH)/2] = buffer[(x+y*WIDTH)/2] & (0xF0 >> (4*(x&1))) | ((color & 0x0F) << (4*(x&1))); } int read_buffer(x,y){ return (buffer[(x+y*WIDTH)/2] >> (4*(x&1))) & 0x0F; } const uint16_t PALLETE[16] = {0xAABB, ...}; LCD_Write(x, y, PALLETE[read_buffer(x,y)]); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Димон Безпарольный 2 19 июня, 2019 Опубликовано 19 июня, 2019 (изменено) · Жалоба 3 hours ago, _pv said: void write_buffer(x,y,color){ buffer[(x+y*WIDTH)/2] = buffer[(x+y*WIDTH)/2] & (0xF0 >> (4*(x&1))) | ((color & 0x0F) << (4*(x&1))); } int read_buffer(x,y){ return (buffer[(x+y*WIDTH)/2] >> (4*(x&1))) & 0x0F; } const uint16_t PALLETE[16] = {0xAABB, ...}; LCD_Write(x, y, PALLETE[read_buffer(x,y)]); Круто. Спасибо. Вот что получилось: void drawPixel(unsigned char x, unsigned char y, unsigned char color) { // LCDBUF[(x+y*160)/2] = (LCDBUF[(x+y*160)/2] & (0xF0 >> (4*(x&1)))) | ((color & 0x0F) << (4*(x&1))); } // И отправляем в дисплей: void Display(void) //Функция передает содержимое буферов цветов в дисплей LCD { // setAddrWindow(0, 0, width, height);//Диаппазон, в котором действует автоинкремент Set_Pin_DC; // int h = width * height/2; //Число точек int ADR = 0; //Индекс массива while (h--) //Цикл передачи массивов цветов в дисплей { // unsigned char LCDByte; LCDByte = LCDBUF[ADR]; if(LCDByte & 0x0F) //Foreground { // unsigned int short color = Colors[LCDByte & 0x0F]; ST7735_write(color >> 8); //Старший байт цвета ST7735_write(color);//Младший байт цвет } // else //BackGround { // ST7735_write(0); //Старший байт цвета ST7735_write(0); //Младший байт цвета } // LCDByte = LCDByte >> 4; // if(LCDByte) //Foreground { // unsigned int short color = Colors[LCDByte]; ST7735_write(color >> 8); //Старший байт цвета ST7735_write(color);//Младший байт цвет } // else //BackGround { // ST7735_write(0); //Старший байт цвета ST7735_write(0); //Младший байт цвета } // ADR++; // } // for(int i=0; i < width * height/2; i++) { //Очистка видеобуфера LCDBUF[i] = 0; // } // } // Теперь проще. Попробую еще монохром сделать. Изменено 19 июня, 2019 пользователем Димон Безпарольный Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Димон Безпарольный 2 19 июня, 2019 Опубликовано 19 июня, 2019 · Жалоба Монохром получился. void drawPixel(unsigned char x, unsigned char y, unsigned char color) { // if (color) LCDBUF[(x+y*160)/8] |= (1 << (x & 7)); else LCDBUF[(x+y*160)/8] &= ~(1 << (x & 7)); } // Вывод в дисплей: void Display(void) //Функция передает содержимое буферов цветов в дисплей LCD { // setAddrWindow(0, 0, width, height);//Диаппазон, в котором действует автоинкремент Set_Pin_DC; // int h = width * height / 8; //Число точек int ADR = 0, i; //Индекс массива while (h--) //Цикл передачи массивов цветов в дисплей { // unsigned char LCDByte; // LCDByte = LCDBUF[ADR]; // for(i = 0; i < 8; i++) // { // if(LCDByte & (1 << i))//Foreground { // ST7735_write(Colors[PixelColor] >> 8); //Старший байт цвета ST7735_write(Colors[PixelColor]); //Младший байт цвет } // else //BackGround { // ST7735_write(0);//Старший байт цвета ST7735_write(0);//Младший байт цвета } // } // ADR++; // } // for(int i=0; i < width * height / 8; i++) { //Очистка видеобуфера LCDBUF[i] = 0; // } // } // Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Димон Безпарольный 2 19 июня, 2019 Опубликовано 19 июня, 2019 · Жалоба Два бита цвета тоже получилось, но коряво. void drawPixel(unsigned char x, unsigned char y, unsigned char color) { // if((x&3) == 0) { LCDBUF[(x+y*160)/4] = ((LCDBUF[(x+y*160)/4] & 0xfc) | (color & 0x03)); } if((x&3) == 1) { LCDBUF[(x+y*160)/4] = ((LCDBUF[(x+y*160)/4] & 0xf3) | ((color & 0x03) << 2)); } if((x&3) == 2) { LCDBUF[(x+y*160)/4] = ((LCDBUF[(x+y*160)/4] & 0xcf) | ((color & 0x03) << 4)); } if((x&3) == 3) { LCDBUF[(x+y*160)/4] = ((LCDBUF[(x+y*160)/4] & 0x3f) | ((color & 0x03) << 6)); } } // Передача в буфер еще хуже void Display(void) //Функция передает содержимое буферов цветов в дисплей LCD { // setAddrWindow(0, 0, width, height);//Диаппазон, в котором действует автоинкремент Set_Pin_DC; // int h = width * height/4; //Число точек int ADR = 0, i; //Индекс массива while (h--) //Цикл передачи массивов цветов в дисплей { // unsigned char LCDByte; LCDByte = LCDBUF[ADR]; if(LCDByte & 0x03) //Foreground { // unsigned int short color = Colors[LCDByte & 0x03]; ST7735_write(color >> 8); //Старший байт цвета ST7735_write(color);//Младший байт цвет } // else //BackGround { // ST7735_write(0); //Старший байт цвета ST7735_write(0); //Младший байт цвета } // LCDByte = LCDByte >> 2; // if(LCDByte & 0x03) //Foreground { // unsigned int short color = Colors[LCDByte & 0x03]; ST7735_write(color >> 8); //Старший байт цвета ST7735_write(color);//Младший байт цвет } // else //BackGround { // ST7735_write(0); //Старший байт цвета ST7735_write(0); //Младший байт цвета } // LCDByte = LCDByte >> 2; // if(LCDByte & 0x03) //Foreground { // unsigned int short color = Colors[LCDByte & 0x03]; ST7735_write(color >> 8); //Старший байт цвета ST7735_write(color);//Младший байт цвет } // else //BackGround { // ST7735_write(0); //Старший байт цвета ST7735_write(0); //Младший байт цвета } // LCDByte = LCDByte >> 2; // if(LCDByte) //Foreground { // unsigned int short color = Colors[LCDByte & 0x03]; ST7735_write(color >> 8); //Старший байт цвета ST7735_write(color);//Младший байт цвет } // else //BackGround { // ST7735_write(0); //Старший байт цвета ST7735_write(0); //Младший байт цвета } // ADR++; // } // for(int i=0; i < width * height/2; i++) { //Очистка видеобуфера LCDBUF[i] = 0; // } // } // Почему - то не получилось запихнуть в цикл. Так не работает: for(i = 0; i > 4; i++) { if(LCDByte & 0x03) //Foreground { // unsigned int short color = Colors[LCDByte & 0x03]; ST7735_write(color >> 8); //Старший байт цвета ST7735_write(color);//Младший байт цвет } // else //BackGround { // ST7735_write(0);//Старший байт цвета ST7735_write(0);//Младший байт цвета } // LCDByte = LCDByte >> 2; // } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 20 июня, 2019 Опубликовано 20 июня, 2019 · Жалоба Отступы - огонь! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 20 июня, 2019 Опубликовано 20 июня, 2019 · Жалоба 2 hours ago, scifi said: Отступы - огонь! Тут куда ни плюнь - все огонь Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 49 20 июня, 2019 Опубликовано 20 июня, 2019 · Жалоба а вот эти вот ручные разворачивания всевозможных вариантов они зачем? особенно отдельная проверка на 0. write_buffer(x, y, color, const N){ //N=0,1,2,3 => 1,2,4,8 bpp idx = (x + y * WIDTH); mask = (1 << (1 << N)) - 1; shift = (idx & ((1 << (3-N))-1)); buff[idx >> (3-N)] = buff[idx >> (3-N)] & (mask << shift) | ((color & mask) << shift); } read_buffer(x, y, const N){ idx = (x + y * WIDTH); mask = (1 << (1 << N)) - 1; shift = (idx & ((1 << (3-N))-1)); return (buff[idx >> (3-N)] >> shift) & mask; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Димон Безпарольный 2 20 июня, 2019 Опубликовано 20 июня, 2019 · Жалоба 4 hours ago, _pv said: а вот эти вот ручные разворачивания всевозможных вариантов они зачем? особенно отдельная проверка на 0. Еще круче. Но этот вариант не работает - часть пикселей другого цвета и сдвинуто по оси Х. void drawPixel(unsigned char x, unsigned char y, unsigned char color) { // #define N 2 //N = 0, 1, 2, 3 => 1, 2, 4, 8 bpp unsigned int idx = (x + y * width); unsigned char mask = (1 << (1 << N)) - 1; unsigned int shift = (idx & ((1 << (3-N))-1)); LCDBUF[idx >> (3-N)] = (LCDBUF[idx >> (3-N)] & (mask << shift)) | ((color & mask) << shift); } Для 4-х битового режима. Чтение буфера не менял. Только запись. Строка LCDBUF[(x+y*160)/2] = (LCDBUF[(x+y*160)/2] & (0xF0 >> (4*(x&1)))) | ((color & 0x0F) << (4*(x&1))); исправно работает. Понять в чем причина не смог пока. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться