Код
unsigned char twi_get_last_status(void)
{
return (TWSR & (1 << TWS7|1 << TWS6|1 << TWS5|1 << TWS4|1 << TWS3));
}
//---------------------------------------------------------------------------
unsigned char twi_Wait_TWINT(void)
{
register unsigned char i=0;
//ожидаем TWIN==1
do
{
if(TWCR & (1<<TWINT))
return 0x01; //true
}
while(--i);
return 0x00; //false
}
//---------------------------------------------------------------------------
void twi_init_asmaster(void)
{
TWBR = 0x20;
TWSR = (0 << TWPS1|0 << TWPS0);
TWCR |= (1 << TWEN|1 << TWEA);
twi_start();
twi_write_address(0xff, 'r');
twi_start();
twi_stop();
}
//---------------------------------------------------------------------------
unsigned char twi_start(void) //он же повстарт
{
TWCR = (1 << TWINT|1 << TWSTA|1 << TWEN);
unsigned char twi_last_status = twi_get_last_status();
if(twi_Wait_TWINT() == 0x01)
{
if((twi_last_status == 0x08) || (twi_last_status == 0x10))
return 0x01; //true
}
else
return 0x00; //false
return 0;
}
//---------------------------------------------------------------------------
unsigned char twi_stop(void)
{
TWCR = (1 << TWINT|1 << TWSTO|1 << TWEN);
register unsigned char i=0;
do
{
if(PINC & 0x10) //смотрим, установилась ли в "1" линия SDA
return 0x01; //true
}
while(--i);
TWCR = (1 << TWINT|1 << TWSTO);
return 0x00; //false
}
//---------------------------------------------------------------------------
unsigned char twi_write_byte(unsigned char data_byte)
{
TWDR = data_byte;
TWCR = (1 << TWINT|1 << TWEN);
if(twi_Wait_TWINT() == 0x01)
{
unsigned char twi_last_status = twi_get_last_status();
if((twi_last_status == 0x28) || (twi_last_status == 0x30))
return 0x01; //true
else if(twi_get_last_status() == 0x38)
return 0x00; //потеряли приоритет
}
else
return 0x00; //false
return 0;
}
//---------------------------------------------------------------------------
unsigned char twi_write_address(unsigned char address_byte, char read_write)
{
if(read_write == 'r')
address_byte |= 0x01;
else if(read_write == 'w')
address_byte &= 0xFE;
else
return 0x00;
TWDR = address_byte;
TWCR = (1 << TWINT|1 << TWEN);
if(twi_Wait_TWINT() == 0x01)
{
unsigned char twi_last_status = twi_get_last_status();
if(read_write == 'w')
{
if((twi_last_status == 0x18) || (twi_last_status == 0x20))
return 0x01; //true
else if(twi_get_last_status() == 0x38)
return 0x00; //потеряли приоритет
}
else if(read_write == 'r')
{
if((twi_last_status == 0x40) || (twi_last_status == 0x48))
{
TWCR = (1 << TWINT|1 << TWEA|1 << TWEN);
return 0x01; //true
}
else if(twi_get_last_status() == 0x38)
return 0x00; //потеряли приоритет
}
}
else
return 0x00; //false
return 0;
}
//---------------------------------------------------------------------------
unsigned char twi_read_byte(unsigned char *data, unsigned char ack_nack) //ack_nack == 1 - подтверждение
{ //ack_nack == 0 - неподтверждение
if(twi_Wait_TWINT() == 0x01)
{
unsigned char twi_last_status = twi_get_last_status();
if((twi_last_status == 0x50) || (twi_last_status == 0x58))
{
*data = TWDR;
if(ack_nack == 1) TWCR = (1 << TWINT|1 << TWEA|1 << TWEN);
if(ack_nack == 0) TWCR = (1 << TWINT|1 << TWEN);
return 0x01; //true
}
}
else
return 0x00;
return 0;
}
{
return (TWSR & (1 << TWS7|1 << TWS6|1 << TWS5|1 << TWS4|1 << TWS3));
}
//---------------------------------------------------------------------------
unsigned char twi_Wait_TWINT(void)
{
register unsigned char i=0;
//ожидаем TWIN==1
do
{
if(TWCR & (1<<TWINT))
return 0x01; //true
}
while(--i);
return 0x00; //false
}
//---------------------------------------------------------------------------
void twi_init_asmaster(void)
{
TWBR = 0x20;
TWSR = (0 << TWPS1|0 << TWPS0);
TWCR |= (1 << TWEN|1 << TWEA);
twi_start();
twi_write_address(0xff, 'r');
twi_start();
twi_stop();
}
//---------------------------------------------------------------------------
unsigned char twi_start(void) //он же повстарт
{
TWCR = (1 << TWINT|1 << TWSTA|1 << TWEN);
unsigned char twi_last_status = twi_get_last_status();
if(twi_Wait_TWINT() == 0x01)
{
if((twi_last_status == 0x08) || (twi_last_status == 0x10))
return 0x01; //true
}
else
return 0x00; //false
return 0;
}
//---------------------------------------------------------------------------
unsigned char twi_stop(void)
{
TWCR = (1 << TWINT|1 << TWSTO|1 << TWEN);
register unsigned char i=0;
do
{
if(PINC & 0x10) //смотрим, установилась ли в "1" линия SDA
return 0x01; //true
}
while(--i);
TWCR = (1 << TWINT|1 << TWSTO);
return 0x00; //false
}
//---------------------------------------------------------------------------
unsigned char twi_write_byte(unsigned char data_byte)
{
TWDR = data_byte;
TWCR = (1 << TWINT|1 << TWEN);
if(twi_Wait_TWINT() == 0x01)
{
unsigned char twi_last_status = twi_get_last_status();
if((twi_last_status == 0x28) || (twi_last_status == 0x30))
return 0x01; //true
else if(twi_get_last_status() == 0x38)
return 0x00; //потеряли приоритет
}
else
return 0x00; //false
return 0;
}
//---------------------------------------------------------------------------
unsigned char twi_write_address(unsigned char address_byte, char read_write)
{
if(read_write == 'r')
address_byte |= 0x01;
else if(read_write == 'w')
address_byte &= 0xFE;
else
return 0x00;
TWDR = address_byte;
TWCR = (1 << TWINT|1 << TWEN);
if(twi_Wait_TWINT() == 0x01)
{
unsigned char twi_last_status = twi_get_last_status();
if(read_write == 'w')
{
if((twi_last_status == 0x18) || (twi_last_status == 0x20))
return 0x01; //true
else if(twi_get_last_status() == 0x38)
return 0x00; //потеряли приоритет
}
else if(read_write == 'r')
{
if((twi_last_status == 0x40) || (twi_last_status == 0x48))
{
TWCR = (1 << TWINT|1 << TWEA|1 << TWEN);
return 0x01; //true
}
else if(twi_get_last_status() == 0x38)
return 0x00; //потеряли приоритет
}
}
else
return 0x00; //false
return 0;
}
//---------------------------------------------------------------------------
unsigned char twi_read_byte(unsigned char *data, unsigned char ack_nack) //ack_nack == 1 - подтверждение
{ //ack_nack == 0 - неподтверждение
if(twi_Wait_TWINT() == 0x01)
{
unsigned char twi_last_status = twi_get_last_status();
if((twi_last_status == 0x50) || (twi_last_status == 0x58))
{
*data = TWDR;
if(ack_nack == 1) TWCR = (1 << TWINT|1 << TWEA|1 << TWEN);
if(ack_nack == 0) TWCR = (1 << TWINT|1 << TWEN);
return 0x01; //true
}
}
else
return 0x00;
return 0;
}
Соответсвенно для работы с температурной микросхемой использую вот такие функции:
Код
void ADT75_init(void)
{
twi_start();
twi_write_address(0x90, 'w');
twi_write_byte(0x01);
twi_write_byte(0x20);
twi_stop();
}
//---------------------------------------------------------------------------
void ADT75_start(void)
{
twi_start();
twi_write_address(0x90, 'w');
twi_write_byte(0x04);
twi_stop();
}
//---------------------------------------------------------------------------
char ADT75_read(void)
{
unsigned char read_temp_h = 0;
unsigned char read_temp_l = 0;
twi_start();
twi_write_address(0x90,'w');
twi_write_byte(0x00);
twi_stop();
twi_start();
twi_write_address(0x90, 'r');
twi_read_byte(&read_temp_h, 1);
twi_read_byte(&read_temp_l, 0);
twi_stop();
return (char)read_temp_h;
}
{
twi_start();
twi_write_address(0x90, 'w');
twi_write_byte(0x01);
twi_write_byte(0x20);
twi_stop();
}
//---------------------------------------------------------------------------
void ADT75_start(void)
{
twi_start();
twi_write_address(0x90, 'w');
twi_write_byte(0x04);
twi_stop();
}
//---------------------------------------------------------------------------
char ADT75_read(void)
{
unsigned char read_temp_h = 0;
unsigned char read_temp_l = 0;
twi_start();
twi_write_address(0x90,'w');
twi_write_byte(0x00);
twi_stop();
twi_start();
twi_write_address(0x90, 'r');
twi_read_byte(&read_temp_h, 1);
twi_read_byte(&read_temp_l, 0);
twi_stop();
return (char)read_temp_h;
}
Но почему то всё время функция ADT75_read(); очень часто возвращает 0. Т.е. симптомы такие - работает всё около часа, потом всё время возвращается 0. Если выключить и снова включить прибор, то может часа три поработать, потом опять нули.
Посмотрите пожалуйста свежим взглядом, а то я уже замылился...
зы: если надо - соответсвующие порты настроены как высокоомные входы, линия подтягиваеться резюками 6,8к (пробовал разные)... Так же на шине присутсвсует микросхема памяти 24CO4N (вроде как), так она работает правильно всё время...