Здравствуйте!
Это моё первое сообщение на данном форуме и прошу не бить, если что-то делаю не так.
Не так давно прикупил себе ЖКИ дисплей с модулем IIC на базе микросхемы PCF8574T.
Микросхема является байтовым (8-ми битный) расширителем портов управляемый по IIC шине и с возможностью задать собственный адрес путем подключения ножек к высокому или низкому уровню.
Первым делом я нашел схему данного модуля и уже по ней я начал писать драйвер.
По данной схеме написал не сложный драйвер для атмеги 8..
Код
#define F_CPU 8000000UL
#define SCL_CLOCK 100000L
#define time 100L
#include <avr/io.h>
#include <compat/twi.h>
#include <util/delay.h>
//Protutypes of TWI functions
void TWI_init ();
bool TWI_start (unsigned char address);
void TWI_start_wait (unsigned char address);
char TWI_rep_start (unsigned char address);
void TWI_stop ();
bool TWI_write (unsigned char data);
char TWI_readACK ();
char TWI_readNAK ();
//Prototupe of LCD functions
void LCD_send_command (uint8_t data);
void LCD_send_data (uint8_t data);
void LCD_init ();
int main(void){
PORTD = 0xFF;
DDRD = 0xFF;
TWI_init();
//Если не сможем подключиться к микросхеме, мигаем.
if (TWI_start(0x4E)){
while (true){
PORTD = 0x00;
_delay_ms(250);
PORTD = 0xFF;
_delay_ms(250);
}
}
//Если не может записать байт, мигаем быстро быстро.
if (TWI_write(0xFF)){
while (true){
PORTD = 0x00;
_delay_ms(10);
PORTD = 0xFF;
_delay_ms(10);
}
}
/*
LCD_init();
LCD_send_data('H');
LCD_send_data('e');
LCD_send_data('l');
LCD_send_data('l');
LCD_send_data('o');
LCD_send_data(' ');
LCD_send_data('W');
LCD_send_data('O');
LCD_send_data('R');
LCD_send_data('L');
LCD_send_data('D');
*/
while (true){
}
}
// TWI_atmega8
void TWI_init(){
TWSR = 0x00;
TWBR = ((F_CPU / SCL_CLOCK) - 16) / 2;
}
bool TWI_start (unsigned char address){
uint8_t twst;
TWCR |= (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
twst = (TW_STATUS & 0xF8);
if ((twst != TW_START) && (twst != TW_REP_START))
return 1;
TWDR = address;
TWCR |= (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
twst = (TW_STATUS & 0xF8);
if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)){
return true;
} else {
return false;
}
}
void TWI_start_wait(unsigned char address){
uint8_t twst;
while (true){
// send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
// send device address
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
// wail until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ((twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK)){
/* device busy, send stop condition to terminate write operation */
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
// wait until stop condition is executed and bus released
while(TWCR & (1<<TWSTO));
continue;
}
//if( twst != TW_MT_SLA_ACK) return 1;
break;
}
}
char TWI_rep_start(unsigned char address){
return TWI_start(address);
}
bool TWI_write (unsigned char data){
uint8_t twst;
TWDR = data;
TWCR |= (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
twst = TW_STATUS & 0xF8;
if (twst != TW_MT_DATA_ACK){
return 1;
} else {
return 0;
}
}
void TWI_stop (){
TWCR |= (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
while (TWCR & (1 << TWSTO));
}
Подключается успешно, байт отправляет успешно. Но когда мерю уровень напряжения на выводах (К сожалею тестера сейчас нет, мерю обычным светодиодом, один провод которого представляет из себя щуп, второй на земле) и напряжения просто нет.
Не могу понять саму причину.
1) Либо у меня нарушено тактирование микроконтроллера.
2) Либо сам ЖКИ + модуль убиты. На ЖКИ 1602 высвечивается вторая полоса заполненая кубиками.
3) Либо есть третья, неведомая мне, причина.