OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5491|回复: 1

TFTLCD+F103战舰参考正点原子程序修改成FSMC+DMA模式失败了

[复制链接]

2

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2020-11-28
在线时间
26 小时
发表于 2022-12-10 09:39:30 | 显示全部楼层 |阅读模式
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);
}




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2020-11-28
在线时间
26 小时
 楼主| 发表于 2022-12-10 15:43:52 | 显示全部楼层
示波器测了一下,配置DMA后 数据总线和地址线从默认上拉变成了默认下拉,有大佬帮忙分析吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 19:53

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表