【AT-START-F407测评】+移植俄罗斯方块
这次活动遇上春节放假,时间上太仓促了。一上班就开始玩板子了,在评测报告征集截止日期(明天)之前还是赶上了,哈哈。之前在另一款单片机上实现了VGA显示器上玩俄罗斯方块:https://bbs.21ic.com/icview-3050778-1-1.html那就移植到AT-START-F407开发板上试试:
关键代码:
定时器配置:
void TIM3_Configuration(void)
{
// TMR3 Channel1 = PA6
// TMR3 Channel2 = PA7
// TMR3 Channel3 = PB0
// TMR3 Channel4 = PB1
TMR_TimerBaseInitTypeTMR_TMReBaseStructure;
TMR_OCInitTypeTMR_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();
}
}
这对于强大的AT32F407来说,真的很轻松,之前那款显示出来还有些毛刺。现在就没有了。赞一个!! 这个也太强了吧俄罗斯方块也可以移植过来。 能分享工程吗 感谢大家支持!
@wsnsyy 你可以看一下我之前的帖子,已经开源的(https://bbs.21ic.com/icview-3050778-1-1.html)
这个也太强了吧 哈哈,又来了。 赞一个。。。 这个高端了。 有完整的代码吗 VGA是怎么驱动 的呢? AT-START-F407性能怎么样 谢谢楼主分享的。 VGA显示器这么高端呢 硬件电路怎么搭建的 玩板子很高端呢。 跑的操作系统吗 VGA的接口这么容易吗
页:
[1]