论坛风格切换切换到宽版
  • 8519阅读
  • 6回复

STM32做VGA接口! [复制链接]

上一主题 下一主题
离线代洪波
 
发帖
4809
只看楼主 倒序阅读 0楼 发表于: 2011-04-25
最近需要用stm32做vga接口。但是我查了下,最慢的扫描速率是60hz场同步,37k行同步,行同步3us,正程扫描时间25us,貌似要输出320个点的数据,stm32跑不过来,大家有没有更好的编码方案?或者合适的便宜的处理器?
离线XLDZZ
发帖
443
只看该作者 1楼 发表于: 2011-04-25
方案有很多 有专门的asic的
但是建议用fpga自己写一个 其实很简单的

但是要用高速da 来输出信号 stm32的估计速度不够
以下是别人写的fpga 驱动vga的verilog

占用就几十个le单元 用cpld也可以写出来的
//==========================================================================
//           640*480@60hz.
//==========================================================================

`define ud #1

`define pixel_max 16'h320 //800
`define line_max 16'h20d   //525

`define hs_time 16'h60   //96
`define vs_time 16'h2   //2

module vga_ctl
     (
     //input ports.
     sysclk,
     rst_b,
     key_b,

     //output ports.
     red,
     green,
     blue,
     vsync,
     hsync
     );

//==========================================================================
//input and output declaration
//==========================================================================

input            sysclk;
input            rst_b;
input            key_b;

output      [1:0]      red;
output      [2:0]      green;
output      [2:0]      blue;
output            vsync;
output            hsync;

//==========================================================================
//wire and reg declaration
//==========================================================================

wire            sysclk;
wire            rst_b;
wire            key_b;

reg      [1:0]      red;
reg      [2:0]      green;
reg      [2:0]      blue;
reg            vsync;
reg            hsync;

//==========================================================================
//wire and reg in the module.
//==========================================================================

reg      [15:0]      pixel_cnt;
reg      [15:0]      line_cnt;

reg      [15:0]      pixel_cnt_n;
reg      [15:0]      line_cnt_n;

reg            vsync_n;
reg            hsync_n;

//==========================================================================
//logic
//==========================================================================

//==========================================================================
//vertical and horizontal sync control
//==========================================================================

//pixel number in one line counter.
always @ (posedge sysclk or negedge rst_b)
begin
if(!rst_b)
  pixel_cnt      <= `ud 16'h0;
else
  pixel_cnt      <= `ud pixel_cnt_n;
end

always @ (*)
begin
if(pixel_cnt == `pixel_max)
  pixel_cnt_n = 16'h0;
else
  pixel_cnt_n = pixel_cnt + 16'h1;
end

//line number counter.
always @ (posedge sysclk or negedge rst_b)
begin
if(!rst_b)
  line_cnt      <= `ud 16'h0;
else
  line_cnt      <= `ud line_cnt_n;
end

always @ (*)
begin
if((line_cnt == `line_max) && (pixel_cnt == `pixel_max))
  line_cnt_n       = 16'h0;
else if((line_cnt != `line_max) && (pixel_cnt == `pixel_max))
  line_cnt_n       = line_cnt + 16'h1;
else
  line_cnt_n   = line_cnt;
end

//hsync control, before enable pixel, sync first.
always @ (posedge sysclk or negedge rst_b)
begin
if(!rst_b)
  hsync      <= `ud 1'h0;
else
  hsync      <= `ud hsync_n;
end

always @ (*)
begin
if(pixel_cnt == `pixel_max)
  hsync_n       = 1'h0;
else if(pixel_cnt == `hs_time)
  hsync_n     = 1'h1;
else
  hsync_n     = hsync;
end


//vsync control, before enable line, sync first.
always @ (posedge sysclk or negedge rst_b)
begin
if(!rst_b)
  vsync      <= `ud 1'h0;
else
  vsync      <= `ud vsync_n;
end

always @ (*)
begin
if(line_cnt == `line_max)
  vsync_n       = 1'h0;
else if(line_cnt == `vs_time)
  vsync_n     = 1'h1;
else
  vsync_n     = vsync;
end

//==========================================================================
//rgb output control
//==========================================================================

always @ (*)
begin
case(line_cnt[8:7])
     2'h0      :      begin
                  red   = 2'h3;
                   green = 3'h0;
                 blue = 3'h0;
                 end

     2'h1      :      begin
                 red   = 2'h0;
                   green = 3'h7;
                 blue = 3'h0;
                 end

     2'h2      :      begin
                   red   = 2'h0;
                   green = 3'h0;
                 blue = 3'h7;
                 end

     2'h3      :      begin
                   red   = 2'h3;
                   green = 3'h7;
                 blue = 3'h7;
                 end

     default   :      begin
                   red   = 2'h0;
                   green = 3'h0;
                 blue = 3'h0;
                 end
  endcase
end



endmodule
离线代洪波
发帖
4809
只看该作者 2楼 发表于: 2011-04-25
'
方案有很多 有专门的asic的
但是建议用fpga自己写一个 其实很简单的
但是要用高速da 来输出信号 stm32的估计速度不够
以下是别人写的fpga 驱动vga的verilog
占用就几十个le单元 用cpld也可以写出来的
//==========================================================================
//           640*480@60hz.
//==========================================================================
`define ud #1
`define pixel_max 16'h320 //800
`define line_max 16'h20d   //525
`define hs_time 16'h60   //96
`define vs_time 16'h2   //2
module vga_ctl
     (
     //input ports.
     sysclk,
     rst_b,
     key_b,
     //output ports.
     red,
     green,
     blue,
     vsync,
     hsync
     );
//==========================================================================
//input and output declaration
//==========================================================================
input            sysclk;
input            rst_b;
input            key_b;
output      [1:0]      red;
output      [2:0]      green;
output      [2:0]      blue;
output            vsync;
output            hsync;
//==========================================================================
//wire and reg declaration
//==========================================================================
wire            sysclk;
wire            rst_b;
wire            key_b;
reg      [1:0]      red;
reg      [2:0]      green;
reg      [2:0]      blue;
reg            vsync;
reg            hsync;
//==========================================================================
//wire and reg in the module.
//==========================================================================
reg      [15:0]      pixel_cnt;
reg      [15:0]      line_cnt;
reg      [15:0]      pixel_cnt_n;
reg      [15:0]      line_cnt_n;
reg            vsync_n;
reg            hsync_n;
//==========================================================================
//logic
//==========================================================================
//==========================================================================
//vertical and horizontal sync control
//==========================================================================
//pixel number in one line counter.
always @ (posedge sysclk or negedge rst_b)
begin
if(!rst_b)
  pixel_cnt      <= `ud 16'h0;
else
  pixel_cnt      <= `ud pixel_cnt_n;
end
always @ (*)
begin
if(pixel_cnt == `pixel_max)
  pixel_cnt_n = 16'h0;
else
  pixel_cnt_n = pixel_cnt + 16'h1;
end
//line number counter.
always @ (posedge sysclk or negedge rst_b)
begin
if(!rst_b)
  line_cnt      <= `ud 16'h0;
else
  line_cnt      <= `ud line_cnt_n;
end
always @ (*)
begin
if((line_cnt == `line_max) && (pixel_cnt == `pixel_max))
  line_cnt_n       = 16'h0;
else if((line_cnt != `line_max) && (pixel_cnt == `pixel_max))
  line_cnt_n       = line_cnt + 16'h1;
else
  line_cnt_n   = line_cnt;
end
//hsync control, before enable pixel, sync first.
always @ (posedge sysclk or negedge rst_b)
begin
if(!rst_b)
  hsync      <= `ud 1'h0;
else
  hsync      <= `ud hsync_n;
end
always @ (*)
begin
if(pixel_cnt == `pixel_max)
  hsync_n       = 1'h0;
else if(pixel_cnt == `hs_time)
  hsync_n     = 1'h1;
else
  hsync_n     = hsync;
end
//vsync control, before enable line, sync first.
always @ (posedge sysclk or negedge rst_b)
begin
if(!rst_b)
  vsync      <= `ud 1'h0;
else
  vsync      <= `ud vsync_n;
end
always @ (*)
begin
if(line_cnt == `line_max)
  vsync_n       = 1'h0;
else if(line_cnt == `vs_time)
  vsync_n     = 1'h1;
else
  vsync_n     = vsync;
end
//==========================================================================
//rgb output control
//==========================================================================
always @ (*)
begin
case(line_cnt[8:7])
     2'h0      :      begin
                  red   = 2'h3;
                   green = 3'h0;
                 blue = 3'h0;
                 end
     2'h1      :      begin
                 red   = 2'h0;
                   green = 3'h7;
                 blue = 3'h0;
                 end
     2'h2      :      begin
                   red   = 2'h0;
                   green = 3'h0;
                 blue = 3'h7;
                 end
     2'h3      :      begin
                   red   = 2'h3;
                   green = 3'h7;
                 blue = 3'h7;
                 end
     default   :      begin
                   red   = 2'h0;
                   green = 3'h0;
                 blue = 3'h0;
                 end
  endcase
end
endmodule
'
成本多少钱?输出有360*240就可以了。要不你帮我做一个?我付开发费?
离线bd4vc
发帖
172
只看该作者 3楼 发表于: 2011-04-25
cpu做vga速度不行,fpga或者cpld都行 时序不是很复杂 fpga加上一片sram和一片视频专用的dac,如果不需要很多颜色和灰度 也可以不用dac rgb分别用fpga管脚驱动也行 8种彩色,成本的话什么都算上估计得在100-200之间要看具体要求 如果对fpga开发不熟悉 可以在网上搜一下类似的产品 也不是很贵
  另外现在有很多cpu自带lcd控制器,用lcd的数据线直接驱动dac也是可以产生vga信号的,当然同步信号也得加上去
离线BI7LNQ
发帖
599
只看该作者 4楼 发表于: 2011-04-26
lz需要显示图片么。
我看了一下单片机模拟vga时序还是蛮多例子的

http://tinyvga.com/pic-vga

http://tinyvga.com/avr-sdram-vga 这个连sdram一起模拟了
发帖
689
只看该作者 5楼 发表于: 2011-04-26
楼主和二楼都是高手。
离线代洪波
发帖
4809
只看该作者 6楼 发表于: 2011-04-28
谢谢大家,已经买了cpld的开发板,不过短时间内估计做不出来。