|
Подмешивание в видеосигнал |
|
|
|
Dec 20 2007, 19:44
|
Частый гость
 
Группа: Новичок
Сообщений: 90
Регистрация: 19-12-07
Пользователь №: 33 459

|
Разбираюсь с АТмегой16, на этот раз экспериментирую с подмешиванием данных (хотя бы палочек-полосок) в композитный видео-сигнал. Перерыл все возможные гуглы, нашел несколько реализаций, нашел описание передачи видео-сигнала. Читал, смотрел, опять читал. С железом более-менее разобрался, принцип работы понятен. А вот с софтом не очень, не хватает познаний. Так что все рассуждения основываются на познаниях из мануалов "для чайников" Итак, купил LM1881, кварц 16 мгц, конденсаторы, резисторы, пару диодов. Подключил все это к меге16 - сигнал горизонтальной синхронизации на вход внешних прерываний INT0, вертикальной на INT1. Получается что прерывание по INT0 возникает в начале прорисовки каждой строки, а INT1 в начале каждого кадра (или полукадра, т.к. рисуется через строчку). Ногу PD7 сделал выходом и подключил обратно к центральной жиле видеокабеля через диод и сопротивление. Сделал счетчик строк, который прибавляет 1 при каждом INT0 и обнуляет при INT1. Посидел, подумал, написал... в прерывании INT0 ждем нужной строки, после чего ждем определенное время, включаем "питание" на PD7, опять ждем, выключаем питание. Получается горизонтальная линия определенной длины и с определенным смещением от левого края. Нарисуем крест. В обработчике INT0 условие - если строка не та, которая нам нужна, то ждем, включаем PD7 и сразу же выключаем (чтобы получить штрих с наименьшим размахом). Т.к. задержка в каждой строке одинаковая, должна получится ровная вертикальная линия. Но не получается :  Линия гуляет как бы лесенкой на всем протяжении. По логике получается, что временной интервал от начала прерывания до начала включения PD7 при одинаковых значениях получается разным  Фото стоп-кадра экрана прикрепил. Вот кусок кода с обработкой прерываний: Код // External Interrupt 0 service routine interrupt [EXT_INT0] void ext_int0_isr(void) { if (vert==150) { i=10; while(i--) { #asm("nop"); } PORTD.7=1; i=30; while(i--) { #asm("nop"); } PORTD.7=0; } else { i=20; while(i--) { #asm("nop"); } PORTD.7=1; PORTD.7=0; }
vert++; }
// External Interrupt 1 service routine interrupt [EXT_INT1] void ext_int1_isr(void) { // Place your code here vert=0; } Обучите, пожалуйста, чайника основным принципам правильного построения изображения на этой железной связке (LM1881 + atmega16). Для начала хотя бы прямых линий
Сообщение отредактировал idono - Dec 20 2007, 19:48
Эскизы прикрепленных изображений
|
|
|
|
|
 |
Ответов
|
Dec 21 2007, 00:07
|
Гуру
     
Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047

|
Цитата(PSP @ Dec 21 2007, 00:19)  Прерывание не обрабатывается мгновенно, всегда происходит завершение выполнения текущей команды фоновой программы, а это обычно от одного до нескольких тактов, плюс время входа в прерывание. Почитайте раздел "Interrupt Response Time" из datasheet. При тактовой 16 МГц это даст переменную задержку не менее 62.5 нс, что составляет больше 1% от ширины экрана, т.к. видимая часть меньше полной длительности строки 64 мкс. Нет, чуть больше 0.1% - ведь разница три порядка, а не два. А 0.1% не очень заметны. Но по-хорошему, надо бы принимать дополнительные меры к синхронизации. Цитата(PSP @ Dec 21 2007, 00:19)  Можно пытаться бороться с неопределенностью момента старта используя сигнал прерывания для выхода из состояния SLEEP, но остается проблема несинхронности тактового генератора процессора и синхроселектора. Или видел вариант применения строчного синхроимпульса в качестве сигнала "сброс" с одновременным разрешением работы тактового RC-генератора процессора. Это позволяет привязать генератор к фазе синхросигнала. Для RC-генератора выход из sleep даст необходимую синхронизацию. Альтернатива - PLL для тактового генератора.
|
|
|
|
|
Dec 21 2007, 07:02
|
Частый гость
 
Группа: Новичок
Сообщений: 90
Регистрация: 19-12-07
Пользователь №: 33 459

|
Вставил бесконечный цикл с idle(); в главной функции - расстояния между изломами вертикальной линии стани больше. Померял линейкой ширину "перелома" (эксперементирую на проекторе, поэтому померять вполне реально) - получилось действительно около 0.2% погрешности. Выходит, что мои волнения были напрасны, для небольшого экрана такая погрешность будет вполне допустима Следующим шагом попробую выводить осмысленные буковки. Кстати, те проекты avr-vga и телеметрию для воздушного шара я нашел и изучил в первую очередь. По коду почти ничего не понял  Буду постить свои попытки изучить систему в этой теме, если вы не против  Может быть еще кому-то из начинающих она поможет в будущем. Если я правильно понял принцип построения текста на экране - есть некий двухмерный массив с битами 0 1, как бы матрица для построения цифры по слоям, в котором цифра, например, 1 выглядит так (беру цифру с разрешением 8х12, как в проекте avr-vga): 11111111 11111111 10000111 11100111 11100111 11100111 11100111 11100111 11100111 11100111 11111111 11111111 Имея массив с текстом для вывода и счетчик текущей строки, выводим чисто построчно, перемигиваясь в каждой строке нулями и единицами. Ну и конечно надо учитывать, что изображение строится через строку. // пошел пробовать
|
|
|
|
|
Dec 21 2007, 08:55
|
Частый гость
 
Группа: Новичок
Сообщений: 90
Регистрация: 19-12-07
Пользователь №: 33 459

|
Цитата(alux @ Dec 21 2007, 10:48)  Смотри на avrfreaks в последних проектах "AVGA demo". там что-то совсем жестко, я и элементарные проекты разобрать не могу  написал сам как смог прорисовку одного символа: Код int start_line=100; // начинаем вывод с линии номер 100 int cur_line=0; // переменная для отсчета линий с момента начала прорисовки символа
// сам тестовый символ (нарисован 0 единичками) char symbol[8]={0b01111111, 0b01000001, 0b01000001, 0b01000001, 0b01000001, 0b01000001, 0b01000001, 0b01111111};
// External Interrupt 0 service routine interrupt [EXT_INT0] void ext_int0_isr(void) { //если находимся в области прорисовки: if (vert>start_line && vert<start_line+9) { i=30; while(i--) { #asm("nop"); } // задержка перед выводом (для отступа слева) PORTD.7=symbol[cur_line] & (1 << 0); // присваиваем порту вывода 1, если в нулевом бите symbol единица (т.е. включаем белый пиксел) PORTD.7=symbol[cur_line] & (1 << 1); // тоже, но проверяем первый бит PORTD.7=symbol[cur_line] & (1 << 2); // второй бит PORTD.7=symbol[cur_line] & (1 << 3); // и так далее PORTD.7=symbol[cur_line] & (1 << 4); PORTD.7=symbol[cur_line] & (1 << 5); PORTD.7=symbol[cur_line] & (1 << 6); PORTD.7=symbol[cur_line] & (1 << 7); cur_line++; // переходим на опрос слдующего элемента массива } else { cur_line=0; // сбрасываем позицию на ноль, если находимся вне области прорисовки }
vert++; // увеличиваем счетчик горизонтальных линий }
// External Interrupt 1 service routine interrupt [EXT_INT1] void ext_int1_isr(void) { vert=0; //сбрасываем счетчик линий при начале прорисовки нового кадра } В результате получается такой широченный символ  Как с максимальной скоростью вывести на PORTD.7 сразу все восемь бит переменной? То есть если в переменной "0b01011100", то на порт PD7 быстренько по-очереди выведутся значения 0 1 0 1 1 1 0 0 Циклом for() получается еще дольше, чем я в ряд записал, видимо процессор тратит много тактов на такие операции
Эскизы прикрепленных изображений
|
|
|
|
Сообщений в этой теме
idono Подмешивание в видеосигнал Dec 20 2007, 19:44 Serj78 на 16 мгц совершенно достаточно засыпать потом про... Dec 20 2007, 21:41 Т.Достоевский Цитата(Serj78 @ Dec 21 2007, 00:41) на 16... Dec 20 2007, 22:52 =VRA= Все это на раз делается даже без LM1881 Dec 20 2007, 23:41 GDI Цитатавидимо процессор тратит много тактов на таки... Dec 21 2007, 09:23 idono Чтение байта из массива перед выводом помогло, шир... Dec 21 2007, 09:55  idono нарисовал из нулей массив цифр, написал функцию дл... Dec 21 2007, 16:32   Maik-vs ИМХО это большой героизм советского толка писать т... Dec 21 2007, 17:17    rx3apf Цитата(Maik-vs @ Dec 21 2007, 20:17)... Dec 21 2007, 17:43    idono Цитата(Maik-vs @ Dec 21 2007, 20:17)... Dec 22 2007, 11:34     idono Сделал вариант с выводом байта целиком в порт с по... Dec 22 2007, 20:23 rezident Чтобы уменьшить джиттер и величину запаздываний вы... Dec 21 2007, 17:24 umup ЦитатаTWI - не лучший вариант. SPI - тоже
как раз... Dec 21 2007, 18:12 rx3apf Цитата(umup @ Dec 21 2007, 21:12) как раз... Dec 21 2007, 18:29  Rst7 Цитата(rx3apf @ Dec 21 2007, 20:29) Я же ... Dec 22 2007, 06:02 Rst7 ЦитатаПолучилась отличная реализация телеметрии дл... Dec 23 2007, 12:46 Xumuk Привет всем
Очень интересная тема, давно думал на... Dec 23 2007, 14:36  idono Xumuk, на схеме сразу бросается в глаза разрыв вид... Dec 23 2007, 18:23   Xumuk Цитата(idono @ Dec 23 2007, 20:23) Xumuk,... Dec 23 2007, 20:40    idono Цитата(Xumuk @ Dec 23 2007, 23:40) А можн... Dec 23 2007, 21:39     idono Объясните на пальцах, пожалуйста, как сделать выво... Jan 1 2008, 01:18 Т.Достоевский Только вертикальную скорость нужно отображать ввид... Dec 23 2007, 18:54 idono Цитата(Т.Достоевский @ Dec 23 2007, 21:54... Dec 23 2007, 19:27  Т.Достоевский Цитата(idono @ Dec 23 2007, 22:27) Не дум... Dec 23 2007, 19:40 HCHUNTER idono,
...от себя хотел добавить - обратите вним... Jan 1 2008, 07:39 Serj78 Idono,
Надо просто помнить, что SPI - фактически... Jan 1 2008, 11:09 HCHUNTER Цитата(Serj78 @ Jan 1 2008, 14:09) невозм... Jan 1 2008, 12:21  Xumuk Может целесообразно использовать 2 микроконтроллер... Jan 19 2008, 08:15 Algol HCHUNTER
А сколько вам необходимо ОЗУ? Может быть ... Jan 19 2008, 09:54 AndyBig ЦитатаМожет быть поставить внешную статическую рам... Jan 19 2008, 15:03
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|