ПЗС линейка: с чем ее едят

6fss-0mg8davzerthbljhhg9ora.jpeg
В этой статье я хочу представить свой опыт по использованию линейного ПЗС-фотоприемника. Такая ПЗС-линейка может быть использована в проекте самодельного спектрометра, считывателя штрих-кодов, датчика положения или отклонения лазерного луча, сканера для фото- или кинопленки и много где еще. В моем случае это был лазерный сканер, описывать который в сети мне не позволяет сфера его применения.
Что такое прибор с зарядовой свзью

Чаще всего, когда говорят о ПЗС, имеют в виду различные фотоприемники. Реже — это устройства памяти: регистры сдвига, линии задержки. По своей сути это устройство, чем-то напоминающее память на цилиндрических магнитных доменах, только на кремнии — с помощью создаваемой системой электродов бегущей волны электрического поля по полупроводнику перемещаются сгустки носителей заряда, каким-либо образом образовавшиеся в нем ранее. Таким образом, мы получаем регистр сдвига, имеющий предельно простую структуру и способный запоминать не только последовательность цифровых единиц и нулей, но и аналоговый сигнал.

atdlgvfbnsok-t_geekshblchyo.gif


В ПЗС-приемниках изображения используется как раз вот эта способность данной структуры — последовательно выводить один за другим заряды, накопленные под каждым из пикселов структуры. Кроме того, та же система затворов, что используется для перемещения зарядов, во время экспонирования создает потенциальные ямы, в которых эти заряды накапливаются (либо эти ямы создаются в процессе формирования структуры — подобно встроенному и индуцированному каналам МОП-транзистора). Более сложные структуры включают в себя резистивный затвор, вдоль которого формируется плавный потенциальный склон (так устроены ПЗС-линейки Hamamatsu S11155)., а также разделение зон накопления и переноса зарядов — накопленные заряды всей строки сначала переносятся в буферную строку, а затем уже последовательно выдвигаются на выход вдоль последней.
Простота внутренней структуры выливается в сложность управления ею. Даже простейший вариант ПЗС-линейки требует генерировать двух-или трехфазный сигнал сложной формы с различными уровнями напряжения с крутыми фронтами (при высокой входной емкости, составляющей 1000 и более пФ), сдвинутыми друг относительно друга. Линейки типа Hamamatsu S11155 требуют аж восьми разных сигналов с различными уровнями напряжений высокого и низкого уровня по обе стороны нуля.
К счастью, некоторые фирмы (например, Sony) выпускали линейки, в которых вся эта сложность формируется прямо на кристалле. И для их работы нужно сформировать всего два сигнала: открывающий электронный затвор на время экспозиции, и тактовый. В нашей конструкции именно такая линейка ILX554: ее (как правило, б/у, но вполне работоспособную) несложно приобрести у китайцев на Aliexpress.

Заглянем в даташит

И видим, что из 22 выводов корпуса задействованы лишь 6. Это питание +5В, входные сигналы ROG и CLK, выходной сигнал Vout, вход выбора режима SHSW и земля. И это все.
ROG — это управление электронным затвором (и запуском переноса заряда с фоточувствительной строки на непосредственно сдвиговый регистр). У него активный уровень — нулевой. Чтобы проэкспонировать матрицу, его надо прижать к нулю и подержать, сколько надо — от 5 мкс до нескольких секунд. А потом, отпустив, подождать не меньше 3 мкс (за это время отрабатывает схема переноса заряда). Все это время на входе CLK мы держим высокий уровень. А затем можно считывать линейку, подавая на вход CLK меандр частотой от нескольких десятков килогерц до 2 МГц. При этом при каждом перепаде с единицы в ноль очередной пиксел будет выталкиваться на выход. Таких пикселов в линейке 2088 штук, из них рабочих, светочувствительных — 2048 (реально — на несколько штук больше, но крайние пикселы частично затенены). Даташит рекомендует подавать на матрицу не менее 2090 импульсов CLK для корректной работы.
А как он будет выталкиваться, зависит от того, что на входе SHSW. Если на нем — логическая единица, то на выходе будет получаться довольно замысловатый сигнал:

dzxqqbdg8vq_r_jgxg4gwek-6lg.gif


Причем при переходе CLK из нуля в единицу происходит сброс, а из единицы в ноль — выдача полезного сигнала.
А при нуле на входе SHSW включается встроенная схема выборки-хранения, которая упрощает этот сигнал до простого ступенчатого видеосигнала, где с каждым новым переходом CLK в ноль просто появляется уровень сигнала очередного пиксела и удерживается в течение всего периода сигнала CLK.
Полезный диапазон выходного сигнала идет от некоего темнового уровня, который по данным даташита составляет 2,85 В, а в реальности он может быть различным (в моей линейке — около 3 В), а при насыщении уровень выходного сигнала падает до 1,5–2 В.
В общем-то и все, что нам нужно про эту линейку знать.

Схема включения

thvoxsmrevwageaehbzgex4j054.png


Она проста и очевидна. Сигналы CLK и ROG мы генерируем программно с помощью МК, а триггеры Шмитта на входе — простейший способ перейти от 3,3 В к 5 В. Дело в том, что по этим входам в линейке нет никаких буферов, и для корректной работы внутренних схем матрицы нужно подать на них меандр с полным размахом от нуля до пяти вольт и хорошей крутизной фронтов. Указанные на схеме NC7SZ14M5X — очень удобные одиночные инвертирующие триггеры Шмитта с крутыми фронтами и повышенной нагрузочной способностью, и я их часто использую в своих проектах.
С помощью DA1 уровень видеосигнала с линейки «разгоняется» до диапазона, в котором работает АЦП, одновременно убирается «подставка» величиной примерно 1,5 В, соответствующая уровню насыщения. Так как у разных экземпляров ПЗС-линеек достаточно сильно разнятся размах сигнала и величина «подставки», сопротивления R1 и R3 следует подобрать, «уложив» выходной сигнал в необходимый диапазон. При этом нужно учесть, что от сопротивления R1 зависит не только смещение, но и усиление, поэтому сначала нужно подбирать его.
L1 и L2 — ферритовые бусины или маленькие дроссели на 1–2 мкГ типоразмера 0805 или 0603. Резисторы и конденсаторы применены того же типоразмера. Схема собрана на двусторонней плате поверхностным монтажом. Разводку платы не привожу, так как у меня на ней еще много чего.

Программная реализация на МК

Задачей МК является формирование сигнала ROG высокого уровня (не забываем про инверторы!) нужной длительности, затем — небольшой (3–10 мкс) паузы, а после нее — последовательности из 2090 импульсов высокого уровня, разделенных равными им по длительности паузами. Во время этих импульсов (или пауз) через некоторое время после фронта значение освещенности пиксела снимается с помощью набортного или внешнего АЦП. После считывания кадра нужно также сделать паузу до нового импульса ROG — те же 3–10 мкс. После включения питания и, как выяснилось, после долгого (больше 100 мс) неиспользования линейки ее нужно «прочистить», подав вхолостую стандартную серию импульсов на CLK пару-тройку раз.
На STM32 это все разумно сделать на прерывании от таймера. Настроив таймер на генерацию прерываний частотой, соответствующей удвоенной частоте пикселов, мы каждое срабатывание таймера попадаем в прерывание, где попеременно выводим в порт ноль или единицу, и когда выводим ноль, после этого считываем показания с АЦП. И отсчитав 2090 циклов, мы останавливаем таймер. Чтобы считать очередной кадр, нужно сбросить счетчик циклов в ноль, запустить таймер и ждать, пока не считается все.
Примерно вот так, как приведено в данных фрагментах кода.

bool clkState = false;
bool frameOk = true;
uint16_t pixCount = 0;
uint16_t ccdFrame[2090];


inline uint16_t readADC1(void)
// Тут у нас зависящая от конкретного МК реализация чтения из АЦП
{
     .
     .
     .
}

void Delay(unsigned int Val) 
// Функция для небольших задержек

{
    for( ; Val != 0; Val--)
        __NOP();
}

void readCCD(void)
// Запуск считывания ПЗС-линейки

{
    pixCount = 0;                      // Обнулили счетчик пикселов
    frameOk = false;                 // Сбросили флаг
    TIM_Cmd(TIM6, ENABLE);    // Запустили таймер 
    while(frameOk == false);     // Стоим, пока флаг не взведется
}


// ... всякий разный код ... //


void TIM6_IRQHandler(void)
/* 
Здесь мы оказываемся раз в сколько-то микросекунд и
формируем меандр CLK и в нужные моменты запускаем АЦП
*/

{
	if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
        {

		if(clkState == true)
                // Формируем паузу (лог.0) и здесь же запускаем АЦП
		{
		    clkState = false;
		    GPIOB->ODR &= ~GPIO_ODR_ODR_1; // выводим в порт логический ноль
		    Delay(3); // Небольшая пауза, пока не закончатся помехи и переходные процессы
		    ccdFrame[pixCount] = readADC1();
		}
		else
                // Формируем импульс (лог.1)
		{
		    pixCount++;
		    clkState = true;
		    GPIOB->ODR |= GPIO_ODR_ODR_1; // Выводим в порт логическую едииницу
		}
			
		if(pixCount >= 2090)
                // Дошли до конца линейки, выставили флаг и остановили таймер
		{
		    pixCount = 0;
                    frameOk = true;
		    TIM_Cmd(TIM6, DISABLE);
		}
                TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
        }
}

И вот результат
Результат неплохой. Несмотря на то, что встроенный АЦП не блещет характеристиками, его шумовые характеристики вполне соответствуют шуму ПЗС-линейки. Размах шумовой дорожки темнового сигнала при времени накопления около 1 мс оказывается равен ~ 3–4 уровням квантования и при использовании внешнего 14-разрядного АЦП с прекрасными характеристиками результаты получаются лишь немногим лучше. С ростом же освещенности шумы растут по простой причине: количество фотоэлектронов в каждом из пикселов не так велико (по моим расчетам — около 30 тысяч при насыщении). У лучших приборов эта величина достигает 200 тысяч.
На графике ниже — пример зарегистрированного линейкой «изображения», на котором на фоне освещенной стены стоит темный стенд, на котором закреплен стеклянный полый шарик диаметром 1 см, залитый внутри черным раствором. Пик — это отражение от внешней поверхности этого шарика. Шум на светлых участках — это структура самой стены, усиленная спеклами от лазера, от кадра к кадру он остается неподвижным. Реальный шум линейки значительно меньше.

image

Другие похожие линейки
Совершенно аналогично работают и некоторые другие 2048-пиксельные черно-белые ПЗС-линейки фирмы SONY — ILX511, ILX551 (у последней отличается цоколевка и ей требуется два напряжения питания — 5 и 9 В), отличающиеся поперечным размером пиксела (от 14 до 200 мкм) и спектральной чувствительностью (ILX554A красно- и ИК-чувствительная, аналогичная с индексом B имеет пониженную чувствительность в ИК области и приближена по чувствительности к глазу, а ILX511B более синечувствительная). Разные у них и динамические характеристики: у ILX551B динамический диапазон за счет малых размеров пиксела достигает 6000 (наша линейка достигает такого ДД при коротких выдержках около 10 мкс).

* * *
В данной статье рассмотрено подключение едва ли не самой простой в использовании ПЗС-линейки. Простота эта обусловлена тем, что вся сложность спрятана у нее под капотом. Если бы не встроенные драйвера, пришлось бы формировать множество разноуровневых сигналов.
К сожалению, по современным меркам, такие ПЗС-линейки со встроенными драйверами имеют не самые лучшие характеристики. Так, у данной линейки динамический диапазон, определенный, как соотношение сигнала насыщения к темновому сигналу, составляет 333:1, а определяемый, как отношение сигнала насыщения к минимальному обнаружимому на фоне шума сигналу — около 1000:1. Но такие приборы не только сложны в использовании, но часто и труднодоступны (та же Hamamatsu требует при покупке ее ПЗС-линеек и других фотоприемников сложных бюрократических формальностей в связи с двойным назначением этих изделий). Вместе с тем, далеко не всегда требуются столь высокие характеристики, и для многих целей

© Habrahabr.ru