硬汉嵌入式论坛

 找回密码
 立即注册
查看: 6466|回复: 5
收起左侧

[有问必答] FSMC控制LCD的问题

[复制链接]

2

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2015-7-20 03:32:50 | 显示全部楼层 |阅读模式
最近搞了一块100个脚的STM32F407VG,想要试一试用FSMC接口控制安富莱的7寸TFT LCD,我是按着V5开发板的显示屏例程改的,因为V5开发板例程用的是178脚的,所以在接线和程序上做了如下的改动:
FSMC:D0-D15不变、NOE,NWE不变
             原先PD13-FSMC_A18接LCD的RS脚,改为PD11-FSMC_A16
             原先PG12-FSMC_NE4接片选NCS,改为PD7-FSMC_NE1
             F407的NRST接LCD的NRST
             一共21根线,RA8875_INT、SPI等线没有接
所以LCD_CtrlLinesConfig()中相应的IO口配置做了下小修改

static void LCD_CtrlLinesConfig(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* 使能FSMC时钟 */
    RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);

    /* 使能 GPIO时钟 */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE, ENABLE);

    /* 设置 PD.00(D2), PD.01(D3), PD.04(NOE), PD.05(NWE), PD.08(D13), PD.09(D14),
     PD.10(D15), PD.14(D0), PD.15(D1) 为复用推挽输出 */

    GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
                                GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 |
                                GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOD, &GPIO_InitStructure);

    /* 设置 PE.07(D4), PE.08(D5), PE.09(D6), PE.10(D7), PE.11(D8), PE.12(D9), PE.13(D10),
     PE.14(D11), PE.15(D12) 为复用推挽输出 */

    GPIO_PinAFConfig(GPIOE, GPIO_PinSource4 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource5 , GPIO_AF_FSMC);

    GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource10 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource11 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource12 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource13 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource14 , GPIO_AF_FSMC);
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource15 , GPIO_AF_FSMC);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | 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_Init(GPIOE, &GPIO_InitStructure);

    /* 设置 PD.11(A16 (RS))  为复用推挽输出 */
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FSMC);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
   
    /* 设置 PD.07 (LCD/CS)) 为复用推挽输出 */
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_FSMC);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_Init(GPIOD, &GPIO_InitStructure);


LCD_FSMCConfig()这个FSMC配置函数,也贴一下

static void LCD_FSMCConfig(void)
{
    FSMC_NORSRAMInitTypeDef  init;
    FSMC_NORSRAMTimingInitTypeDef  timingWrite;
    FSMC_NORSRAMTimingInitTypeDef  timingRead;

    /*-- FSMC Configuration ------------------------------------------------------*/
    /*----------------------- SRAM Bank 4 ----------------------------------------*/
    /* FSMC_Bank1_NORSRAM4 configuration */
    /* 摄像头DMA麻点,需设置 4 0 5 2 0 0 */
    timingWrite.FSMC_AddressSetupTime = 4;
    timingWrite.FSMC_AddressHoldTime = 0;
    timingWrite.FSMC_DataSetupTime = 6;
    timingWrite.FSMC_BusTurnAroundDuration = 1;
    timingWrite.FSMC_CLKDivision = 0;
    timingWrite.FSMC_DataLatency = 0;
    timingWrite.FSMC_AccessMode = FSMC_AccessMode_A;

    timingRead.FSMC_AddressSetupTime = 4;
    timingRead.FSMC_AddressHoldTime = 0;
    timingRead.FSMC_DataSetupTime = 8;
    timingRead.FSMC_BusTurnAroundDuration = 1;
    timingRead.FSMC_CLKDivision = 0;
    timingRead.FSMC_DataLatency = 0;
    timingRead.FSMC_AccessMode = FSMC_AccessMode_A;


    /*
     LCD configured as follow:
        - Data/Address MUX = Disable
        - Memory Type = SRAM
        - Data Width = 16bit
        - Write Operation = Enable
        - Extended Mode = Enable
        - Asynchronous Wait = Disable
    */
    //init.FSMC_Bank = FSMC_Bank1_NORSRAM4;
    init.FSMC_Bank = FSMC_Bank1_NORSRAM4;
    init.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
    init.FSMC_MemoryType = FSMC_MemoryType_SRAM;
    init.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
    init.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
    init.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;    /* 注意旧库无这个成员 */
    init.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
    init.FSMC_WrapMode = FSMC_WrapMode_Disable;
    init.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
    init.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
    init.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
    init.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
    init.FSMC_WriteBurst = FSMC_WriteBurst_Disable;

    init.FSMC_ReadWriteTimingStruct = &timingRead;
    init.FSMC_WriteTimingStruct = &timingWrite;

    FSMC_NORSRAMInit(&init);

    /* - BANK 1 (of NOR/SRAM Bank 1~4) is enabled */
    FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);

这个函数原封不动没有改,里面配置的参数太多没怎么看懂,把NORSRAM4改成了NORSRAM1试了一试,没什么用,屏幕还是点不亮。。

因为100个脚的那个芯片外接8MHz晶振的,所以我把HSE_VALUE   改成了8000000。

bsp_ra8875_port.c文件中做了修改

    #define RA8875_BASE        ((uint32_t)(0x60000000 | 0x00000000))

    #define RA8875_REG        *(__IO uint16_t *)(RA8875_BASE +  (1 << (16 + 1)))    /* FSMC 16位总线模式下,FSMC_A16口线对应物理地址A17 */
    #define RA8875_RAM        *(__IO uint16_t *)(RA8875_BASE)

    #define RA8875_RAM_ADDR        RA8875_BASE
因为改用NE1,所以吧RA8875_BASE从6C000000改成了60000000,改用A16而不是用A18,所以吧RA8875_REG中的18+1改为16+1

一共改了这些东西,可是并没能把屏幕点亮- -,没有办法了,想请教一下,是FSMC配置的问题吗?
电路上的问题可能性不大,测过一遍,每个脚都接好了,屏幕插在V5主板上的时候也是好使的
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2015-7-20 08:59:10 | 显示全部楼层
看了,也没有发现什么问题,你可以参考下我们X3的板子,用的STM32F407VGT6。

另外你的分频系数改了吗,比如PLL_M  PLL_N,这个也得改。
回复

使用道具 举报

2

主题

2

回帖

2

积分

新手上路

积分
2
 楼主| 发表于 2015-7-20 14:50:51 | 显示全部楼层
分频系数后来改了,把PLL_N改成8,不过好像不是主要问题。
调试了一下,发现在执行延时函数bsp_DelayMS(150)或者FillTestData()函数时进入了HardFault_Handler硬件错误中断里去了
把延时函数改成最简单的阻塞的延时函数也会进入HardFault_Handler,是时钟配置的问题吗?没有看门狗喂狗?
/*
*********************************************************************************************************
*    函 数 名: FillTestData
*    功能说明: 填充测试数据
*    形    参: 无
*    返 回 值: 无
*********************************************************************************************************
*/
static void FillTestData(void)
{
    uint16_t i;

    for (i = 0; i < SAMPLE_COUNT; i++)
    {
        g_pDSO->CH1.AdcBuf = 2048 + (int32_t)(2000 * sin((2 * 3.14159 / (SAMPLE_COUNT / 15)) * i));/* 5个周期正弦波 */

        if ((i / (SAMPLE_COUNT / 24)) % 2)        /* 6个周期方波  */
        {
            g_pDSO->CH2.AdcBuf = 1000;
        }
        else
        {
            g_pDSO->CH2.AdcBuf = 3000;    /* 方波  */
        }
    }
}
回复

使用道具 举报

2

主题

2

回帖

2

积分

新手上路

积分
2
 楼主| 发表于 2015-7-20 15:14:55 | 显示全部楼层
上面写错了,是把PLL_M改成8。。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117586
QQ
发表于 2015-7-20 16:40:50 | 显示全部楼层
确定是该的这个宏下面的PLL_M吧,还有引脚驱动,每一个当前用到的都核对下,包括引脚相应的时钟都使能了没有。
1.png
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2019-5-2 11:15:30 | 显示全部楼层
请问你的问题当时解决了吗?我现在遇到了类似的问题……跟你改的内容差不多
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-17 12:48 , Processed in 0.051894 second(s), 33 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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