Например TDA7294

Форум РадиоКот • Просмотр темы - SSD1306 + AtMega8(88) = проблемы отображения
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Ср апр 24, 2024 09:31:16

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 4 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: SSD1306 + AtMega8(88) = проблемы отображения
СообщениеДобавлено: Ср фев 19, 2020 02:17:38 
Опытный кот

Карма: 16
Рейтинг сообщений: 74
Зарегистрирован: Вс янв 19, 2014 00:55:09
Сообщений: 736
Рейтинг сообщения: 0
Здоровья котам! :beer:
Друзья, помогите пожалуйста убить проблему. Несколько вечеров возюкаюсь безрезультатно. То ли уже не вижу ничего, то ли она в принципе не решаема?
Изображение
На фото, слева - у-координаты символов кратны 8 и здесь все в порядке и с картинкой (вверху) и со строкой ("768"). А вот справа, у-координаты картинки = 4, текста = 35 и снизу вылезла непонятная "грязь".
Вывод посимвольный, буфер(512 байт), всякий раз чистится и заполняется побитово. Здесь псевдокод ответственный за проблему.
Спойлер
Код:
/*
 * temp_ssd1306.c
 *
 * Created: 18.02.2020 22:36:34
 *  Author: МОНСТЕР
 */
 
#define  BUFFER_LENGTH   SSD1306_WIDTH * SSD1306_HEIGHT >>4
#define  BUFFER_ROWS   BUFFER_LENGTH / SSD1306_WIDTH * 8

uint8_t dev_address;
uint8_t _oled_buffer[BUFFER_LENGTH]; /*512 bytes*/

/*
эта функция меняет состояние соответствующего бита
в распределенных элементах буфера, определяемого координатами х/у.
По идее, биты полученные от единого байта из draw_byte(), здесь могут распределиться по разным байтам буфера.
*/
void draw_pixel(int16_t x, int16_t y, uint16_t color, uint8_t width){
   //y %= BUFFER_ROWS;
   uint16_t  bi = width * (y / 8) + x;
   color?(_oled_buffer[bi] |= (1 << (y & 0x07))):(_oled_buffer[bi] &= ~(1 << (y & 0x07)));
}

/*
Состояние каждого бита аргумента byte поочередно отправляется для модификации буфера.
Остальные аргументы - сквозняком.
*/
void draw_byte(uint8_t byte, int16_t x, int16_t y, uint8_t width){
   uint8_t bit = 8;
   while(bit--){
      draw_pixel(x, y, byte & 0x80, width);
      byte <<= 1;
      y++;
   }
}

/*
В памяти дисплея задаем прямоугольную область для дальнейшей отрисовки.
Возвращается байтовый размер этой области.
*/
uint16_t set_area(int x, int y, uint8_t width, uint8_t height){
   uint8_t page_0 = y >> 3;                     //стартовая страница области
   uint8_t pages = height >> 3;                  //общее количество
   while((height + (y & 0x07)) > (pages << 3)) pages++;//страниц области
   i2c_cmd(0x21);                              //установка столбца
   i2c_cmd(x);                                 //Начальный столбец.
   i2c_cmd(x + width - 1);                        //Конечный столбец.
   i2c_cmd(0x22);                              //установка страницы
   i2c_cmd(page_0);                           //Начальная страница.
   i2c_cmd(page_0 + pages - 1);                  //Конечная страница.
   return (pages * width);                        //Байтовый размер области
}

/*
Вывод символа в заданные координаты экрана.
\   char c - код символа
\   int x, int y - пиксельные координаты лево-верхнего пиксела символа.
cfont - структура моноширинного шрифта. Здесь:
\   cfont.data - массив шрифта + служебные байты. Сам шрифт смещен на величину FONT_DATA_SHIFT от начала массива.
\   cfont.x_size, cfont.y_size - пиксельные размеры символа шрифта.
\   cfont.bytes - количество байт на символ в массиве шрифта.
\   cfont.interspace - межсимвольный промежуток в слове.

*/
void _print_char(char c, int x, int y){
   uint16_t size, sym_id;      //байт-размер области, смещение и счетчик байт символа в массиве шрифта.
   uint8_t pages, current_y;   //вертикальный размер символа в страницах дисплея, смещение по "у" для обрабатываемой страницы.
   size = set_area(x, y, cfont.x_size + cfont.interspace, cfont.y_size);
   memset(_oled_buffer, 0, size);
   current_y = y & 7;  pages = 1;
   while((current_y + cfont.y_size) > (pages << 3)) pages++;
   //декодирование символа c
   switch (c){
      case 0x2a: sym_id = FONT_DATA_SHIFT; break; // "*"
      default: sym_id = (c - 0x2c) * cfont.bytes + FONT_DATA_SHIFT; // "-./0123456789:"
   }
   //******************
   for (uint8_t dy = 0; dy < pages; dy++){
      for (uint8_t dx = 0; dx < cfont.x_size; dx++){
         draw_byte(pgm_read_byte(&cfont.data[sym_id++]), dx, current_y, cfont.x_size + cfont.interspace);
      }
      current_y += 8;
   }
   i2c_data_array(_oled_buffer, size);
}

/*   Вывод строки   */
void oled_print(char *st, int x, int y){
   while(*st != '\0'){
      _print_char(*st++, x, y);
      x += (cfont.x_size + cfont.interspace);
   }
}

/*
Вывод картинки.
Алгоритм во многом повторяет процедуру _print_char.
*/
void oled_drawImage(const uint8_t* image, int x, int y){
   cimage.data = image;
   cimage.width = pgm_read_byte(&cimage.data[OLED_IMG_WIDTH]);
   cimage.height = pgm_read_byte(&cimage.data[OLED_IMG_HEIGHT]);
   cimage.bytes = pgm_read_byte(&cimage.data[OLED_IMG_BYTES]);
   uint16_t size = set_area(x, y, cimage.width, cimage.height);
   uint16_t shift = OLED_IMG_SHIFT;
   uint8_t sy = y & 7, pages = 1;
   memset(_oled_buffer, 0, size);
   //memset(_oled_buffer, 0, BUFFER_LENGTH);
   while((sy + cimage.height) > (pages << 3)) pages++;
   for (uint8_t dy = 0; dy < pages; dy++){
      for (uint8_t dx = 0; dx < cimage.width; dx++){
         draw_byte(pgm_read_byte(&cimage.data[shift++]), dx, sy, cimage.width);
      }
      sy += 8;
   }
   i2c_data_array(_oled_buffer, size);
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: SSD1306 + AtMega8(88) = проблемы отображения
СообщениеДобавлено: Ср фев 19, 2020 10:31:07 
Мудрый кот

Карма: 10
Рейтинг сообщений: 272
Зарегистрирован: Пт мар 26, 2010 17:16:52
Сообщений: 1769
Откуда: Kazan
Рейтинг сообщения: 0
Может у вас SH1106?
Присылают под видом SSD1306/
Вот пишут
Цитата:
Контроллер оказался проще, чем ssd1306. В частности, он не поддерживает режимы горизонтальной и вертикальной адресации, а умеет только страничную адресацию. Возможности по ремапу строк столбцов тоже ограничены. Поэтому попытка запуска экранчика с кодом от 1306 привела к закономерной неудаче.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: SSD1306 + AtMega8(88) = проблемы отображения
СообщениеДобавлено: Ср фев 19, 2020 14:31:15 
Опытный кот

Карма: 16
Рейтинг сообщений: 74
Зарегистрирован: Вс янв 19, 2014 00:55:09
Сообщений: 736
Рейтинг сообщения: 0
pcb432, Здесь горизонтальная адресация и она работает вроде... Картинка 16х16, а шрифт 10х14 бит. Т.е. занимают 2, а когда и 3 страницы (это если координата у не кратна 8). Так вот 2 страницы рисуются идеально,
при любых координатах, а на 3 почему-то мусор.


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: SSD1306 + AtMega8(88) = проблемы отображения
СообщениеДобавлено: Чт фев 20, 2020 17:48:54 
Опытный кот

Карма: 16
Рейтинг сообщений: 74
Зарегистрирован: Вс янв 19, 2014 00:55:09
Сообщений: 736
Рейтинг сообщения: 0
Решил задачу. Видимо передоз программирования был. :)
В процедурах _print_char(...) и oled_drawImage(...) битовое смещение, в циклах подсчета страниц, было лишним. Правильно работающие строчки таковы:
Код:
void _print_char(char c, int x, int y){
   ...
   while(cfont.y_size > (pages << 3)) pages++;
  ...
}

void oled_drawImage(const uint8_t* image, int x, int y){
   ...
   while(cimage.height > (pages << 3)) pages++;
   ...
}


Вернуться наверх
 
Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.

Подробнее>>
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 4 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 19


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y