Всё больше убеждаюсь, что простых вещей в природе не существует. В любой простой вещи находятся скрытые сложности, достаточно лишь хорошо присмотреться. Что может быть проще, чем динамическая индикация?
В одном из устройств (лабораторный БП) реализована динамическая индикация, фрагмент схемы приведен на рисунке выше. Совершенно случайно заметил такую вещь: один из светодиодов (конкретно - светодиод FINE), который вовсе не имеет отношения к динамической индикации, иногда начинает чуть заметно светиться, когда программно он выключен. Немного покрутив на индикаторе менюшки, обнаружил, что светодиод чуть заметно загорается, когда в первом разряде индикатора все сегменты погашены. В других ситуациях он не горит. Первым делом под подозрение попала программа. Это аксиома - во всем всегда виноваты программисты. Вывод в регистры сдвига реализован через аппаратный SPI STM32. Начал проверять исходник - ну конечно, вот же она, ошибка!
void SpiWr(uint8_t d)
{
SPI1->DR = d;
while(!(SPI1->SR & SPI_SR_TXE));
}
void RgWr(uint32_t Value)
{
Pin_LOAD = 0;
SpiWr(BYTE1(Value));
SpiWr(BYTE2(Value));
SpiWr(BYTE3(Value));
Pin_LOAD = 1;
}
Данные защелкиваются в регистрах до того, как заканчивается передача по SPI, ведь флаг TXE говорит об опустошении буфера, но не о конце передачи. Добавил строчку:
...
while(SPI1->SR & SPI_SR_BSY);
Pin_LOAD = 1;
Теперь всё корректно. Но радость от найденной ошибки была недолгой. Глюк как был, так и остался. Светодиод продолжал чуть заметно светиться, когда его не просят. Оказалось, что задержка, связанная с временем цикла проверки флага, плюс с временем выхода из подпрограммы оказывалась достаточной, чтобы SPI успел закончить передачу байта. Однако если этот фрагмент переписать без использования подпрограмм, то без анализа флага BSY вывод мрачно глючит. Иногда так бывает - находишь и исправляешь причину глюка, а он не исчезает. Находишь и исправляешь еще одну причину - он по-прежнему не исчезает. И только с какого-то раза находится истинная причина.
Пришлось пойти на крайние меры - посмотреть осциллографом, что же там происходит в схеме. На выводе 12 микросхемы U6 были обнаружены короткие импульсы, которые и заставляли светодиод слабо светиться:
Эти импульсы следовали с периодом сканирования всех разрядов индикатора, т.е. примерно 4 мс. Импульсы пропадали, когда в первом разряде индикатора светился хотя бы один сегмент. Еще большее удивление вызвал тот факт, что при закороченном на землю входе 5 микросхемы U6 светодиод продолжал слабо светиться!
Предположение - емкостная связь между выходами 12 и 13 микросхемы U6. На выходе 13 непрерывно идут импульсы сканирования индикатора, а дорожки выводов 12 и 13 идут на плате параллельно где-то миллиметров 7. Светодиод современный, эффективный, для заметного свечения ток нужен мизерный. Раз подозрение на емкостную связь, емкостью нужно и бороться. Попробовал, но озадачило то, что светодиод гас только при подключении параллельно ему емкости порядка 10 нФ. Многовато, чтобы компенсировать паразитную емкость! Включение резистора параллельно светодиоду тоже ничего не дало - 1 кОм вызывал лишь небольшое уменьшение яркости засветки, причем во включенном режиме яркость при этом тоже падала. Да и странно всё это - на выводе 13 импульсы сканирования идут всегда, а светодиод подсвечивается лишь тогда, когда в первом разряде индикатора ничего нет.
Посмотрел форму сигнала на выводе 13 (SCAN4). При горящих сегментах во всех разрядах индикатора никаких неожиданностей нет. Когда линия сканирования активна, на ней около 0.7 В, что является нормальным падением для составных транзисторов внутри ULN2003. Когда линия сканирования выключена, напряжение на ней выше, порядка 1.3 В.
Но когда в первом разряде индикатора не горит ни один сегмент, увидел нечто странное. В то время, когда включается линия SCAN1, на линии SCAN4 вижу выброс, который уходит в отрицательные значения, примерно до -0.7 В. Как раз в этот момент на выводе управления светодиодом и возникает выброс (момент обозначен белой стрелкой). Земля и питание при этом чистые.
Оказалось, виноват именно отрицательный выброс. Если включить диод Шоттки с земли на выход 13, чтобы ограничить отрицательный выброс, подсветка светодиода полностью исчезает. Странно, что этот выброс влияет только на соседний вывод ULN, и непонятно, откуда этот выброс вообще берется.
Upd: козни ULN2003. Для появления паразитной засветки светодиода требуется не только отсутствие горящих сегментов в первом разряде, но и наличие горящих сегментов в четвертом разряде. Картина постепенно проясняется. Когда включается линия SCAN1, на анодах светодиодов индикатора происходит скачок напряжения вниз, так как выходы регистра U3 переключаются из высокого уровня в низкий. Этот скачок через емкость переходов светодиодов передается на выключенные выходы ULN, создавая там отрицательный выброс. А емкость, видно, не маленькая. Тем более, в выключенном состоянии переходы остаются прямосмещенными (хоть и ниже порога открывания), в таких условиях емкость максимальна.
Чтобы наблюдать эффект в чистом виде, можно провести простой опыт. Для этого взял ULN2003AN производства TI. Все входы подключил к GND. К одному из выходов через резистор 2.2 кОм подключил светодиод, на который подал +5 В. Светодиод не горит, как и положено. Теперь через резистор 10 кОм подключаю соседний выход к источнику -12 В. Светодиод загорелся! Если подключить не соседний выход, а какой-то другой, подальше, светодиод горит менее ярко.
Конечно, в реальных схемах никто не собирается подавать на выходы ULN отрицательное напряжение. Но эта микросхема часто используется для коммутации "злых" нагрузок, которые могут создавать выбросы, в том числе и отрицательной полярности. Светодиоды не являются экзотической нагрузкой, но будучи запитанными от регистра динамической индикации, тоже способны такие выбросы давать. В некоторых применениях даже кратковременное включение выхода ULN, который по задумке должен быть выключен, может привести к серьезным последствиям.
Что об этой проблеме говорит datasheet? Внутренняя схема ULN2003, кроме известных всем диодов с выходов на COM, имеет еще диоды с земли на входы и выходы. В данном случае открывается диод между землей и выходом, и это приводит к катастрофе. Мелкими-мелкими буквами в datasheet сказано:
"The collector-emitter diode is a parasitic structure and should not be used to conduct current. If the collector(s) go below ground an external Schottky diode should be added to clamp negative undershoots".
Если бы с этой проблемой не столкнулся на практике, то никогда бы не прочитал этой фразы - на такую простую, как грабли, микросхему изучать datasheet до буковки желания обычно не возникает. Да и на схемах диодов Шоттки на выходах ULN тоже никогда не встречал.
Еще это наглядная демонстрация разницы между набором ключей на дискретных транзисторах и массивом интегральных ключей. С дискретными транзисторами таких эффектов не возникло бы. А внутри интегральных схем кроме всего прочего существуют связи, которые дают о себе знать только в редких ситуациях.