Обсуждаем контроллеры компании Atmel.
Ответить

DS1621 определить конец преобразования Решено

Ср сен 21, 2022 12:39:30

Доброго всем добрым!
Суть проблемы. Девайс с термометром на DS1621. В процессе работы (при постоянном преобразовании), микра греется и начинает врать +4/+5 градусов. Да, знаю, что так не должно быть, но так есть. Сразу после включения, в холодном состоянии, показания корректны, затем начинает прогреваться в среднем на градус за минуту работы и так до описанной погрешности. Подозреваю, что погрешность будет нелинейна, а поскольку диапазон работы устройства будет от -5 до +40, нет желания строить таблицу поправок. Тем более, места в памяти уже не особо осталось, а переходить на больший камень из-за погрешности термометра как-то моветон.
Пытаюсь реализовать измерение один раз в минуту, мне этого достаточно. Т.е. запускаю преобразование, жду результата, читаю его, отключаю преобразование. И так раз в минуту. Но! Столкнулся с тем, что не могу отловить окончание преобразования :o По даташиту, этот момент знаменуется выставлением бита MSb в регистре статуса (адрес Ach). В общем конструкция вида:
Код:
uint8_t ds1621_get_status(void)
{
   temp = 0x00;
   i2c_start();
   i2c_send_byte(DS1621_ADR_W);
   i2c_send_byte(DS1621_ACCES_CONFIG);
   i2c_restart();
   i2c_send_byte(DS1621_ADR_R);
   temp = i2c_read_byte(NACK);
   i2c_stop();
   return temp;
}
   uint8_t getTemperatura(void)
{
        i2c_start();
   i2c_send_byte(DS1621_ADR_W);
   i2c_send_byte(DS1621_START_CONVERT);   
         
      [b]while[/b](ds1621_get_status() != 0x51) ds1621_get_status();            
             temp = 0x00;
   i2c_start();   
   i2c_send_byte(DS1621_ADR_W);
   i2c_send_byte(DS1621_READ_TEMPR);
   i2c_restart();
   i2c_send_byte(DS1621_ADR_R);
   temperatura = i2c_read_byte(NACK);
        i2c_restart();   
   i2c_send_byte(DS1621_ADR_W);
   i2c_send_byte(DS1621_STOP_CONVERT);
   i2c_stop();
        return temperatura;
         }

не работает :( Причем, что в Студии, что в Протеусе, не выполняется if else :shock: Вернее выполняется один раз, получает значение temp = 0x11, а при втором заходе просто пролетает сразу на строку i2c_start(). И temp не обнуляется :shock: temp, само-собой, определена volatile uint8_t temp = 0;
Последний раз редактировалось Land Ср сен 21, 2022 14:20:34, всего редактировалось 2 раз(а).

Re: DS1621 определить конец преобразования

Ср сен 21, 2022 13:02:32

преобразование у нее длится менее 1 секунды.
можно окончание не проверять вообще.
запустил преобразование, отмерил 1 сек., прочитал результат.
или так:
прочитал, запустил преобразование, а через минуту опять прочитал и запустил преобразование.

Re: DS1621 определить конец преобразования

Ср сен 21, 2022 13:10:18

Starichok51, да, я про этот костылик уже думал. Хотелось бы более красивое решение. Но, если не найду, придется так, увы (
блин, туплю. Надо же while использовать, а не if :idea:
Последний раз редактировалось Land Ср сен 21, 2022 13:40:32, всего редактировалось 1 раз.

Re: DS1621 определить конец преобразования

Ср сен 21, 2022 13:13:07

костыль - это караулить окончание преобразования.
я предложил простое и логичное решение.

Re: DS1621 определить конец преобразования

Ср сен 21, 2022 14:05:34

Starichok51, и именно потому, что это костыль, специально реализован флаг окончания конца преобразования. Логично )

Добавлено after 24 minutes 7 seconds:
veso74, да, спасибо. Я ступил, чего-то if использовал вместо while

Re: DS1621 определить конец преобразования

Ср сен 21, 2022 14:08:49

Не могу макс. понять логику написанного
Код:
if(ds1621_get_status() != 0x51)
  ds1621_get_status();           
else
  temp = 0x00;

но достаточно контролировать бит 7: DONE в configuration register
DONE = Conversion Done bit. "1" = Conversion complete, "0" = Conversion in progress.

или через маску 0x80 подойдет
Код:
uint8_t config_reg = 0;
while (!(config_reg & 0x80)) {
  config_reg = ds1621_get_status();
}
T = getTemperatura();

Re: DS1621 определить конец преобразования

Ср сен 21, 2022 14:19:22

вот в таком виде работает
Код:
uint8_t getTemperatura(void)
{
   i2c_start();
   i2c_send_byte(DS1621_ADR_W);
   i2c_send_byte(DS1621_START_CONVERT);
      while(!(temp & 0x80))
     {
        ds1621_get_status();
     }
          temp = 0x00;
   i2c_start();   
   i2c_send_byte(DS1621_ADR_W);
   i2c_send_byte(DS1621_READ_TEMPR);
   i2c_restart();
   i2c_send_byte(DS1621_ADR_R);
   temperatura = i2c_read_byte(NACK);
   i2c_restart();   
   i2c_send_byte(DS1621_ADR_W);
   i2c_send_byte(DS1621_STOP_CONVERT);
   i2c_stop();
   return temperatura;
}

Re: DS1621 определить конец преобразования

Ср сен 21, 2022 14:22:44

Land, ты куда-то опоздаешь, если прочитаешь результат через 1 секунду, а не через 0,9 сек.?

Re: DS1621 определить конец преобразования Решено

Ср сен 21, 2022 15:13:03

Да, для DS18 зимой приходилось увеличивать время подготовки / чтения, иначе было Т + 0,2..0,3 градуса (T = 5..10 градуса), думаю это от самонагрева. 2,5..3 и более секунд между двумя событиями практически отсранило добавка. В общем, изменение температуры (для обычных целей) - это медленный процесс во времени.

Лучше разбить два события (подготовки / чтения), чтобы могли управлять ими по отдельности, если это необходимо.
Ответить