新手入门
- 积分
- 15
- 金钱
- 15
- 注册时间
- 2018-5-17
- 在线时间
- 2 小时
|
发表于 2018-5-17 10:00:26
|
显示全部楼层
我是用 W25Q16 2M flash 存储的,使用spi1 dma 直接写屏 LCD端口。需要注意,DMA 外设 为spi ,内存为lcd 端口。外设到内存模式。我lcd 是16bit模式,所以 外设spi设定为16bit 模式,内存也设定为16bit 模式,这是第一,第二 spi 也要设定为16bit模式,8bit 模式无法显示。
void dma_spi1_to_lcd(u32 addr,u16 xs,u16 ys,u16 len,u16 height)
{
u16 tt=0xFFFF;
LOCK_SPI();
spi_cs_flash();
block_spi_send(0x0b);
block_spi_send((addr&0xFF0000)>>16); // ADR1
block_spi_send((addr&0xFF00)>>8); // ADR2
block_spi_send(addr&0xFF); // ADR3
block_spi_send(0xFF);
SPI1->CR1&= (~SPI_CR1_SPE);
SPI1->CR1|=((1<<11)|(0<<7));// DFF 位 16bit 模式 SPI 调整为16bit 模式应对lcd ·16bit; 高位先
SPI1->CR2 |=((SPI_I2S_DMAReq_Tx|SPI_I2S_DMAReq_Rx)); // dma open RX TX
// SPI TX DMA
DMA1_Channel3->CCR&= (uint16_t)(~DMA_CCR1_EN); //关闭DMA
DMA1_Channel3->CCR&=~(DMA_MemoryInc_Enable); // MeM 地址 不增加 读取时 TX 随便发送
DMA1_Channel3->CMAR=(u32) &tt; // 内存地址 随便个内容
DMA1_Channel3->CCR=(DMA1_Channel3->CCR&(u32)(~(0b1111<<8)))|(0b0101<<8);
// SPI RX
DMA1_Channel2->CCR&= (uint16_t)(~DMA_CCR1_EN); //关闭DMA
DMA1_Channel2->CCR&=~(DMA_MemoryInc_Enable); // MeM 地址 不动
DMA1_Channel2->CCR=(DMA1_Channel2->CCR& (u32)(~(15<<8)))|(0b0101<<8); // MeM 16bit 直接写入 LCD 时 为16bit;
DMA1_Channel2->CMAR=(u32) &LCD_RAM; // 内存地址
SPI1->SR&=~(SPI_I2S_FLAG_RXNE|SPI_I2S_FLAG_TXE);
lock_lcd();
LCD_SET_WINDOW(xs,ys,xs+len-1,ys+height-1);
LCD_ENTER_RAM();
u32 igm_size=len *height;
while (len)
{
//
if(len<65535)
{
DMA1_Channel3->CNDTR=igm_size;
DMA1_Channel2->CNDTR=igm_size;
len=0;
}
else
{
DMA1_Channel3->CNDTR=65535;
DMA1_Channel2->CNDTR=65535;
igm_size-=65535;
}
DMA1_Channel2->CCR|= (uint16_t)(DMA_CCR1_EN); //open DMA
DMA1_Channel3->CCR|= (uint16_t)(DMA_CCR1_EN); //open DMA
SPI1->CR1|= (SPI_CR1_SPE); //开启spi
CoPendSem(DMA1_TC2_EVENT,0); //等待spi 完成,无os 可以死等。
SPI1->CR1&= ~(SPI_CR1_SPE); //close spi
DMA1_Channel2->CCR&= (uint16_t)~(DMA_CCR1_EN); //open DMA
DMA1_Channel3->CCR&= (uint16_t)~(DMA_CCR1_EN); //open DMA
DMA1_Channel2->CMAR+=65535; // 内存地址
};
spi_dcs_flash();
DMA1_Channel2->CCR&= (uint16_t)(~DMA_CCR1_EN); //关闭DMA
DMA1_Channel2->CCR=(DMA1_Channel2->CCR& (u32)(~(15<<8)))|(0b0000<<8);
DMA1_Channel3->CCR&= (uint16_t)(~DMA_CCR1_EN); //关闭DMA
DMA1_Channel3->CCR=(DMA1_Channel3->CCR& (u32)(~(15<<8)))|(0b0000<<8);
SPI1->CR1&= (~SPI_CR1_SPE);
SPI1->CR1&=(~((1<<11)|(1<<7)));
LCD_DESET_WINDOW();
unlock_lcd();
UNLOCK_SPI();
}
void DMA1_Channel2_IRQHandler(void)
{
CoEnterISR();
// if(DMA_GetITStatus(DMA1_IT_TC2)==SET)
if (DMA1->ISR&DMA1_IT_TC2)
{
//DMA_ClearITPendingBit(DMA1_IT_TC2);
DMA1->IFCR=DMA1_IT_TC2;
isr_PostSem(DMA1_TC2_EVENT);// 传输完成
// SPI_STATE=SPI_IN_IDLE;
}
CoExitISR();
} |
|