индикация по таймеру

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Сообщения: 580
Зарегистрирован: Пт ноя 08, 2013 01:01:18

Сообщение melandr »

Добрый день, уважаемые коты. Помогите решить такую проблему. Есть устройство, измеряющее температуру четырьмя датчиками DS1820. Номер датчика и значение его температуры выводится на трехразрядный семисегментный индикатор на сдвиговых регистрах.
вот так организован вывод в основном цикле
Спойлерfor (unsigned char i = 0; i < ds18b20_devices; i++)
{
write_byte(pgm_read_byte(&SEGMENTE[10])); // Выводим "-"
write_byte(pgm_read_byte(&SEGMENTE[i + 1])); // Выводим номер датчика
write_byte(pgm_read_byte(&SEGMENTE[10])); // Выводим "-"

_delay_ms(1000);
if (error_crc)
{
if (znak == 0)
{
write_byte(pgm_read_byte(&SEGMENTE[temperature % 10])); // Выводим 3 разряд
write_byte((pgm_read_byte(&SEGMENTE[temperature % 100 / 10])) | 0x80); // Выводим 2 разряд
write_byte(pgm_read_byte(&SEGMENTE[temperature % 1000 / 100])); // Выводим 1 разряд
}
if (znak == 1)
{
write_byte(pgm_read_byte(&SEGMENTE[temperature % 10])); // Выводим 3 разряд
write_byte((pgm_read_byte(&SEGMENTE[temperature % 100 / 10])) | 0x80); // Выводим 2 разряд
write_byte(pgm_read_byte(&SEGMENTE[10])); // Выводим 1 разряд
}
}
else
{
write_byte(pgm_read_byte(&SEGMENTE[10])); // Выводим "-"
write_byte(pgm_read_byte(&SEGMENTE[10]));// Выводим "-"
write_byte(pgm_read_byte(&SEGMENTE[10])); // Выводим "-"
}
_delay_ms(2000);
}
}

Не нравится то, что в основном цикле происходит "затык": 1 секунда на вывод номера датчика и 2 секунды для вывода температуры. А так как датчиков 4, то имеем "затык" - 12 секунд. Как правильно организовать вывод показаний, чтобы основной цикл был максимально коротким, а показания выводились в фоне, с выдержкой соответствующих задержек. Есть таймер с прерыванием, тикающий каждую 1 мс.
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

Сообщение ptr128 »

Код: Выделить всё

#define DELAY_SCALE         1000
#define SENSOR_COUNT        3
#define SENSOR_NUMBER_DELAY 1
#define SENSOR_DATA_DELAY   3

static uint16_t volatile display_timer=0;  // Эта переменная должна инкрементироваться каждую 1 мс в Вашем прерывании

void loop ()
{
  static uint8_t display_status=0;  // Эту переменную используем для сохранения статуса

  for (uint8_t i=0;i<SENSOR_COUNT;i++)
  {
    if ( display_timer>=(uint16_t)i*SENSOR_DATA_DELAY*DELAY_SCALE && 
         display_timer<((uint16_t)i*SENSOR_DATA_DELAY+SENSOR_NUMBER_DELAY)*DELAY_SCALE &&
         display_status<i*SENSOR_DATA_DELAY+SENSOR_NUMBER_DELAY )
    {
       display_status=i*SENSOR_DATA_DELAY+SENSOR_NUMBER_DELAY;
       // Отображаем номер датчика как i+1
    }
    if ( display_timer>=((uint16_t)i*SENSOR_DATA_DELAY+SENSOR_NUMBER_DELAY)*DELAY_SCALE && 
         display_timer<(uint16_t)(i+1)*SENSOR_DATA_DELAY*DELAY_SCALE &&
         display_status<(i+1)*SENSOR_DATA_DELAY )
    {
       display_status=(i+1)*SENSOR_DATA_DELAY;
       // Отображаем показание датчика с номером i+1
    }
  }
  if (display_timer>=((uint16_t)SENSOR_COUNT*SENSOR_DATA_DELAY+SENSOR_NUMBER_DELAY)*DELAY_SCALE )
  {
     display_status=0;
     cli();
     display_timer=0;
     sei();
  }
}
Добавлено after 4 minutes 5 seconds:
Ой, для трех датчиков написал.
Ну значит SENSOR_COUNT надо установить в 4
Благо все равно вынес это в дефайны )
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Реклама
Вымогатель припоя
Сообщения: 580
Зарегистрирован: Пт ноя 08, 2013 01:01:18

Сообщение melandr »

Спасибо, вроде работает. Правда еще одна проблема похожая вылезла. Так как в ATtiny4313 АЦП нет, то используется аналоговый компаратор для измерения напряжения методом заряда емкости постоянным током.И вот на этом участке кода рвется все измерение напряжения
Спойлерif (ds18b20_devices > 0) //если датчики подключены производим опрос
{
DS18B20_StartMeasure(0); // запускаем измерение для всех датчиков
_delay_ms(750); // ждем минимум 750 мс, пока конвертируется температура
for (unsigned char i=0; i<ds18b20_devices; i++) // теперь сортируем устройства и запрашиваем данные
{
unsigned char data[2]; // переменная для хранения старшего и младшего байта данных
cli();
error_crc = DS18B20_ReadData(owDevicesIDs, data); // считываем данные
temperature = DS18B20_ConvertToThemperature(data,&znak); // преобразовываем температуру в человекопонятный вид
sei();
}
}
Сейчас попробую проверить, где именно происходит глюк, отпишусь
Этот код весь рвет мне работу с аналоговым компаратором. Нужно попробовать по Вашему принципу добавить счетчик для задержки в 750 мсек для конвертирования температуры. Чтобы не ждать в основном цикле.
ЗЫ:Блин работает Ваш алгоритм, нужно понять как работает, а то так сходу не разберешься
Ответить

Вернуться в «AVR»