SSD1306 по I2C

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить
Родился
Аватара пользователя
Сообщения: 15
Зарегистрирован: Чт ноя 16, 2017 17:04:14
Откуда: Сургут

Сообщение Angry Engineer »

День добрый, пытаюсь завести сабж, пока безуспешно (ну точнее включается/инициализируется, но чистятся только первые 8 линий), ткните носом по возможности куда копать.

камень ATmega328p использую аппаратный TWI (подтяжка к питанию 10 КОм), внешний кварц на 16 Mhz
среда Atmel Studio 7

к методам работы с TWI вроди притензий нет (часы читаются и устанавливаются)

Код: Выделить всё

#define F_CPU           16000000UL				//задаем частоту МК
#define F_SCL           100000L					//задаем частоту I2C
#define LCD_module	0x78

//БИБЛИОТЕКИ
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

//===I2C====
void I2C_Init()
{
	TWSR = 0;
	TWBR = ((F_CPU/F_SCL)-16)/2;
	TWCR =(1<<TWIE)|(1<<TWEN);
}
void I2C_Start()
{
	_delay_us(5);
	TWCR =(1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
	while(!(TWCR &(1<<TWINT)))
	{
	}
}
void I2C_Stop()
{
	TWCR =(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}
void I2C_Send_Device_Address(uint8_t dev_address, bool write)
{
	if (write == true)
	{
		TWDR = dev_address;
	}
	else
	{
		TWDR = dev_address|1;
	}
	TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
	while(!(TWCR &(1<<TWINT)))
	{
	}
}
void I2C_Send_Register_Address(uint8_t reg_address)
{
	TWDR = reg_address;
	TWCR =(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
	while(!(TWCR &(1<<TWINT)))
	{
	}
}
void I2C_Send_Data_ACK(uint8_t data)
{
	TWDR = data;
	TWCR =(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
	while(!(TWCR &(1<<TWINT)))
	{
	}
}
void I2C_Send_Data_NACK(uint8_t data)
{
	TWDR = data;
	TWCR =(1<<TWINT)|(1<<TWEN)|(0<<TWEA);
	while(!(TWCR &(1<<TWINT)))
	{
	}
}
uint8_t I2C_Read_Data_ACK()
{
	uint8_t Result = 0;
	TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
	while(!(TWCR &(1<<TWINT)))
	{
	}
	Result = TWDR;
	return Result;
}
uint8_t I2C_Read_Data_NACK()
{
	uint8_t Result = 0;
	TWCR =(1<<TWINT)|(1<<TWEN)|(0<<TWEA);
	while(!(TWCR &(1<<TWINT)))
	{
	}
	Result = TWDR;
	return Result;
}

//===LCD===
#define		Data_array	0b01000000		//Передача нескольких байт данных
#define		Data		        0b11000000		//Передача одного байта данных
#define		Command		0b10000000		//Передача байта комманды

const uint8_t Init_Sequence[18] PROGMEM =
{
	0xA8,0x3F,0xD3,0x00,0x40,0xA1,0xC8,0xDA,0x12,
	0x81,0x7F,0xA4,0xA6,0xD5,0x80,0x8D,0x14,0xAF
};

void LCD_Clear_Display()
{
	I2C_Start();
	I2C_Send_Device_Address(LCD_module, true);
	
	I2C_Send_Data_ACK(Command);
	I2C_Send_Data_ACK(0x20);
	I2C_Send_Data_ACK(Command);
	I2C_Send_Data_ACK(0x00);
	
	I2C_Send_Data_ACK(Data_array);
	for (uint8_t page= 0; page<8; page++)
	{
		for (uint8_t column=0; column<128; column++)
		{
			I2C_Send_Data_ACK(0x00);
		}
	}
	I2C_Stop();
}
void LCD_init()
{
	I2C_Start();
	I2C_Send_Device_Address(LCD_module, true);
	for (uint8_t i=0; i<18; i++)
	{
		uint8_t command = pgm_read_byte(&(Init_Sequence[i]));
		I2C_Send_Data_ACK(Command);
		I2C_Send_Data_ACK(command);
	}

	I2C_Stop();
}

int main()
{
	IO_Init();
	I2C_Init();
	
	sei();

	_delay_ms(500);
	LCD_init();
	_delay_ms(500);
	LCD_Clear_Display();

	while (true)
	{
		PORTC = PORTC | (1<<PORTC2);

				
		PORTC = PORTC & ~(1<<PORTC2);
	}
}
Реклама
Электрический кот
Аватара пользователя
Сообщения: 1031
Зарегистрирован: Чт июн 20, 2013 00:00:58
Откуда: москва, м.Сходненская

Сообщение Mishany »

ручной выбор страниц для очистки, функция установки страницы все равно понадобится
Реклама
Родился
Аватара пользователя
Сообщения: 15
Зарегистрирован: Чт ноя 16, 2017 17:04:14
Откуда: Сургут

Сообщение Angry Engineer »

Тоесть перед очисткой использовать страничный режим адрессации, а потом опять горизонтальный?
Электрический кот
Аватара пользователя
Сообщения: 1031
Зарегистрирован: Чт июн 20, 2013 00:00:58
Откуда: москва, м.Сходненская

Сообщение Mishany »

функции использовать согласно настройкам адресации памяти
Реклама
Эиком - электронные компоненты и радиодетали
Родился
Аватара пользователя
Сообщения: 15
Зарегистрирован: Чт ноя 16, 2017 17:04:14
Откуда: Сургут

Сообщение Angry Engineer »

такц стоп, я инициализирую его в горизонтальный режим адрессации, но при очистке нужно в ручную щелкать страницы или я как то не правильно понял первое сообщение? или для очистки нужен постраничный режим?
Реклама
Ответить

Вернуться в «Периферия»