关键代码:
定时器配置:
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();
}
}
|
@zhengfish :循环播放的,其实是重头又开始了。
newB,为啥最后一块砖头还能上升?
很给力