打印
[活动专区]

【AT-START-F407测评】+移植俄罗斯方块

[复制链接]
1246|21
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
这次活动遇上春节放假,时间上太仓促了。一上班就开始玩板子了,在评测报告征集截止日期(明天)之前还是赶上了,哈哈。之前在另一款单片机上实现了VGA显示器上玩俄罗斯方块:https://bbs.21ic.com/icview-3050778-1-1.html
那就移植到AT-START-F407开发板上试试:





使用特权

评论回复
评论
muyichuan2012 2021-3-1 17:02 回复TA
@zhengfish :循环播放的,其实是重头又开始了。 
zhengfish 2021-3-1 16:40 回复TA
newB,为啥最后一块砖头还能上升? 
dirtwillfly 2021-2-26 10:53 回复TA
很给力 
沙发
chongdongchen|  楼主 | 2021-2-25 14:02 | 只看该作者
关键代码:
定时器配置:
void TIM3_Configuration(void)
{
//    TMR3 Channel1 = PA6
//    TMR3 Channel2 = PA7
//    TMR3 Channel3 = PB0
//    TMR3 Channel4 = PB1
   
    TMR_TimerBaseInitType  TMR_TMReBaseStructure;
    TMR_OCInitType  TMR_OCInitStructure;
   
  /* Compute the prescaler value */
  /* TMRe base configuration */
  
  TMR_TimeBaseStructInit(&TMR_TMReBaseStructure);
  TMR_TMReBaseStructure.TMR_Period = 1056 - 1;  //1056 / 40 = 26.4us  //800*600@60Hz, 26.4us
  TMR_TMReBaseStructure.TMR_DIV = (uint16_t) (SystemCoreClock / 40000000) - 1;
  TMR_TMReBaseStructure.TMR_ClockDivision = 0;
  TMR_TMReBaseStructure.TMR_CounterMode = TMR_CounterDIR_Up;

  TMR_TimeBaseInit(TMR3, &TMR_TMReBaseStructure);

  /* PWM1 Mode configuration: Channel1 */
  TMR_OCStructInit(&TMR_OCInitStructure);
  TMR_OCInitStructure.TMR_OCMode = TMR_OCMode_PWM1;
  TMR_OCInitStructure.TMR_OutputState = TMR_OutputState_Enable;
  TMR_OCInitStructure.TMR_Pulse = 128 - 1;
  TMR_OCInitStructure.TMR_OCPolarity = TMR_OCPolarity_Low;
  TMR_OC1Init(TMR3, &TMR_OCInitStructure);
  TMR_OC1PreloadConfig(TMR3, TMR_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel2 */
  TMR_OCInitStructure.TMR_OutputState = TMR_OutputState_Enable;
  TMR_OCInitStructure.TMR_Pulse = 128 - 1 + 88 - 12;    //12是修正值
  TMR_OCInitStructure.TMR_OCPolarity = TMR_OCPolarity_High;
  TMR_OC2Init(TMR3, &TMR_OCInitStructure);
  TMR_OC2PreloadConfig(TMR3, TMR_OCPreload_Enable);

//  /* PWM1 Mode configuration: Channel3 */
//  TMR_OCInitStructure.TMR_OutputState = TMR_OutputState_Enable;
//  TMR_OCInitStructure.TMR_Pulse = 128 - 1 + 88 + 800;
//  TMR_OCInitStructure.TMR_OCPolarity = TMR_OCPolarity_High;
//  TMR_OC3Init(TMR3, &TMR_OCInitStructure);
//  TMR_OC3PreloadConfig(TMR3, TMR_OCPreload_Enable);

  TMR_ARPreloadConfig(TMR3, ENABLE);

  //interrupts
  TMR_INTConfig(TMR3, TMR_INT_Overflow, ENABLE);
  TMR_INTConfig(TMR3, TMR_INT_CC2, ENABLE);
  
  /* TMR3 enable counter */
  TMR_Cmd(TMR3, ENABLE);
}
DMA配置:
void DMA_Configuration(void)
{
  DMA_InitType DMA_InitStructure;

  /* DMA1 Channel5 Config */
  DMA_Reset(DMA1_Channel5);
  DMA_DefaultInitParaConfig(&DMA_InitStructure);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)0x4000380C;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)vgaBuf;
  DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALDST;
  DMA_InitStructure.DMA_BufferSize = 50;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;
  DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;
  DMA_InitStructure.DMA_PeripheralDataWidth = DMA_PERIPHERALDATAWIDTH_BYTE;
  DMA_InitStructure.DMA_MemoryDataWidth = DMA_MEMORYDATAWIDTH_BYTE;
  //DMA_InitStructure.DMA_Mode = DMA_MODE_CIRCULAR;
  DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;
  DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH;
  DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;

  DMA_Init(DMA1_Channel5, &DMA_InitStructure);
  
  //interrupts
  DMA_INTConfig(DMA1_Channel5, DMA_INT_TC, ENABLE);

  /* DMA1 Channel5 enable */
  DMA_ChannelEnable(DMA1_Channel5, ENABLE);
}
SPI配置:
void SPI_Configuration(void)
{
  SPI_InitType SPI_InitStructure;

  /* SPI_MASTER configuration ------------------------------------------------*/
  SPI_DefaultInitParaConfig(&SPI_InitStructure);
  SPI_InitStructure.SPI_TransMode = SPI_TRANSMODE_FULLDUPLEX;
  SPI_InitStructure.SPI_Mode = SPI_MODE_MASTER;
  SPI_InitStructure.SPI_FrameSize = SPI_FRAMESIZE_8BIT;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_LOW;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1EDGE;
  SPI_InitStructure.SPI_NSSSEL = SPI_NSSSEL_SOFT;
  SPI_InitStructure.SPI_MCLKP = SPI_MCLKP_8;
  SPI_InitStructure.SPI_FirstBit = SPI_FIRSTBIT_MSB;
  SPI_InitStructure.SPI_CPOLY = 7;
  SPI_Init(SPI2, &SPI_InitStructure);
   
  SPI_I2S_DMAEnable(SPI2, SPI_I2S_DMA_TX, ENABLE);
   
  SPI_Enable(SPI2, ENABLE);
}
中断处理:
void DMA1_Channel5_IRQHandler(void)
{
    //关闭DMA
    //DMA_ChannelEnable(DMA1_Channel5, DISABLE);
    DMA1_Channel5->CHCTRL &= (uint16_t)(~DMA_CHCTRL1_CHEN);

    DMA1->ICLR = DMA1_INT_GL5 | DMA1_INT_TC5 | DMA1_INT_HT5 | DMA1_INT_ERR5;
}

void TMR3_GLOBAL_IRQHandler(void)
{
    static __IO uint32_t vga_hs = 0;
    static __IO uint32_t valid = 0;
    static u8* addr = 0;
   
    if(TMR3->STS & TMR_INT_Overflow)
    {
        vga_hs++;

        if(vga_hs >= 628)       //新的一帧,VSYNC开始
        {
            GPIOB->BRE = GPIO_Pins_1;
            vga_hs = 0;
        }
        else if(vga_hs == 4)    //VSYNC结束
        {
            GPIOB->BSRE = GPIO_Pins_1;
            addr = vgaBuf;
        }
        else if(vga_hs == 627)
        {
            valid = 0;
        }
        else if(vga_hs >= 27)   //有效区
        {
            //重新初始化DMA,准备好下一行数据
            DMA_ChannelEnable(DMA1_Channel5, DISABLE);
            
            DMA1_Channel5->CMBA = (u32)addr;
            DMA1_Channel5->TCNT = (XPix / 8);
            
            if(!(vga_hs & 1))
                addr += (XPix / 8);
            valid = 1;
        }

        TMR3->STS = (uint16_t)~TMR_INT_Overflow;
    }
    if(TMR3->STS & TMR_INT_CC2)
    {
        //启动DMA
        if(valid)
            DMA1_Channel5->CHCTRL |= DMA_CHCTRL1_CHEN;

        TMR3->STS = (uint16_t)~TMR_INT_CC2;
    }
}


主函数:
int main(void)
{
  RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_DMA1, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_TMR3 | RCC_APB1PERIPH_SPI2, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA | RCC_APB2PERIPH_GPIOB |
                         RCC_APB2PERIPH_GPIOC | RCC_APB2PERIPH_AFIO, ENABLE);
  GPIO_Configuration();
  DMA_Configuration();
  SPI_Configuration();
  TIM3_Configuration();
  AT32_Board_Init();
  NVIC_Configuration();
  
  tetris_init();
   
  while (1)
  {
    static uint32_t t_10ms = 0;
    static uint16_t led = LED1;

    Delay_ms(10);
    if(++t_10ms >= 10)
    {
      if(++led >= LED_NUM)led = LED2;
      AT32_LEDn_Toggle(led);
      t_10ms = 0;
    }

    sysTime_10ms++;

    JOYPAD_run();
    tetris_key_processing();
    tetris_run();
  }
}


使用特权

评论回复
板凳
chongdongchen|  楼主 | 2021-2-25 14:08 | 只看该作者
这对于强大的AT32F407来说,真的很轻松,之前那款显示出来还有些毛刺。现在就没有了。赞一个!!

使用特权

评论回复
地板
muyichuan2012| | 2021-2-26 09:06 | 只看该作者
这个也太强了吧  俄罗斯方块也可以移植过来。

使用特权

评论回复
5
wsnsyy| | 2021-2-26 10:24 | 只看该作者
能分享工程吗

使用特权

评论回复
6
chongdongchen|  楼主 | 2021-2-26 14:59 | 只看该作者
感谢大家支持!
@wsnsyy 你可以看一下我之前的帖子,已经开源的(https://bbs.21ic.com/icview-3050778-1-1.html)

使用特权

评论回复
7
有何不可0365| | 2021-2-28 22:33 | 只看该作者

这个也太强了吧

使用特权

评论回复
8
zhengshuai888| | 2021-3-1 07:59 | 只看该作者
哈哈,又来了。

使用特权

评论回复
9
小明的同学| | 2021-3-1 19:09 | 只看该作者
赞一个。。。

使用特权

评论回复
10
aspoke| | 2021-3-7 21:33 | 只看该作者
这个高端了。        

使用特权

评论回复
11
232321122| | 2021-3-7 21:33 | 只看该作者
有完整的代码吗   

使用特权

评论回复
12
ghuca| | 2021-3-7 21:34 | 只看该作者
VGA是怎么驱动 的呢?   

使用特权

评论回复
13
soodesyt| | 2021-3-7 21:34 | 只看该作者
AT-START-F407性能怎么样  

使用特权

评论回复
14
mnynt121| | 2021-3-7 21:34 | 只看该作者
谢谢楼主分享的。         

使用特权

评论回复
15
plsbackup| | 2021-3-7 21:34 | 只看该作者
VGA显示器这么高端呢

使用特权

评论回复
16
kmzuaz| | 2021-3-7 21:34 | 只看该作者
硬件电路怎么搭建的   

使用特权

评论回复
17
qiufengsd| | 2021-3-7 21:35 | 只看该作者
玩板子很高端呢。   

使用特权

评论回复
18
wengh2016| | 2021-3-7 21:35 | 只看该作者
跑的操作系统吗   

使用特权

评论回复
19
iyoum| | 2021-3-7 21:35 | 只看该作者
VGA的接口这么容易吗  

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

54

主题

1229

帖子

10

粉丝