用STM32F030直连VGA做游戏机

2019-12-21 12:10发布

本帖最后由 love_ourdev 于 2016-11-10 21:55 编辑

看了坛里的高手用51做俄罗斯方块,我也萌生了做一个游戏机的念头,把一边闲着的VGA显示器用起来。
我不求高手的挑战极限,我要留足资源多做几个游戏;而且还要尽可能方便的开发游戏,当然又不能太浪费。所以我用了STM32F030C8,
8KB RAM,64KB ROM,目前搭好了游戏框架,做出了演示。软件上支持双显存和但显存随意切换,简单适应多种显示分辨率,
软件耗费如下:

  1.   6 860 bytes of readonly  code memory
  2.      84 bytes of readonly  data memory
  3.   6 188 bytes of readwrite data memory
复制代码

优酷视频:
http://v.youku.com/v_show/id_XMTgxNDExNzE4OA==.html

电路连接实物图:
IMG_20161110_213241.jpg (357.77 KB, 下载次数: 0) 下载附件 电路链接图 2016-11-10 21:51 上传

演示的代码如下:

  1. #include "usrinc.h"
  2. #include <string.h>

  3. static const uint32_t sprite1[8] = {
  4.   0x66666666,
  5.   0x68111186,
  6.   0x61822816,
  7.   0x61288216,
  8.   0x61288216,
  9.   0x61822816,
  10.   0x68111186,
  11.   0x66666666,
  12. };

  13. void UserEntryInit(void)
  14. {
  15.   HWU_BoardLedInit();
  16.   HWU_VGASetup(&displayer640x480);
  17.   GE2D_ClearScreen();
  18.   GE2D_SwapBuffer();
  19.   GE2D_ClearScreen();
  20. }

  21. void UserEntryLoop(void)
  22. {
  23.   uint32_t tick = 0;
  24.   uint32_t angle;
  25.   GUI_RECT rect;
  26.   int xDiff, yDiff;
  27.   
  28.   rect.x0 = 0;
  29.   rect.y0 = 0;
  30.   rect.x1 = GE2D_X_SIZE-1;
  31.   rect.y1 = GE2D_Y_SIZE-1;
  32.   
  33.   while(1)
  34.   {
  35.     HWU_WaitVSync();
  36.     GE2D_SwapBuffer();
  37.    
  38.     GE2D_ClearScreen();

  39.     GE2D_SetForeColor(GUI_WHITE);
  40.     GE2D_DrawRect(&rect);
  41.    
  42.     GE2D_SetForeColor(GUI_YELLOW);
  43.     F8x8_DispString(4, 2, "STM32F0");
  44.    
  45.     GE2D_SetForeColor(GUI_RED);
  46.     GE2D_DrawHLine(2, 12, 2+(tick%60));
  47.     GE2D_DrawHLine(61-(tick%60), 14, 61);
  48.     GE2D_DrawBitmap4((tick%60)-4, 13-4, sprite1, 0x00080008);
  49.    
  50.     GE2D_SetForeColor(GUI_BLUE);
  51.     GE2D_DrawCircle(32, 48, 24);
  52.    
  53.     GE2D_SetForeColor(GUI_BLUE);
  54.     angle = tick << 3;
  55.     yDiff = 25*(util_sin_fixed28(angle)/65536)/4096;
  56.     xDiff = 25*(util_cos_fixed28(angle)/65536)/4096;
  57.     GE2D_DrawLine(32, 48, 32+xDiff, 48+yDiff);
  58.     yDiff = 25*(util_sin_fixed28(angle+340)/65536)/4096;
  59.     xDiff = 25*(util_cos_fixed28(angle+340)/65536)/4096;
  60.     GE2D_DrawLine(32, 48, 32+xDiff, 48+yDiff);
  61.     yDiff = 25*(util_sin_fixed28(angle-340)/65536)/4096;
  62.     xDiff = 25*(util_cos_fixed28(angle-340)/65536)/4096;
  63.     GE2D_DrawLine(32, 48, 32+xDiff, 48+yDiff);
  64.    
  65.     GE2D_DrawBitmap4(32-4+xDiff, 48-4+yDiff, sprite1, 0x00080008);
  66.    
  67.     HWU_BoardLedCtrl(tick>>3);
  68.     tick++;
  69.   }
  70. }

复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
65条回答
love_ourdev
2019-12-23 00:35
yuyu87 发表于 2016-11-10 23:17
强,速度够么?分辨率多少?

输出的VGA时序上,可以输出各种分辨率的,如1024*768,800*600之类的,更高也行,只是不能超过单片机主频48MHZ的精度。
不管输出多大分辨率,我的逻辑分辨率是不变的。比方说,实际VGA时序分辨率640*480时,我输出逻辑80行,那么每个逻辑行我输出6次,也即6个扫描行。
横向分辨率,其实由单片机的性能决定。每个扫描行,我能用LDR指令和STR指令几次,就能输出几个像素。比如一个扫描行通常是20几微妙,那么20*48=960个时钟,这几个时钟也执行不了几个指令啊。

一周热门 更多>