реклама на сайте
подробности

 
 
> Проблемы с TWI, при работе с ADT75
UniBomb
сообщение Mar 23 2009, 13:46
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 148
Регистрация: 26-05-05
Пользователь №: 5 416



Добрый день. Работаю с восьмой мегой и температурным датчиком ADT75. Написал собсвенные функции работы с TWI:

Код
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;
}


Соответсвенно для работы с температурной микросхемой использую вот такие функции:

Код
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;
}


Но почему то всё время функция ADT75_read(); очень часто возвращает 0. Т.е. симптомы такие - работает всё около часа, потом всё время возвращается 0. Если выключить и снова включить прибор, то может часа три поработать, потом опять нули.

Посмотрите пожалуйста свежим взглядом, а то я уже замылился...

зы: если надо - соответсвующие порты настроены как высокоомные входы, линия подтягиваеться резюками 6,8к (пробовал разные)... Так же на шине присутсвсует микросхема памяти 24CO4N (вроде как), так она работает правильно всё время...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
sensor_ua
сообщение Apr 3 2009, 04:52
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Цитата
совершенно непонятно как это делает мой код нерабочим
Вы меня не поняли. Я не берусь судить рабочий Ваш код или нет - я обращаю внимание на то, что отличия есть.
Ещё у Fleury в записи проверяется вроде бы (лень искать эту маску) нужные флаги вместе (главное, что "в один присест")
Код
    if( twst != TW_MT_DATA_ACK) return 1;
    return 0;

а у Вас в twi_write_address
Код
   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; //потеряли приоритет
     }
....

Проверка похожа, но, думаю, что не такая, ну и второе чтение регистра статуса - вроде бы у Fleury его нет. Аналогично с проверкой и вторым чтением регистра у Вас в twi_write_byte.
Не знаю, что правильно, но думаю, что такие отличия существенны


--------------------
aka Vit
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- UniBomb   Проблемы с TWI   Mar 23 2009, 13:46
- - UniBomb   ммм...... неужели нет мыслей? Путём отладки выясн...   Mar 26 2009, 08:31
- - UniBomb   Перепробовал все примеры использования, какие толь...   Mar 30 2009, 10:22
- - sensor_ua   Посмотри туда - http://homepage.hispeed.ch/peterfl...   Mar 30 2009, 11:24
- - ReAl   Цитата(UniBomb @ Mar 23 2009, 16:46) Добр...   Mar 30 2009, 11:36
- - UniBomb   sensor_ua, лучше бы ты меня идиотом назвал... Пров...   Mar 30 2009, 12:09
|- - ReAl   Цитата(UniBomb @ Mar 30 2009, 15:09) А на...   Mar 30 2009, 13:23
- - sensor_ua   Цитатавсе различия несущественны функция i2c_start...   Mar 30 2009, 22:04
- - UniBomb   sensor_ua, continue там стоит логично (по идее), н...   Apr 2 2009, 11:19
- - M_Andrey   Цитата(UniBomb @ Mar 23 2009, 17:46) ... ...   Apr 2 2009, 16:13
|- - UniBomb   M_Andrey, я надеюсь не на шину, а к питанию? ens...   Apr 3 2009, 07:12
- - sensor_ua   Цитатаясно))) Вы немного неправильно делаете извин...   Apr 3 2009, 08:15
- - UniBomb   Так, вопрос всё ещё актуальный... sensor_ua, прош...   Apr 6 2009, 08:05
- - UniBomb   вопрос - как связаны между собой модуль TWI и спящ...   Apr 6 2009, 12:56
- - sensor_ua   Выключается ли модуль TWI перед сном? Как GPIO нас...   Apr 7 2009, 20:06
- - UniBomb   Цитата(sensor_ua @ Apr 8 2009, 00:06) Вык...   Apr 8 2009, 07:12


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 23:24
Рейтинг@Mail.ru


Страница сгенерированна за 0.01397 секунд с 7
ELECTRONIX ©2004-2016