Rickard Gunee
" How to generate video signals in real-time using a PIC16F84 "
Перевод с английского.
Перевод выполнен с небольшими сокращениями.


Как с помощью PIC16F84 генерировать видео сигнал.

Краткое содержание.

О видео сигнале. Если Вы не знаете как выглядит видеосигнал, Вы не сможете получить его программным способом.
Создание видеосигнала программным способом. Как эффективно создать видеосигнал с помощью PIC, если Вы знаете как этот сигнал должен выглядить.
Наложение видео на существующий сигнал. Краткое описание того, как с помощью PIC программным способом наложить графику.
Цветной видеосигнал и почему PIC16F84 не может его создать. Краткое описание того, как программным способом генерируется цветной видеосигнал и почему в этом случае следует использовать SX-контроллер.


О видео сигнале.

Чтобы понять каким образом формируется видеосигнал в реальном времени, необходимо хорошо, в деталях, понимать каким образом получается видеоизображение. Поэтому прежде чем разбирать какой либо код поговорим сначала об этом.

Как работает стандартный телевизор.
В стандартном телевизоре используется вакуумная труба, которая имеет экран, покрытый слоем люминофора и электронную пушку, которая излучает электроны в направлении экрана. В момент удара электрона об экран и в течении некоторого времени после удара в месте удара люминофорный слой излучает свет. Траекторию электронного потока, излучаемого пушкой, можно изменить с помощью магнитного поля и тогда электроны будут ударяться в другую точку экрана. Используя такое управление можно рисовать горизонтальные линии по всему экрану. При изменении интенсивности электронного луча изменяется яркость свечения, таким образом можно получить на экране изображение. В системе PAL экран перерисовывается 25 раз в секунду. Чтобы уменьшить мерцание экрана при обновлении картинки, сначала рисуются все нечетные, а потом все четные линии. Поэтому картинка практически обновляется 50 раз в секунду. Для того чтобы получить цветное изображение, необходимо чтобы каждая точка экрана состояла из трех цветов: красного, зеленого и синего. Здесь мы будим рассматривать только черно-белое телевидение, так как только его можно получить в реальном времени с помощью PIC16F84.
.
Электронный луч рисует изображение. Две части изображения образуют одно сплошное.
Различные телевизионные стандарты.
Существуют три основных телевизионных стандарта: NTSC, SECAM и PAL. NTSC ( National Television System Committe ) – это американский стандарт. Он имеет 525 строк и частоту обновления кадров 30 Гц. SECAM ( Sequentil Color And Memory ) - французский стандарт и PAL ( Phase Alternating Lines ) имеют 625 строк в кадре при частоте кадров 25 Гц. Кроме различия кадровой и строчной частот эти стандарты отличаются способом кодирования цветного сигнала. Далее мы будим рассматривать стандарт PAL.

Информация в видеосигнале.
Точки разной яркости образуют на экране изображение. Когда электронный луч проходит по экрану, его интенсивность изменяется за счет изменения уровня видеосигнала. Но в этом сигнале нет информации о том, в какой части экрана находится в настоящее время луч. Для решения этой проблемы используется синхроимпульс, который передается в начале каждой строки. Синхроимпульс говорит телеприемнику, что текущая строка закончилась и необходимо перевести луч вниз, в начало следующей строки ( это похоже на нажатие кнопки 'Enter' на клавиатуре когда Вы набираете текст на компьютере ). Телеприемник должен также знать, когда начинается новый кадр. Об этом сообщает специальная комбинация синхроимпульсов ( как функция 'Новый документ' при написании текста с помощью компьютера ). При обновлении кадра 25 раз в секунду изображение будит заметно мерцать, поэтому сначала рисуются все нечетные, а потом все четные линии. За счет этого число кадров в секунду увеличивается до 50, и изображение становится более качественным. Информация о четности/нечетности строки передается в комбинации вертикальных синхроимпульсов. Амплитуда видеосигнала изменяется в пределах от 0 до 1В. Уровень 0,3В соответствует черному цвету, а 1В – белому ( яркость серого изменяется между этими значениями ). Уровень 0В соответствует синхроимпульсу.

Строка видеосигнала.
Изображение разделено на строки. Каждая строка имеет длительность 64 мкс. В первые 4 мкс передается строчный синхроимпульс. Это производится переводом уровня сигнала в 0 для того, чтобы сказать телеприемнику, что началась новая строка. Старые телевизоры были очень медленными, после получения синхроимпульса им требовалось 8 мкс для перевода электронного луча в начало следующей строки. В течении этого времени сигнал поддерживается на уровне черного. В оставшиеся 52 мкс передаются данные изображения. Изображение рисуется слева направо с яркостью, соответствующей уровню видеосигнала. Черный цвет соответствует уровню 0,3В, и с увеличением уровня видеосигнала увеличивается яркость. Максимум яркости достигается при уровне видеосигнала 1В ( белый цвет ). На рисунке показана осциллограмма строки видеосигнала.
Осциллограмма строки видеосигнала.
Объединение строк вместе в изображение.
Изображение состоит из 625 строк. Но телевизор не показывает все 625. Часть из них используется для синхронизации. Другая часть ( не знаю точно сколько ) не видна на экране так как старым телевизорам требовалось некоторое время для перевода электронного луча из нижнего правого угла растра в верхний левый. ( В настоящее время эти строки используются для других возможностей, например для телетекста ).
Осциллограмма нескольких строк видеосигнала.
Вертикальная синхронизация.
Для того чтобы сообщить телеприемнику, что начинается новый кадр, посылается специальный импульсный пакет. Так как изображение состоит из двух полукадров, пакеты отличаются в четном и нечетном полукадрах. Импульсы кадровой синхронизации выглядят как на рисунке.


Здесь показано, чем отличаются вертикальные синхроимпульсы в разных полукадрах. Уровень напряжения изменяется от 0 до 0,3 В. Цифры указывают номер строки.

DIGITA.ru: Телевизоры, DVD-плееры, видеомагнитофоны, видео-плееры. Аппаратура Hi-End класса.

Создание видеосигнала программным способом.

Итак, эта часть о том, как программным способом получить видеосигнал. Для того, чтобы понять как это делается, необходимо чтобы Вы хорошо усвоили ранее изложенный материал. Если Вы хорошо понимаете, что представляет собой видеосигнал, его легко будит получить программным путем имея процессор с неограниченными возможностями. Проблема в том, что требования к процессору достаточно высоки. Но даже если Вы не имеете мощного процессора кое-что все же можно сделать. Поговорим сначала о написании кода.
В моих примерах кода в этой части используются два следующих макроса:
DNOP –двойная команда NOP –макрос, который обеспечивает паузу в течении двух циклов.
dnop		MACRO
		LOCAL	label
label		goto	label+1
		ENDM 
DELAY – макрос паузы, длительность которой в три раза больше числа, записанного в регистр W.
Delay		MACRO
		LOCAL	label
		movwf	delaycnt
label		decfsz	delaycnt
		goto label
		ENDM 

Схемное решение.
Для генерации видеосигнала необходима некая схема, способная создавать сигналы с амплитудой напряжения от 0 до 1В. Чтобы создать изображение Вам необходимо как минимум три уровня сигнала. Телевизор должен получать уровень черного и уровень синхросигнала для того, чтобы синхронизировать изображение. Если Вы хотите большего, чем просто черный экран, Вам понадобится некоторый уровень серого или белого. Для получения трех необходимых уровней аналогового сигнала требуется два бита данных цифрового сигнала. Стандартное входное сопротивление видеовхода телевизора – 75 Ом. Используя два резистора и два выхода порта микроконтроллера можно создать требуемые уровни напряжения.
При соединении обоих выходов D0 и D1 с землей, напряжение на видеовходе
телевизора будит равно 0, что соответствует синхроуровню.

Выход D1 соединен с землей, а выход D0 - с +5В. В этом случае резистор 450 Ом включен параллельно 75 Ом-ному сопротивлению видеовхода телевизора, а резистор 900 Ом подключен к этой цепи последовательно. Этот делитель напряжения позволяет получить на видеовходе уровень 0,33В, что очень близко к уровню черного. (Истинный уровень черного 0,3В.)

Выход D0 соединен с землей, а выход D1 - с +5В. В этом случае резистор 900 Ом включен параллельно 75 Ом-ному сопротивлению видеовхода телевизора, а резистор 450 Ом подключен к этой цепи последовательно. Этот делитель напряжения позволяет получить на видеовходе уровень 0,67В. Это уровень серого.

Оба выхода D0 и D1 соединены с +5В. В этом случае резисторы 900 Ом и 450 Ом включены параллельно, а 75 Ом-ное сопротивление видеовхода телевизора, подключено к этой цепи последовательно. Этот делитель напряжения позволяет получить на видеовходе уровень 1В. Это уровень белого.

Эта схема позволяет получить четыре уровня напряжения. На рисунках представлены эквивалентные схемы четырех различных уровней напряжения и показано, каким образом они получаются. Номинал резисторов не критичен. Вы можете использовать большие, стандартные значения: 470 Ом и 1 кОм вместо 450 Ом и 900 Ом. Схема будит работать, просто немного изменится яркость изображения.
Итак, мы можем создать синхроуровень, уровни черного, серого и белого. Этого достаточно чтобы создать простое изображение, как в играх Pong и Tetris. Возможно создание и большего числа уровней яркости если использовать большее число бит выходного порта. Но в этом случае Вы не сможете с помощью них выполнять другие функции.

Программно и аппаратно генерируемый сигнал.
В стандартных видеосистемах, таких, как видеокарта в ПК, информация о том, что выводить на экран берется из видеопамяти. Это осуществляется автоматически на аппаратном уровне. Синхроимпульсы формируются так же автоматически железом. Все, что требуется от программы - это записывать в видеопамять то изображение, которое аппаратная часть должна вывести на экран. Это требует мощной аппаратной части и много памяти. Видеокарта в ПК имеет обычно несколько МБайт видеопамяти. У PIC16F84 есть 68 Байт памяти, и эта память должна хранить не только изображение, но и другую информацию, например переменные. Невозможно держать в памяти всю картинку, как это происходит в видеокарте. Видеоданные должны формироваться непосредственно в момент вывода изображения на экран. Создать изображение программным способом с помощью такого простого процессора достаточно трудно, это может быть только очень простое изображение. Зато этот способ очень дешев.

Строка, формирующая вертикальные полосы.
Первый тест, который я сделал, когда начал экспериментировать с программной генерацией видео – это получение вертикальных полос на экране. Надо создать строку, в которой информация о цвете изменяется в такой последовательности: серый – черный – белый – черный – серый. Повторяя эту строку непрерывно, получим на черном фоне экрана изображение трех полос: две серые по краям и одна белая по центру экрана. Сигнал включает горизонтальный синхроимпульс, последующую задержку и информацию о яркости. Телевизионное изображение будит устойчиво по горизонтали, а по вертикали может плавать или дрожать, так как вертикальные синхроимпульсы отсутствует. На рисунке показано как это примерно выглядит.
Осциллограмма сигнала, генерируемого кодом,
который приведен ниже. Низкие импульсы -
это серые полосы, высокий импульс в середине
- белая полоса.
Так выглядит видеосигнал на экране
телевизора. Две серых и одна белая полосы.
main: 
movlw COLOR_SYNC          ;get sync level (1) 
;**** 4us sync **** 
movwf VIDEO_PORT          ;set port value (1) 
movlw 3                   ;setup delay time (1) 
DELAY                     ;delay for 3us (9) 
movlw COLOR_BLACK         ;get black color (1)
 
;**** 8us delay **** ;
movwf VIDEO_PORT          ;set port value (1) 
movlw 7                   ;setup delay time (1) 
DELAY                     ;delay for 7us (21)
movlw COLOR_GRAY          ;get gray color (1) 

;*** 52us image data *** 
movwf VIDEO_PORT          ;set port value (1)
movlw 3                   ;setup delay time (1)
DELAY                     ;delay for 3us (9)
movlw COLOR_BLACK         ;get black color (1) 
movwf VIDEO_PORT          ;set port value (1) 
movlw 19                  ;setup delay time (1) 
DELAY                     ;delay for 19us (57) 
movlw COLOR_WHITE         ;get white color (1)
movwf VIDEO_PORT          ;set port value (1)
movlw 3                   ;setup delay time (1)
DELAY                     ;delay for 3us (9)
movlw COLOR_BLACK         ;get black color (1)
movwf VIDEO_PORT          ;set port value (1) 
movlw 19                  ;setup delay time (1)
DELAY                     ;delay for 19us (57)
movlw COLOR_GRAY          ;get gray color (1)
movwf VIDEO_PORT          ;set port value (1)
movlw 2                   ;setup delay time (1)
DELAY                     ;delay for 2us (6)
DNOP                      ;delay for two clocks 
goto main                 ;once again (2)
Этот код позволяет генерировать на черном фоне две серых и одну белую полосы. ( Внимание! Этот код написан мной по памяти и не тестировался, поэтому нет гарантии что он рабочий. )
Как Вы, наверное, заметили, этот фрагмент программы выполняется за 192 машинных цикла и создает строку длительностью 64 мкс. Это время имеет очень большое значение.

Проблема с низким разрешением.
PIC16F84 при частоте 12 МГц выполняет 3 миллиона инструкций в секунду ( для выполнения одной инструкции ( команды ) необходимо 4 такта генератора ). За 64 мкс ( длительность строки ) выполняется 192 инструкции, а в течении 52 мкс ( видимая часть строки ) – только 156 инструкций. Если в эти 52 мкс значение выходного порта будит изменяться каждой инструкцией, Вы получите разрешение 156 пикселей по оси X. Это очень мало. К тому же даже все эти 156 пикселей не могут использованы та как Вы хотите. Если значение пикселя должно меняться с каждым новым циклом, Вы не сможете за один цикл просчитать значение пикселя и вывести его на экран.

Достижение высокого разрешения с помощью команды сдвига.
Если вы хотите показать 8 пикселей черного и белого, сохраненных в одном байте памяти, то это можно сделать так:

movlw 8            ;number of pixels is 8 (1) 
movwf counter      ;set counter to number of pixels (1) 
shiftloop: 
movlw COLOR_BLACK  ;set default color to black (1) 
rrf thedata,f      ;rotate data right, make put bit in carry (1)
skpnc              ;check if carry, if not pixel remains black (1 or 2)
movlw COLOR_WITE   ;carry was set, set color to white (1)
movwf VIDEO_PORT   ;set color to DA (1) 
decfsz counter     ;decrease counter, check for zero (1 or 2) 
goto shiftloop     ;if more pixels, keep looping (2)
Этот код выводит биты одного байта в видеопорт. Таким образом на экран можно вывести различые изображения.
В этом примере для вывода одного бита требуется 8 машинных циклов. При этом разрешение составляет только 19 пикселей, то есть практически применять этот способ бессмысленно. Однако есть хорошее решение этой проблемы. Можно использовать один порт как сдвиговый регистр, сдвигающий на выход по одному биту в каждом цикле. Но за все надо платить. Вы должны принести в жертву возможность использовать порт для других целей. К тому же этот вариант работает только в черно-белом режиме ( серого цвета нет ). Это может выглядеть так:
Соедините резистор 450 Ом с битом 0 PORTB, а резистор 900 Ом с одним из битов PORTA. Для использования PORTB как дополнительного все его биты должны быть настроены как выходы. Бит PORTA устанавливается в 1, в PORTB записывается байт и сдвигается на выход. Генерируемые черно-белые уровни соответствуют байту, например как здесь:

movfw thedata     ;set up the byte to be shifted out
movwf PORTB,f     ;now the first bit becomes visible (1 clock)
rrf PORTB,f       ;second bit is shifted out (1 clock)
rrf PORTB,f       ;third bit is shifted out (1 clock)
rrf PORTB,f       ;fourth bit is shifted out (1 clock)
rrf PORTB,f       ;fifth bit is shifted out (1 clock)
rrf PORTB,f       ;sixth bit is shifted out (1 clock)
rrf PORTB,f       ;sevenths bit is shifted out (1 clock)
rrf PORTB,f       ;eighth bit is shifted out (1 clock)
Этот код выводит биты одного байта в видеопорт, как в предыдущем примере, но делает это на много быстрее. При этом программа использует все восемь бит выходного порта.
Этот пример позволяет каждый цикл изменять видеосигнал, что дает разрешение 156 пикселей, если не нужно установочного времени. В действительности обычно всегда есть значительное установочное время до и после вывода 8 бит графики. В течении этого времени выводятся черные или белые пиксели. В игре Pong установочное время можно видеть при отображении на экране текста. Там используется этот метод, поэтому между буквами на экране такое большое пространство. Я думаю реально получить 10 символов в строке, каждый шириной 8 пикселей. Таким образом в среднем для вывода каждого пикселя требуется 1,5 цикла ( включая установочное время ). В Pong биты, которые сдвигаются на выход, берутся из ОЗУ. Для одной строки требуется 8*8бит=8Байт. Для каждой линии эти 8 Байт должны быть получены путем чтения из ППЗУ, где они хранятся. В ходе выполнения программы в нужный момент требуемые данные строки изображения переписываются из ППЗУ в ОЗУ. Для того чтобы сделать все это для 8 символов требуется очень много времени. На это уходит целая строка. Вот почему текст отображается через строку. В тот момент, когда отображается черная строка, микропроцессор производит вычисления для следующей строки.

Как было сказано выше, символ рисуется только каждую вторую строку.

Итак, этот метод позволяет получить изображение с достаточно высоким разрешением, но требует целиком PORTB для сдвиговой операции. Сначала может показаться, что невозможно использовать PORTB для других целей, но это не так. Он легко может быть использован как выходной, если один из выходов PORTA использовать для запрета другим устройствам соединяться с PORTB, когда он используется как сдвиговый регистр. Так же возможно использовать PORTB как вход в момент, когда не выполняется операция сдвига. В моих играх мне требовалось много входов для подключения джойстика. Соединять джойстик напрямую рискованно, так как можно сжечь входной буфер порта. ( Джойстик – это группа выключателей, которые замыкаются на землю при нажатии. ) Я решил эту проблему путем использования 100кОм подтягивающих резисторов 1кОм защитных резисторов. Это позволяет напряжению опускаться до 0, когда джойстик нажат и PORTB используется как вход, но защищает от короткого замыкания при работе PORTB в качестве сдвигового регистра.

DIGITA.ru: огромный выбор телевизоров (обычные, проекционные, 100MHz, плазменные).

Вертикальная синхронизация.
Для получения устойчивого изображения необходимо добавить в видеосигнал импульсы вертикальной синхронизации. Это может быть достигнуто с помощью представленного ниже кода.
shortsync:          ; label "Shortsync", entry for short sync generator
movwf counter1      ; set counter1 to number of shortsyncs
shortsync_l0:       ; label "Shortsync_l0", short sync count loop entry
bcf porta,0         ; set level to synclevel (bit 1)
bcf portb,0         ; set level to synclevel (bit 0)
dnop                ;
movlw 0x1D          ; set counter2 to "30us" 
movwf counter2      ;
nop                 ;
bsf porta,0         ; set level to black 
shortsync_l1:       ; label "Shortsync_l1", short sync delay loop
decfsz counter2     ; do delay counting
goto shortsync_l1   ; loop if not finished with delay
decfsz counter1     ; count number of shortsyncs 
goto shortsync_l0   ; if more shortsyncs, keep looping
retlw 5             ; return and set w to number of longsyncs (5 longsyncs)
vertsync:           ; label "vertsync", this is the label to call from main
movlw 5             ; set number of shortsyncs to 5
btfss videostuff,0  ; check if first field 
movlw 6             ; yes, change number of short syncs to 6
call shortsync      ; do those short syncs
incf videostuff     ; update field for the new frame
longsync:           ; label "longsync", just to make it easy to understand 
movwf counter1      ; set synccounter to number of longsyncs
longsync_l0         ; label "longsync_l0", long sync count loop entr
movlw 0x1D          ; set counter to 30us
movwf counter2      ; set level to sync (bit 1)
bcf porta,0         ; set level to sync (bit 0)
bcf portb,0         ; label "Shortsync_l1", long sync delay loop 
longsync_l1         ; do delay counting 
decfsz counter2     ; loop if not finished with delay
goto longsync_l1    ; 
nop                 ; set level to black
bsf portb,0         ; 
nop                 ; count number of shortsyncs
decfsz counter1     ; if more shortsyncs, keep looping 
goto longsync_l0    ; set number of shortsyncs to 5
movlw 5             ; check if second field 
btfss videostuff,0  ; yes, do 4 shortsyncs instead
movlw 4             ; do those short syncs
goto shortsync
Этот код генерирует вертикальные синхроимпульсы, как было описано выше. Код состоит из участков, которые выполняются по нескольку раз. Сначала вызывается подпрограмма коротких импульсов, затем подпрограмма длинных импульсов, потом в последней строке кода снова вызывается подпрограмма коротких импульсов. Программа кажется запутанной, но это позволяет сократить ее длинну и сэкономить память программ.

Моя игра Pong.
Код игры Pong кажется запутанным и непонятным. Это моя первая программа, связанная с видео. Я многому научился после того, как ее написал и думаю, что возможно, ее можно было бы сделать более эффективной.
Для того, чтобы сохранить мяч в границах экрана, в программе приходится использовать много циклов IF. Первые линии просто белые. Это верхние линии, во время которых выполняются действия, определяющие логику игры. Для остальных линий определены по два значения: одно с мячом, второе – без мяча. В лини без мяча сначала показывается левый игрок, если он есть, потом черный участок, а затем, если необходимо , правый игрок. В линии с мячом выполняется то же самое, но на черном фоне в определенном месте должен быть показан мяч. До и после мяча присутствуют две паузы, во время которых вычисляется положение мяча в строке. Каждая пауза длится три цикла, поэтому мяч перемещается довольно большими скачками.
В низу экрана отображается счет. Для показа счета используется сдвиговый метод, описанный ранее. В большинстве строк проверяется, включен ли звук. Если да, на выход аудио подается сигнал.
Информация о тексте меню хранится в памяти данных в виде строк длинной 8 символов. Текст выводится на экран методом сдвига. Это происходит через строку так как в течении первой строки производится извлечение информации из памяти данных и сохранение ее в буфере, а уже во время второй строки эти данные передаются на выход видео.
.
Игра Pong в действии. Экран меню.
Моя игра Tetris.
Для того, чтобы хорошо понять логику работы программы, прежде чем писать ее на ассемблере для PIC, я сначала написал ее на Borland C для DOS для ПК.
Блоки хранятся в памяти в сжатом виде и в нужный момент распаковываются в буфер, где хранятся в соответствии с координатами места на экране. В программе есть три режима управления блоками в буфере экрана: установка, очистка и тест. Установка и очистка это режимы, в которых блоки могут добавляться и удаляться в/из в определенную часть экрана. В режиме тест проверяется попал ли блок в нужное положение. Такой подход делает программу достаточно структурированной и легкой ( по сравнению с Pong ) для просмотра. Режим вывода на экран похож на вывод текста, просто вместо букв на видеовыход сдвигаются данные о блоках и черных участках между ними.
В игре присутствует звуковое сопровождение, которое изменяется в зависимости от момента игры. Счет отображается сдвиговым методом, здесь все как обычно. Меню в игре нет, так как под него не хватило памяти.

Игра Tetris в действии.



Наложение видео на существующий сигнал.

Меня часто спрашивают, – как наложить один видеосигнал на другой. Кратко коснусь этой темы. Довольно сложно сложить два видеосигнала, но намного легче наложить изображение на видеосигнал, если изображение мы генерируем сами. В этом случае вместо того, чтобы генерировать синхроимпульсы, мы извлекаем их из входного видеосигнала. Это легко можно сделать с помощью микросхемы LM1881. LM1881 – это селектор синхроимпульсов, он выделяет горизонтальные и вертикальные синхроимпульсы из видеосигнала. Допустим, мы хотим добавить маленькую картинку в нижний правый угол текущего изображения. Тогда мы ждем вертикальный синхроимпульс, а после этого просто начинаем считать горизонтальные синхроимпульсы до тех пор, пока не начнется строка, в которую требуется добавить изображение. Если надо добавить картинку 8х8 пикселей, тогда мы должны изменить изображение в конце следующих 8 строк. Изображение добавляется отключением на этот момент оригинального сигнала и передачей нашей видеоинформации. В каждой строке необходимо ждать 40 – 50 мкс, в зависимости от Х-положения, куда должна быть добавлена картинка. Когда это будет сделано для всех 8 строк, мы опять начинаем ждать вертикальный синхроимпульс, и повторяем все сначала. Размер памяти микроконтроллера PIC ограничен, поэтому сделать что то более значительное на много сложнее.

DIGITA.ru: DVD-плееры, видео-магнитофоны, видео-плееры. Большой выбор. Лучший сервис.

Цветной видеосигнал и почему PIC16F84 не может его создать.

В этой части поговорим о том, как работает цветной видеосигнал. Эта тема достаточно сложна и требует некоторых базовых знаний в радиоэлектроники. Я только прикоснусь к этому вопросу, так как слишком сложно вдаваться в детали, да и все равно, невозможно программным путем с помощью PIC16F84 получить цветной видеосигнал. Если Вы хотите получить больше информации, прочтите книгу по этой теме.

Информация о цвете в видеосигнале.
Когда разрабатывалось цветное телевидение, требовалась его совместимость со старым черно-белым телевидением. Поэтому в цветном телевидении много от черно-белого. Если цветной телевизионный сигнал принимается черно-белым телевизором, должно быть возможным смотреть его так, чтобы он не отличался черно-белого видеосигнала. Для этого в видеосигнал был добавлен амплитудно-модулированный сигнал цвета с несущей частотой 4,43 МГц. Несущая цвета фактически добавляет некоторый шум в изображение, но он незначителен. В черно-белых телевизорах, созданных после выпуска цветных, был добавлен специальный фильтр для удаления несущей цвета.
Комбинируя красным, зеленым и синим цветами, можно получить любой оттенок цвета, который Вы желаете. Таким образом, видеосигнал должен содержать три компоненты цвета. По сравнению с черно-белым сигналом это требует передачи значительно большей информации. Сумма всех компонент фактически уже является информацией об интенсивности черно-белого сигнала. Так же при передаче двух цветоразностных сигналов (R-G) и (B-G) можно выделить все три цвета. Но передавать две цветовые компоненты, используя одну несущую частоту, разве это возможно? Да это можно сделать, если генерировать два варианта несущей, с фазовым сдвигом 90 градусов. Сигнал (R-G) передается на оригинальной несущей, а (B-G) на несущей с измененной фазой. Упрощенно видеосигнал можно представить так:

signal_level = (R+G+B) + (R–G)*sin(w*t) + (B-G)*cos(w*t)

Для того чтобы выделить две компоненты цвета, генератор телевизора должен работать синхронно с генератором передатчика. В течении 8 мкс задержки, когда электронный луч движется к началу следующей строки, в черно-белом сигнале ничего не передается. В цветном сигнале в этот промежуток времени передается около 10 периодов несущей цвета. Эту цветовую вспышку телевизор использует для обеспечения требуемой синхронизации. Если этого не будет сделано, то невозможно будет корректно получить цвет. В ранние годы цветного телевидения цветовой вспышки не всегда было достаточно, генератор был нестабилен, поэтому фаза менялась, и лица людей становились зелеными. Это проблема NTSC стандарта. При создании стандарта PAL, в каждой линии был добавлен сдвиг фазы на 180 градусов. После этого фазовые ошибки исчезли.

Осциллограмма строки цветного сигнала. Сначала передается синхроимпульс длительностью 4мкс, затем в течении 8мкс задержки передается несущая цвета. В оставшиеся 52 мкс передается информация об изображении.

Генерация цвета программным способом.
На первый взгляд кажется, что невозможно создать цветной видеосигнал программным способом, ведь это должен быть аналоговый сигнал с несущей частотой 4,43 МГц. В действительности же на видеовходе телевизора стоит фильтр, который не пропускает частоты выше спектра видеосигнала (4 – 5 МГц ). Если вместо синусоидального сигнала будут передаваться прямоугольные импульсы, они все равно будут восприняты телеприемником как синусоидальный сигнал, так как верхние гармоники будут срезаны фильтром. Поэтому нет необходимости создавать реальный аналоговый сигнал ( хотя вероятно при полностью аналоговом сигнале качество изображения будит лучше ). Для создания одного сигнала частотой 4,43 МГц PIC16F84 должен выполнять не менее 2х4,43 MIPS (миллион операций в секунду ). Но этого не достаточно, так как в видеосигнал необходимо добавить две несущих, сдвинутых друг относительно друга на 90 градусов. Для этого требуется разбить период несущей частоты еще на 4 части, то есть требуется производительность 4х4,43=17,72 MIPS. Таким образом PIC должен работать на частоте не менее 70,88 МГц, а это много. Приведенный расчет соответствует случаю, когда цвет не изменяется. Невозможно одновременно изменить больше одного бита информации о цвете. Для того, чтобы изменить целый байт цвета требуется два цикла. Таким образом, PIC должен работать на частоте 141,76 МГц, что для него очень много. Однако такую производительность можно достичь с помощью SX-чипа, он похож на PIC, но выполняет 50 или 100 MIPS. Я действительно делал несколько экспериментов с этим микроконтроллером в начале 1999 года, но безуспешно. У меня были проблемы с программированием этого чипа. Сначала я думал, что причина в SX-key программаторе, но оказалось, что дело в ранней версией SX-чипа. Проблема была решена с помощью Scenix, и в ближайшее время я собираюсь продолжить работу с этим проектом. Думаю, что с помощью SX-чипа все-таки возможно генерировать цветной видеосигнал. Правда это будит несложная графика, например как в Tetris и в других подобных играх. Если Вы хотите генерировать цветной сигнал с помощью PIC, тогда вам потребуется несколько дополнительных микросхем для поддержки цветовой части. Это было сделано Marcelo Maggi, который сделал colortest pattern generator используя дополнительную микросхему цвета. Сегодняшние PIC микроконтроллеры не позволяют программным способом создать цветной видеосигнал.
Rickard Gunee
" How to generate video signals in real-time using a PIC16F84 "
Перевод с английского.
Перевод выполнен с небольшими сокращениями.

Примеры практического применения:
- Генератор видеосигнала на микроконтроллере PIC16F84.
- Игра Pong.
- Игра Tetris.


НА ГЛАВНУЮ | ЧТО ТАКОЕ PIC ? | ПРОГРАММАТОР | ПРОЕКТЫ | СТАТЬИ | ССЫЛКИ | КАРТА САЙТА

Карта сайта.

Главная.

Что такое PIC ?
|__ Макетная плата.

Программатор.
|__ Схема.
|__ Печатная плата программатора.
. . . . |__ Вариант1 Автор: Николай Большаков.
. . . . |__ Вариант2 Автор: Дмитрий Скупов.
. . . . |__ Вариант3 Автор: Oleg.
. . . . |__ Вариант4 Автор: Leshiy.
. . . . |__ Вариант5 Автор: Медведь.
. . . . |__ Вариант6 Автор: Виктор.
|__ Предложения по улучшению cхемы программатора.
. . . . |__ Схема модифицированного ( с Z-состоянием) программатора.
|__ Ответы на вопросы, связанные с работой программатора.
|__ История изменений внесенных в программу.

Проекты.
|__ Генератор видеосигнала на микроконтроллере PIC16F84.
|__ Устройство управления на микроконтроллере PIC16F84.

Статьи.
|__ Как с помощью PIC16F84 генерировать видеосигнал.
|__ Реализация последовательной асинхронной передачи данных в микроконтроллерах PIC16Cxx.

Ссылки.

Архив новостей.
 
Hosted by uCoz