День добрый, пытаюсь завести сабж, пока безуспешно (ну точнее включается/инициализируется, но чистятся только первые 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);
}
}