ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
29 марта
1022389
=AK= (30.07.2020 14:50, просмотров: 51728)
Хочу то ли страшилку рассказать, то ли в жилетку поплакаться. Пока сам не знаю. 

И не знаю, относится ли тема к PIC-ам или к компонентам. Пока что проблема выглядит просто как полный бред.


Есть некое старинное устройство, даталоггер. Ему порядка 25 лет. Сделан на PIC16C770. Код написан на ассемблере разными людьми, документирован плохо. Этот логгер меряет температуру и влажность. Результаты измерений он показывает на LCD дисплее, а также записывает в I2C EEPROM с периодом, заданным в настройках.


Использовавшийся в логгере ранее сенсор Sensirion SHT15 снят с производства. Для замены выбран Sensirion SHT35. Он точнее, а его измерения проще обрабатывать: считанное с сенсора 16-битное число надо умножить на 1000 и поделить на 0xFFFF, получишь относительную влажность с шагом 0.1%. Лепота.


Я выбросил из проекта старый код для SHT15 и взамен написал новый код для SHT35. Единственно где схалтурил: вместо умножения на 1000 деления на 0xFFFF просто сдвигал считанный с результат на 6 разрядов вправо. Дешево и сердито. Правда, результат получается кривоватый, как если бы я измерение умножил на 1024 и поделил на 0x10000, но для проверки это сойдет.


И действительно, все работало как часы. Сделали для затравки 6 новых логгеров с таким кодом, положили их в тестовые установки с контролируемой влажностью. Считали результаты, сравнили с калиброванными приборами - все работает как часы, отлично. Единственно, что показания врут немного, чем больше влажность - тем больше. Это не диво, на полной шкале должны врать на 2.4%.


Напоследок вместо простого сдвига на 6 вправо запендюрил операцию 16х16 умножения на 1000=0x03E8. Отладил функцию умножения в симуляторе, заменил функцию сдвига вправо на 6 на умножение на 1000 (и деления на 0x10000 заодно, т.е. сдвиг, хрен с ним, с 0хFFFF, погрешность мизерная). И все, капец, теперь все сломалось и не работает.


Сломалось и не работает так, что у меня крыша едет. На мой взгляд, наблюдается полный бред. Симптомы такие.


1) Данные относительной влажности, считанные из лога (EEPROM) как бы "осциллируют" с двойной амплитудой порядка 0.8%. Иногда амплитуда больше раза в 3-4, но как правило - порядка 0.8%. То есть, на графике наблюдается некая "пила", залоггированные измерения поочередно: то больше - то меньше. Время записи в лог (т.е. в EEPROM) можно менять, это роли не играет: что раз в 2 секунды, что раз в минуту - все равно записывается "пила", каждое следующее измерение поочередно то больше, то меньше. Данные, которые выводятся на LCD каждые 4 секунды, скачут в соответствии с темпом записи в EEPROM, Например, если запись в EEPROM делается раз в 30 секунд, то в течении 30 секунд каждые 4 секунда LCD показывает вполне актуальную (на глазок) относительную влажность, затем прыгает примерно на 0.8% вверх или вниз, и следующие 30 секунд опять показывает вполне актуальную (на глазок), но другую, влажность,.


2) Если я в логгер ставлю МК с прошивкой, в которой результат просто сдвигается на 6 разрядов вправо - "осцилляции" исчезают. Результат выглядит отлично, только врет на 2.4% при большой влажности


3) Если с процедурами умножения на 1000 я прошиваю в логгер код, который после считывания данных из SHT35 заменяет их константами, то в лог прописываются постоянные значения, без осцилляций


4) Если я прошиваю в логгер и тот код, оторый просто сдвигает вправо на 6, и который умножает на 1000, то в любом случае, какую бы пост-обработку я ни выбрал (просто в goto подставляю тот или другой адрес) , данные в логе "осциллируют". Хотя, казалось бы, когда я выбираю "просто сдвинуть результат вправо на 6" отличется от п. 2) только тем, что в программной памяти сидит неиспользуемый код, который умеет умножать на 1000.


Отмечу, что все стандартные PIC16 заморочки:

а) связанные с PCLATH - каждый раз проверяются в листинге, их нет

b) связанные с банками RAM - тоже многократно проверены и отсутствуют

с) связанные с прерыванием - отсутствуют, поскольку все функции основного кода исполняются в промежутке между 1 сек прерываниями; кроме того, соответствеющие процедуры сохранения и восстановления контекста были добавлены, но никакого эффекта не возымели.


Из п.3) можно довольно уверенно сделать вывод, что данные "скачут" при считывании из сенсора. Но почему они скачут в пп.1).и 4), но не скачут в п.2) - моему уму непостижимо.