VGA сигнал

krikus
Offline
Зарегистрирован: 22.07.2011

Прошу помощи в расчетах. Мне нужно сформировать VGA сигнал: 256x208x50Hz. Вопрос: как расчитать тайминги, периоды/задержки синхронизаций и т.п. Я часто нахожу подобные картинки стандартов: ->

Я понимаю, что 256x208 - нифига не стандарт, но все же... все тайминги должны рассчитываться по какой-то формуле. Единственное, что я знаю, что Pixel Clock для 256x208x50Hz будет 2MHz.

__Alexander
Offline
Зарегистрирован: 24.10.2012
krikus
Offline
Зарегистрирован: 22.07.2011

Может я слепой, но я не вижу расчет таймингов для n-ого разрешения экрана. Там стандартное разрешение: 640x480.

krikus
Offline
Зарегистрирован: 22.07.2011

http://wiki.pic24.ru/doku.php/osa/articles/vga_terminal То же пример. Никак не могу найти из них расчеты таймингов. В упор не вижу.

Ynicky
Offline
Зарегистрирован: 30.05.2013

Мне нужно сформировать VGA сигнал: 256x208x50Hz.

А на какой монитор/телевизор Вы хотите выдавать этот сигнал?

Мониторов, насколько я знаю, на 50 Гц не бывает.

krikus
Offline
Зарегистрирован: 22.07.2011

Ynicky пишет:

Мне нужно сформировать VGA сигнал: 256x208x50Hz.

А на какой монитор/телевизор Вы хотите выдавать этот сигнал?

Мониторов, насколько я знаю, на 50 Гц не бывает.

Elenberg TFT Monitor. Очень хорошо "кушает" этот сигнал. (Проверено)

Ynicky
Offline
Зарегистрирован: 30.05.2013

Тогда такой вопрос.

256x208 - это на весь экран? А если на часть, то при каком стандартном разрешении?

krikus
Offline
Зарегистрирован: 22.07.2011

Ynicky пишет:

Тогда такой вопрос.

256x208 - это на весь экран? А если на часть, то при каком стандартном разрешении?

Он показывает на весь экран, но обрезает 8строк сверху.

Ynicky
Offline
Зарегистрирован: 30.05.2013
Ну, если я правильно понял вопрос, частота VGA контроллера (pixel clock)
определяется так:
(количество эл. из. по горизонтали(256) + колич. эл. из. на бордюр(слева + справа) +
колич. эл. из. на строчный гасящий импульс) * (количество эл. из. по вертикали(208) +
колич. эл. из. на бордюр(сверху + снизу) + колич. эл. из. на кадровый гасящий импульс)
* 50 Гц.
Соответственно времена на отдельные составляющие растра рассчитываются из
количества эл. из. (периодов пиксельной частоты), занимающие участок растра.
 
krikus
Offline
Зарегистрирован: 22.07.2011

Ynicky пишет:

Ну, если я правильно понял вопрос, частота VGA контроллера (pixel clock)
определяется так:
(количество эл. из. по горизонтали(256) + колич. эл. из. на бордюр(слева + справа) +
колич. эл. из. на строчный гасящий импульс) * (количество эл. из. по вертикали(208) +
колич. эл. из. на бордюр(сверху + снизу) + колич. эл. из. на кадровый гасящий импульс)
* 50 Гц.
Соответственно времена на отдельные составляющие растра рассчитываются из
количества эл. из. (периодов пиксельной частоты), занимающие участок растра.
 

А бордюры как вычисляются? или они всегда одинаковые?

krikus
Offline
Зарегистрирован: 22.07.2011

Ynicky пишет:

Мне нужно сформировать VGA сигнал: 256x208x50Hz.

А на какой монитор/телевизор Вы хотите выдавать этот сигнал?

Мониторов, насколько я знаю, на 50 Гц не бывает.

И еще. дополню.

В принципе, можно формировать изображение размером 640x480x50Hz. Просто использовать pixel clock от разрешения, которое мне нужно. Тем самым, 1"виртуальный пиксель" будет занимать ~5.7 "реальных пикселей", я полагаю. Такой трюк был замечен там: http://www.lucidscience.com/pro-vga%20video%20generator-5.aspx

Ynicky
Offline
Зарегистрирован: 30.05.2013
А бордюры как вычисляются? или они всегда одинаковые?
 
В зависимости от стандарта они разные.
В стандарте 640x480x60 - они занимают по горизонтали по 8 эл.из. с обоих сторон
+ еще какое-то время уровня черного (причем слева и справа разное).
Так же и по вертикали.
Это связано с работой старых мониторов с электронно-лучевыми трубками.
 
В принципе, можно формировать изображение размером 640x480x50Hz.
Просто использовать pixel clock от разрешения, которое мне нужно.
Тем самым, 1"виртуальный пиксель" будет занимать ~5.7 "реальных пикселей", я полагаю.
 
Тогда у Вас будет не пропорциональное изображение, т.е. вместо круга - эллипс.
 
krikus
Offline
Зарегистрирован: 22.07.2011

Тогда у Вас будет не пропорциональное изображение, т.е. вместо круга - эллипс.

Это можно подкорректировать на мониторе.(параметр - сжатие, вроде бы) Теперь главный вопрос: как научить ArduinoUno/Mega/etc. рисовать не только полосы(что почти во всех проектах) на экране, но и заполнять определенный пиксель, либо читать растровые изображения из флэш памяти... при малом разрешении это должно быть возможно.

Ynicky
Offline
Зарегистрирован: 30.05.2013

А вот это не поможет?

http://www.polesite.ru/?p=2207

 

krikus
Offline
Зарегистрирован: 22.07.2011

Ynicky пишет:

А вот это не поможет?

http://www.polesite.ru/?p=2207

 

Хех :) Мне рекомендуют мой же сайт. Да, это в какой-то степени помогает, единственное, там ArduinoDue, ну и мощь у нее соответственная, а мне бы под что-то поменьше. Но, прочитав кучу статей, уже начинаю осознавать, что под ArduinoUno/Mega такое разрешение не запустишь. Если только использовать скорость аппаратного SPI, но там всего 1 вывод - т.е. изображение можно будет сделать только черно-белое. Либо разогнать, у меня есть разогнанная ArduinoMega2560 - 26.6MHz, но при такой частоте микроконтроллер часто дает сбой.

 

krikus
Offline
Зарегистрирован: 22.07.2011

Подредактировал скетч оттуда http://garagelab.com/profiles/blogs/arduino-generated-vga-color-signal-complete

Сделал вывод изображения 272x208, но с синхроимпульсами для разрешения 640x480. Результат:

Видимо, что-то с таймингами не то, поэтому изображение искаженное.

Вот код:



#define NOP asm("nop")
 
unsigned int linecount = 1;
 
void setup()
{
  //Set pins 5 to 10 as outputs
  // 7 - HSYNC
  // 6 - VSYNC
  // 10, 9 e 8 - RGB  
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  DDRD = B11111111;
 
  //set timer  
  TCCR2A = 0x02;                        // WGM22=0 + WGM21=1 + WGM20=0 = Mode2 (CTC)
  TCCR2B |= (1 << CS20);                //
  TCCR2B |= (1 << CS21);                // Set prescaler
  TCCR2B &= ~(1 << CS22);               //
 
  TCNT2 = 0;                            // clean counter
 
  TIMSK2 &= ~(1<<OCIE2A);                // set comparison interrupt  
  TIMSK2 |= (1<<TOIE2);                // set overflow interrupt  
}
 
void loop()
{
  noInterrupts();
  do{
    PORTD = 0;
    if (TCNT2 > 0x0f){
 
      delayMicroseconds(1);
      NOP;NOP;NOP;NOP;
     
      TCNT2 = 0x00;
 
   
                       
      // #### HSYNC ###
      PORTB &= ~(1 << 1);      
      if (++linecount >= 525){ //525 lines
        linecount = 1;
      }      
      PORTB |= (1 << 1);
 
 
 
      // ### VSYNC ###
      if ((linecount == 1)||(linecount == 2)){
        PORTB &= ~(1 << 0);      
      } else {
        PORTB |= (1 << 0);
       
 
        NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
        NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
        NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;
        NOP;NOP;NOP;NOP;NOP;
       
        if ((linecount >= 145) && (linecount <= 353)){
         //Video-DATA 
			PORTD = 1; 
			PORTD = 2;
			PORTD = 3;
			PORTD = 4;
			PORTD = 5;
			PORTD = 6;
			PORTD = 7;
			PORTD = 8;
			PORTD = 9;
			PORTD = 10;
			PORTD = 11;
			PORTD = 12;
			PORTD = 13;
			PORTD = 14;
			PORTD = 15;
			PORTD = 16;
			PORTD = 17;
			PORTD = 18;
			PORTD = 19;
			PORTD = 20;
			PORTD = 21;
			PORTD = 22;
			PORTD = 23;
			PORTD = 24;
			PORTD = 25;
			PORTD = 26;
			PORTD = 27;
			PORTD = 28;
			PORTD = 29;
			PORTD = 30;
			PORTD = 31;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 255;
			PORTD = 31;
			PORTD = 30;
			PORTD = 29;
			PORTD = 28;
			PORTD = 27;
			PORTD = 26;
			PORTD = 25;
			PORTD = 24;
			PORTD = 23;
			PORTD = 22;
			PORTD = 21;
			PORTD = 20;
			PORTD = 19;
			PORTD = 18;
			PORTD = 17;
			PORTD = 16;
			PORTD = 15;
			PORTD = 14;
			PORTD = 13;
			PORTD = 12;
			PORTD = 11;
			PORTD = 10;
			PORTD = 9;
			PORTD = 8;
			PORTD = 7;
			PORTD = 6;
			PORTD = 5;
			PORTD = 4;
			PORTD = 3;
			PORTD = 2;
			PORTD = 1;
			PORTD = 0;
			PORTD = 0;
			PORTD = 0;
			PORTD = 0;
			PORTD = 0;
			PORTD = 0;
			PORTD = 0;
           //END of VIdeo-DATA     
        }
           
      }
 
 
}
 
 
}while(1);
 
}