Amateur Radio Station R9AL



VGA это сокращение от Video Graphics Array, протокола отображения видео, который часто встречается в мире электроники. В VGA используется одна "частота следования пикселей" и установленная частота вывода видео данных горизонтально, строка за строкой, пока весь кадр не будет отображен, а потом всё начинается снова.

Цель и обзор этого проекта



Целью данного проекта является использование Arduino для вывода стандартного изображения с красным, зеленым и синим цветом на компьютерный VGA монитор. Кроме платы Arduino используется плата с VGA разъемом.

Для того, чтобы вывести красный, зеленый и синий цвета на компьютерный VGA монитор, мы должны договориться о разрешении, которое мы будем пытаться имитировать. Например, 800x600 удобно, т.к. используются целые круглые числа, и частота следования пикселей составляет 40МГц. И можно имитировать VGA разрешение 800x600 и выводить 200 линий красного, 200 линий зеленого и 200 линий синего цветов. Поскольку Arduino работает на частоте 16МГц, невозможно получить доступ к каждому пикселю, поэтому мы будем выводить целиком линии.

Элементы:

Особенности схемы

RGB соединения

В VGA используется смешивание красного зеленого и синего цветов для получения всех цветов радуги. Параметры на каждом из этих контактов показывают монитору, насколько интенсивно должен гореть этот цвет. Мы не регулируем интенсивность цвета, поэтому у нас всегда для каждого из цветов 100% красного, 100% зеленого или 100% синего.

Hsync и Vsync соединения

Для того чтобы знать, какая линия сейчас отображается и завершен ли кадр, используется два сигнала синхронизации: горизонтальная синхронизация H-SYNC и вертикальная синхронизация V-SYNC. Это самые важные сигналы, и если их тайминги будут нарушены, то VGA выход не будет работать как надо.

Основы теории VGA

В спецификации VGA описывается отображение цветовых данных, горизонтальной и вертикальной синхронизации, и об определенном времени на каждое действие, которое нельзя пропускать.

Arduino UNO тактируется кварцевым генератором 16МГц и одна инструкция выполняться за один цикл, что означает, что каждая инструкция в нашей программе будет выполняться точно за (1/16000000) секунды или примерно 62,5 наносекунды.



Так как каждая инструкция выполняется 62,5 наносекунды, и мы должны проводить синхронизацию в определенное время, важно, что каждое время с картинки выше делиться на 62,5 наносекунды, а это значит, что мы можем использовать инструкции с задержкой, чтобы получить идеальное время для синхронизации.



При использовании 800x600VGA, каждая строка заканчивается горизонтальным импульсом синхронизации, который сообщает монитору данные следующей строки. После синхронизации 601 линии, монитор ожидает импульс вертикальной синхронизации продолжительностью 4 линии. В этот момент есть пауза в 23 линии. Благодаря вертикальной синхронизации и задней площадки строчного гасящего импульса, линии отображаются, но информация о цвете не используется.

Программная часть

Есть две основных части кода:
- Цвет для циклов + Hsync
- Вертикальная синхронизация

3 цикла используются для создания трех различных цветов, которые отображаются на экране. Вот выдержка из кода для генерации 200 линий красного цвета. Время указано в комментариях, и вы можете легко увидеть соответствие.
#include 

//Quickly Turn VSYNC On/Off
//Or You Can Change The VSYNC Pin..
#define VSYNC_LOW    PORTD &= ~_BV(6)
#define VSYNC_HIGH   PORTD |= _BV(6)

//Quickly Turn HSYNC On/Off
//Or You Can Change The HSYNC Pin..
#define HSYNC_LOW    PORTD &= ~_BV(7)
#define HSYNC_HIGH   PORTD |= _BV(7)

//RED
#define RED_ON       PORTB |= _BV(4)
#define RED_OFF      PORTB &= ~_BV(4)

//Green
#define GREEN_ON     PORTB |= _BV(3)
#define GREEN_OFF    PORTB &= ~_BV(3)

//BLUE
#define BLUE_ON      PORTB |= _BV(2)
#define BLUE_OFF     PORTB &= ~_BV(2)

void setup() {
}

void loop() {
//Initializations
int i = 0;
cli();
DDRB = 0xFF;
DDRD = 0xFF;
  
//Loop Over-And-Over Again
  while(1){
        //Clear The i counter
      i=0;
        //VSYNC Low
      VSYNC_LOW;
        //200 Lines Of Red
      while(i < 200){
            //Red Color High
          RED_ON;
          
            //2.2uS Back Porch
          delayMicroseconds(2);  
          __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
          
            //20uS Color Data
          delayMicroseconds(20); // 1uS        
          
            //Red Color Low
          RED_OFF;  //Low
          
            //1uS Front Porch
          delayMicroseconds(1); // 1uS 
          i++;
          
            //3.2uS Horizontal Sync
          HSYNC_HIGH;  //HSYNC High
          delayMicroseconds(3);
          __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
          HSYNC_LOW;  //HSYNC Low
          
          //26.4uS Total
      }
         //Clear The i counter
      i=0;
        //VSYNC Low 
      VSYNC_LOW;
        //200 Lines Of Green
      while(i < 200){
            //Green Color High
          GREEN_ON;      
            
            //2.2uS Back Porch
          delayMicroseconds(2);
          __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
          
            //20uS Color Data
          delayMicroseconds(20); // 1uS        
          
            //Green Color Low
          GREEN_OFF;  //Low
          
            //1uS Front Porch
          delayMicroseconds(1); // 1uS 
          i++;
          
            //3.2uS Horizontal Sync
          HSYNC_HIGH;  //HSYNC High
          delayMicroseconds(3);
          __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
          HSYNC_LOW;  //HSYNC Low
          
            //26.4uS Total
      }    
  
        //Clear The i counter
      i=0;
        //VSYNC Low 
      VSYNC_LOW;  //Low
        //200 Lines Of Blue
      while(i<200){
            //Blue Color High
          BLUE_ON;  //Low      
          //2.2uS Back Porch
          delayMicroseconds(2);
          __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
          
            //20uS Color Data
          delayMicroseconds(20); // 1uS        
          
            //Blue Color Low
          BLUE_OFF;  //Low
          
            //1uS Front Porch
          delayMicroseconds(1); // 1uS 
          i++;
          
            //3.2uS Horizontal Sync
          HSYNC_HIGH;  //HSYNC High
          delayMicroseconds(3);
          __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
          HSYNC_LOW;  //HSYNC Low
          
            //26.4uS Total
      }    
        //Clear The i counter
      i=0;
        //VSYNC High
      VSYNC_HIGH;
        //4 Lines Of VSYNC   
      while(i<4){         
            //2.2uS Back Porch    
          delayMicroseconds(2);
          __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
          
            //20 uS Of Color Data
          delayMicroseconds(20);// 20uS
          
            //1uS Front Porch
          delayMicroseconds(1); // 1uS
          i++;
          
            //HSYNC for 3.2uS
          HSYNC_HIGH;  //High
          delayMicroseconds(3);
          __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
          HSYNC_LOW;  //Low  
          
            //26.4uS Total
      }
      
        //Clear The i counter
      i=0;
        //VSYNC Low
      VSYNC_LOW;
        //23 Lines Of Vertical Back Porch + 1 Line Of Front Porch
        //This is very, very flexible...Setting it to 22 Lines
      while(i < 22){
            //2.2uS Back Porch
          delayMicroseconds(2);
          __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
    
            //20uS Color Data
          delayMicroseconds(20);// 20uS
            
            //1uS Front Porch
          delayMicroseconds(1); // 1uS
          i++;
          
            //HSYNC for 3.2uS
          HSYNC_HIGH;  //High
          delayMicroseconds(3);
          __asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
          HSYNC_LOW;  //Low  
          
            //26.4uS Total
      }    
  }
}


Подробнее: https://forums.msevm.ru/index.php?topic=6289


Файлы: vga.zip

Использованы материалы: http://www.pyroelectro.com/tutorials/arduino_basic_vga/







Copyright © R9AL 2015 Все права защищены

Рейтинг@Mail.ru Яндекс цитирования