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

Проблема с OLED дисплеем 128*64 пикселя 0,96" на SSD1306


-=FISHER=-

Рекомендуемые сообщения

Всех приветствую!

 

Разбираюсь сейчас с OLED дисплеем 128*64 пикселя, подключен у меня он к отладочной плате с AtMega328p (НЕ ардуино :)).

Wyswietlacz-OLED-0-96-SSD1306-BLUE-Arduino-SPI-I2C.jpg.b4181720017e683960c1ff80f596bc15.jpg

Начал с малого - пытаюсь с помощью USART отследить общение по I2C путем чтения регистра TWSR, а точнее приём бита ACK. Однако дисплей на отрез отказывается мне его присылать :unknw:. После отправки команд, посылаю содержимое регистра TWSR в терминал на компьютер и сверяю результат с таблицей Table 21-3. Status Codes for Master Transmitter Mode. 

Чтобы не быть голословным, прикладываю исходный код: 

I2C(TWI).h

Скрытый текст

#include "I2C(TWI).h"

#define SCL_CLOCK 400000 //скорость шины I2C

void I2C_Init (void)
{
	TWBR = ((F_CPU/SCL_CLOCK)-16)/2; //установка скорости I2C в 400 кГц
}

void I2C_StartCondition(void)
{
	TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
	while (!(TWCR & (1<<TWINT)));//подождем пока установится TWIN
}

void I2C_StopCondition(void)
{
	TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}

void I2C_SendByte(unsigned char c)
{
	TWDR = c; //запишем байт в регистр данных
	TWCR = (1<<TWINT)|(1<<TWEN); //включим передачу байта
	while (!(TWCR & (1<<TWINT))); //подождем пока установится TWIN
}

void I2C_SendByteByADDR(unsigned char c,unsigned char addr)
{
	I2C_StartCondition(); // Отправим условие START
	I2C_SendByte(addr); // Отправим в шину адрес устройства + бит чтения-записи
	I2C_SendByte(c); // Отправим байт данных
	I2C_StopCondition(); // Отправим условие STOP
}

unsigned char I2C_ReadByte(void)
{
	TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
	while (!(TWCR & (1<<TWINT)));//ожидание установки бита TWIN
	return TWDR;//читаем регистр данных
}

unsigned char I2C_ReadLastByte(void)
{
	TWCR = (1<<TWINT)|(1<<TWEN);
	while (!(TWCR & (1<<TWINT)));//ожидание установки бита TWIN
	return TWDR;//читаем регистр данных
}

 

main.c

Скрытый текст

#include "main.h"

#define		ADDRESS		0x3C //адрес устройства
#define		DATS		0x40 //все следующие байти данные
#define		DAT			0xC0 //следующий байт данные
#define		COM			0x80 //передаем команду

uint8_t scr_buffer[0]; // Буфер дисплея

// Массив команд инициализации
const uint8_t init[25] =
{
	0xAE, // Выключить дисплей
	0xD5, // Настройка частоты обновления дисплея
	0x80,
	///+----- делитель 0-F/ 0 - деление на 1
	//+------ частота генератора. по умочанию 0x80
	0xA8, // Установить multiplex ratio
	0x3F, // 1/64 duty (значение по умолчанию), 0x1F - 128x32, 0x3F - 128x64
	0xD3, // Смещение дисплея (offset)
	0x00, // Нет смещения
	0x40, // Начала строки начала разверки 0x40 с начала RAM
	0x8D, // Управление внутреним преобразователем
	0x14, // 0x10 - отключить (VCC подается извне) 0x14 - запустить внутрений DC/DC
	0x20, // Режим автоматической адресации
	0x00, // 0-по горизонтали с переходом на новую страницу (строку)
	// 1 - по вертикали с переходом на новую строку
	// 2 - только по выбранной странице без перехода
	0xA1, // Режим разверки по странице (по X)
	// A1 - нормальный режим (слева/направо) A0 - обратный (справа/налево)
	0xC8, // Режим сканирования озу дисплея
	// для изменения системы координат
	// С0 - снизу/верх (начало нижний левый угол)
	// С8 - сверху/вниз (начало верний левый угол)
	0xDA, // Аппаратная конфигурация COM
	0x12, // 0x02 - 128x32, 0x12 - 128x64
	0x81, // Установка яркости дисплея
	0x8F, // 0x8F..0xCF
	0xD9, // Настройка фаз DC/DC преоразователя
	0xF1, // 0x22 - VCC подается извне / 0xF1 для внутренего
	0xDB, // Установка уровня VcomH
	0x40, // Влияет на яркость дисплея 0x00..0x70
	0xA4, // Режим нормальный
	0xA6, // 0xA6 - нет инверсии, 0xA7 - инверсия дисплея
	0xAF  // Дисплей включен
};

void display_init (void)
{
	unsigned char k;

	I2C_StartCondition(); //отправка условие START
	USART_SendChar(TWSR); //читаем статусный регистр
	
	I2C_SendByte(ADDRESS); //отправляем адрес дисплея
	USART_SendChar(TWSR); //читаем статусный регистр

	for(k=0;k<24;k++) //перебираем команды из массива команд
	{
		I2C_SendByte(COM); //отправляем посылку, что следующая посылка будут данными
		USART_SendChar(TWSR); //читаем статусный регистр и отправляем в терминал
		
		I2C_SendByte(init[k]); //отправляем команду
		USART_SendChar(TWSR); //читаем статусный регистр и отправляем в терминал
	}

	I2C_StopCondition(); //отправка условие STOP
}

int main(void)
{
	I2C_Init(); //инициализация шины I2C
	USART_ini(103); //инициализация USART на скорости 9600 бод
	display_init(); //инициализация дисплея
    while (1) 
    {
		
    }
}

 

А так же прикладываю таблицу для сравнения из даташита на мегу.

Скрытый текст

1120892729_.JPG.bbabdd8e5d9a42342a77fe234eef406f.JPG

После выполнения кода, в терминале наблюдаю следующую картину (содержание регистра TWSR):

  • после отправки условия START - 0x08 (условие старт успешно передано)
  • после отправки адреса устройства - 0x20 (адрес передан, но бита подтверждения ACK принято не было)
  • после отправки всех последующих команд - 0x30 (данные переданы, но бита подтверждения ACK принято не было)

 

Скрытый текст

1659839193_.JPG.8531cb3c70e04d4a20d3f6d49ded15a1.JPG

Дисплей заведомо исправный (проверял на чужом коде), при подключении вместо него модуля часов реального времени на DS3231, бит ACK приходит (после адреса 0x18, после данных 0x28).

Подскажите пожалуйста, должен ли ACK вообще приходить от SSD1306?... Если да, то что я делаю неправильно?...

Изменено пользователем -=FISHER=-

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

1 минуту назад, Yurkin2015 сказал:

Адрес надо сдвинуть налево на 1

Помогло!!! :clapping:Только не понятно, почему с DS3231 заработало без сдвига? :huh:

Мы все учились по-немногу, чему-нибудь и как-нибудь...

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

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

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

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Потому что число 0xD0 - это уже сдвинутый адрес. А на самом деле адрес у DS3231 равен 0x68.

Изменено пользователем Yurkin2015
Ссылка на комментарий
Поделиться на другие сайты

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • собирай на 4558, будет работать 100%...  чуток более нелинейных искажений и чуток более шумов.. но на слух ты их скорее не определишь..
    • То, что вы называете "перекосом" (на одном плече 200 на другом 150) - это результат работы разделительной ёмкости С3. Она убрала постоянную составляющую, возникшую из-за лишнего импульса в нижнем плече. Начните с внимательной проверки каскада раскачки на Q3 Q4. Что на базы приходит, что на коллекторах получается, что на выходных обмотках. Надо найти причину возникновения этого лишнего импульса.
    • проверяйте на емкость и ЭПС. Все базовые цепи надо проверить. В любом случае, при замере напряжения к-э силовых ключей, разница будет видна при сухом конденсаторе
    • Если это нормальные оригинальные (или хотя бы просто нормальные) 4558 а не самая дикая китайская паль, то обычному человеку их боооолее чем хватит.  Вот такая схема, можете спокойно по ней собирать. Питание тут однополярное, 4558 прекрасно в ней работать будет. C3 только увеличить до 1-10 мкФ (микрофарад) и R2 убрать. PR1 регулирует усиление, от 1 до 100 раз. Если усилитель возбуждается (скорее всего так и будет), поставьте параллельно выводам резистора PR1 конденсатор на 47-100 пФ (пикофарад). У TL072 и 4558 в корпусах DIP8 и SOIC 8 распиновка одинаковая. 
    • Спасибо за помощь. Понял что эта схема не подходит но все таки хотелось бы именно на 4558.
    • С9 и С10 по 0,1 мкФ стоят, но не керамика, а плёнка. Думаете надо их заменить на керамику? И поставить непосредственно на выводы микросхемы?  По коррекции попробовать увеличить С6? Сейчас 5пф.
    • Возможно, подвозбуд в активном режиме. Стоит попробовать специальную NiZn ферритовую бусину на затвор. Нужно одеть бусину непосредственно на ножку, ближе к кристаллу. Eмкостная связь разрывается, условий для генерации емкостной трехточки уже не будет. Простое увеличение затворного сопротивления, как правило, в этом случае не эффективно. Марганец-цинковый феррит или амрфные/нанокристаллические сердечники тоже не очень хороши в этом месте.
×
×
  • Создать...