初级会员
- 积分
- 50
- 金钱
- 50
- 注册时间
- 2020-11-28
- 在线时间
- 26 小时
|
10金钱
本帖最后由 Longmanpa 于 2022-12-10 09:42 编辑
想用FSMC+DMA驱动3.5寸lcd屏,一直没有效果,帮我看看是不是初始化哪里有错,现象是调用lcd_clear没有效果;单独使用FSMC,不用DMA的话有效果
1.初始化uint8_t lcd_init(void)
{
LCD_BL_OFF();
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef ReadWriteTimingInitStructure;
FSMC_NORSRAMTimingInitTypeDef WriteTimingInitStructure;
// NVIC_InitTypeDef NVIC_InitStructure;
DMA_DeInit(DMA1_Channel1);
FSMC_NORSRAMDeInit(FSMC_Bank1_NORSRAM4);
// 开启外设时钟
RCC_AHBPeriphClockCmd(RCC_AHBENR_FSMCEN, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOG, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// LCD 背光控制BC
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// FSMC D0,D1,D2,D3,D13,D14,D15
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15 | GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
// FSMC D4,D5,D6,D7,D8,D9,D10,D11,D12
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
// FSMC NE4 片选4 LCD-CS
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOG, &GPIO_InitStructure);
// FSMC NOE 读命令 LDC-RD;FSMC NOW 写命令 LCD-WR
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
// FSMC A10 地址10 LDC-RS 1-读写数据 0-读写命令
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOG, &GPIO_InitStructure);
// 读时序设置
ReadWriteTimingInitStructure.FSMC_AddressSetupTime = 0x01; // 地址建立时间
ReadWriteTimingInitStructure.FSMC_AddressHoldTime = 0x00; // 地址保持时间
ReadWriteTimingInitStructure.FSMC_DataSetupTime = 0x01; // 数据建立时间
ReadWriteTimingInitStructure.FSMC_BusTurnAroundDuration = 0x00; // 总线转换周期,在NOR FLASH中,数据线和地址线可以分时复用
ReadWriteTimingInitStructure.FSMC_CLKDivision = 0x00; // 设置时钟分频,仅用于同步时钟
ReadWriteTimingInitStructure.FSMC_DataLatency = 0x00; // 数据保持时间,仅用于同步NOR FLASH的存储器
ReadWriteTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_A; // 存储器访问模式,使用模式A
// 写时序设置
WriteTimingInitStructure.FSMC_AddressSetupTime = 0x00; // 地址建立时间
WriteTimingInitStructure.FSMC_AddressHoldTime = 0x00; // 地址保持时间
WriteTimingInitStructure.FSMC_DataSetupTime = 0x01; // 数据保持时间
WriteTimingInitStructure.FSMC_BusTurnAroundDuration = 0x00; // 总线转换周期,在NOR FLASH中,数据线和地址线可以分时复用
WriteTimingInitStructure.FSMC_CLKDivision = 0x00; // 设置时钟分频,仅用于同步时钟
WriteTimingInitStructure.FSMC_DataLatency = 0x00; // 数据保持时间,仅用于同步NOR FLASH的存储器
WriteTimingInitStructure.FSMC_AccessMode = FSMC_AccessMode_A; // 存储器访问模式,使用模式A
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4; // 使用bank1 norsram4
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; // 数据地址复用
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; // SRAM
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; // 16位数据宽度
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; // 突发模式,只能适用于同步sram
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; // 是否使能在同步传输时使用的等待信号
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; // 等待信号的有效电平,要求等待时使用高或低
FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; // 仅在突发模式下有效,是否支持非对齐的AHB突发操作分割成2次线性操作
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; //仅在突发模式下有效.决定存储器在等待状态之前的\
一个数据周期有效还是在等待状态期间有效
FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; // 是否使能写操作
FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; // 在突发模式下,是否允许通过NWAIT信号插入等待状态
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable; //是否使用扩展模式,在扩展模式下,对存储器的读写时序可以分开配置,读时序使用\
FSMC_BCR寄存器,写时序使用FSMC_BWTR寄存器的配置,即FSMC_WriteTimingStruct\
结构体;非拓展模式下,读写的时序都是用FSMC_BCR寄存器中的配置
FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; // 是否使能写突发模式
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &ReadWriteTimingInitStructure; // 指针,读写时序的参数配置
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &WriteTimingInitStructure; // 指针,写时序的参数配置,拓展模式下有效
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);
// 写FSMC数据
DMA_InitStructure.DMA_PeripheralBaseAddr = 0; // 写到FSMC的数据,数据来源
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)LCD->LCD_RAM;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 0;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
// DMA_ClearITPendingBit(DMA1_IT_TC1);
// DMA_ClearITPendingBit(DMA1_IT_TE1);
// DMA_ClearFlag(DMA1_FLAG_TC1);
// DMA_ClearFlag(DMA1_FLAG_TE1);
// DMA_ITConfig(DMA1_Channel1,DMA_IT_TE,ENABLE);
// DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
//DMA_Cmd(DMA1_Channel1, ENABLE);
// NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure);
delay_ms(50);
uint16_t id[4 = {0};
lcd_read_nparameters(0xD4, id, 4);
if (((*(id + 2) << 8) | (*(id + 3))) == 0x5310)
{
lcd_ram_init();
LCD_BL_ON();
LCD_35310.lcd_id = 0x5310;
LCD_35310.dir = 1;
LCD_35310.height = 480;
LCD_35310.width = 320;
LCD_35310.wramcmd = 0x2C;
LCD_35310.setxcmd = 0x2A;
LCD_35310.setycmd = 0x2B;
LCD_35310.totalpoint = 480*320;
LCD_Clear(&black);
printf("lcd id:0x5310\n");
return 1;
}
else
{
return 0;
}
}
2.清屏程序
void LCD_Clear(uint16_t *color)
{
lcd_stcursor(0x00, 0x0000); //设置光标位置
while(DMA1_Channel1->CNDTR != 0);
DMA_Cmd(DMA1_Channel1,DISABLE);
while(DMA1_Channel1->CCR & DMA_CCR1_EN == DMA_CCR1_EN);
DMA1_Channel1->CPAR = (uint32_t)color;
DMA1_Channel1->CNDTR = LCD_35310.totalpoint;
DMA1_Channel1->CCR &= (~DMA_CCR1_PINC);
LCD_WR_REG(LCD_35310.wramcmd);
DMA_Cmd(DMA1_Channel1,ENABLE);
}
|
|