灵动微MM32的FSMC接口驱动TFT_LCD屏幕

本文详细介绍了FSMC(Flexible Static Memory Controller)存储区的配置,包括BANK1的基地址和子bank的寻址方式,强调了HADDR[27:26]在选择不同区的作用。同时,提供了硬件接口初始化的代码示例,涉及GPIO端口配置和FSMC外设初始化步骤,以及LCD读写操作的实现。内容涵盖了地址线、数据宽度、时序参数和控制信号等方面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

FSMC存储区域说明(挂载在AHB3总线)

在这里插入图片描述

BANK1的基地址是0x60000000,不同的子bank地址不同,通过HADDR[27:26]这两位的值确定。

HADDR[27:26]BANK SELECT(可挂载4个设备)
00 (0x0)BANK1-NOR/PSARM [NE1]
01 (0x1)BANK1-NOR/PSARM [NE2]
10 (0x2)BANK1-NOR/PSARM [NE3]
11 (0x3)BANK1-NOR/PSARM [NE4]
HADDR27:262524:0

Bank1的256M字节空间由 28 根地址线(HADDR[27:0])寻址(注意:这里的HADDR是内部AHB的地址线,它的地址是按字节进行“编号”的)。
这里HADDR[25:0]来自外部存储器地址FSMC_A[25:0],而HADDR[27:26]对4个区进行寻址
注意:DATA长度为16位情况下,由地址线FSMC_A[24:0]决定)

Exp: 若我们选择了第四个,这两位是11,所以子bank的基地址是:0x60000000+(0x3<<23)=0x6C000000。注:FSMC_A[23]作为 RS 控制信号

若要写指令,RS =0(根据实际外接设备的时序标准)

当 数据宽度 设置为 16bit 时,向地址(FSMC_BANK1_BASE+(0x0«23))写入命令CMD,则 FSMC_A[23]作为 RS 控制信号;
当 数据宽度 设置为 8bit 时,向地址(FSMC_BANK1_BASE+(0x0«23)) 写入命令CMD,则 FSMC_A[22]作为 RS 控制信号。

若要写数据,RS =1(根据实际外接设备的时序标准)

当 数据宽度 设置为 16bit 时,向地址(FSMC_BANK1_BASE+(0x1«23))写入数据DATA,则 FSMC_A[23]作为 RS 控制信号
当 数据宽度 设置为 8bit 时,向地址(FSMC_BANK1_BASE+(0x1«23))写入数据DATA, 则 FSMC_A[22]作为 RS 控制信号。

#define FSM_BANK_PSRAM_ADDR ((unsigned int)0x60000000) //BANK1的首地址

.硬件接口初始化

/*硬件接口*/
void mm32_fsmc_gpio_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOD, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOE, ENABLE);  
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//AF12--FSMC复用
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_12);//PD4-FSMC_NOE [nRD]	
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_12);//PD5-FSMC_NWE [nWR]
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_12);//PD7-FSMC_NE1 [nCS] 即挂载在BANK1上
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_12);//PD13-FSMC_A18[R/S] -->RS接到了A18线
    
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_12);//PD14-FSMC_D00
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_12);//PD15-FSMC_D01
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_12);//PD0-FSMC_D02
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_12);//PD1-FSMC_D03
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource7, GPIO_AF_12);//PE7-FSMC_D04
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_12);//PE8-FSMC_D05
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_12);//PE9-FSMC_D06
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_12);//PE10-FSMC_D07
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_12);//PE11-FSMC_D08
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_12);//PE12-FSMC_D09
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_12);//PE13-FSMC_D10
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_12);//PE14-FSMC_D11
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource15, GPIO_AF_12);//PE15-FSMC_D12
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_12);//PD8-FSMC_D13
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_12);//PD9-FSMC_D14
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_12);//PD10-FSMC_D15    
//FSMC
    GPIO_InitStructure.GPIO_Pin     =  GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4\
                                       |GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_8\
                                       |GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_13\
                                       |GPIO_Pin_14|GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
    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_Speed   = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode    = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOE, &GPIO_InitStructure);
}
/*
**FSMC外设初始化
*/
void mm32_fsmc_init(void)
{
    FSMC_InitTypeDef                FSMC_InitStructure;
    FSMC_NORSRAM_Bank_InitTypeDef   FSMC_BankInitStructure;
    
    RCC_AHB3PeriphClockCmd(RCC_AHB3ENR_FSMC, ENABLE);
//	FSMC_NORSRAM_BankStructInit(&FSMC_BankInitStructure);
//  FSMC_NORSRAMStructInit(&FSMC_InitStructure);
//5.95ns@168MHz
//10.4ns@96MHz
/*
**SM_READ_PIPE:读数据延迟周期数,
**即从 SRAM 读数据输出端到FSMC 内部读数据端之间的寄存器数,默认为 0。
*/		
    FSMC_BankInitStructure.FSMC_SMReadPipe    = 0;//数据延迟
/*READY_MODE:选择是否采用外部设备 FSMC_NWAIT 信号。
**0:不采用外部 FSMC_NWAIT 信号,而采用内部相关信号;
**1:采用外部设备 FSMC_NWAIT 信号。
*/
    FSMC_BankInitStructure.FSMC_ReadyMode     = 0;//0: Internal FSMC 1: External DEVICE (ie from FSMC_NWAIT)
/*
**t_wp:写操作周期,取值范围 0~63,对应写脉冲宽度 1~64 个时钟周期
*/		
    FSMC_BankInitStructure.FSMC_WritePeriod   = 0x8;//写周期(OMA=66ns)	
/*
**t_rc 读操作周期,取值范围 2~63,对应读操作周期 1~62 个时钟周期
*/
    FSMC_BankInitStructure.FSMC_ReadPeriod    = 0x8;//读周期(OMA=160ns)   
/*
**t_wr:写操作时地址的保持时间,取值范围 0~3,对应写操作时地址的保持时间0~3 个时钟周期
*/	
    FSMC_BankInitStructure.FSMC_WriteHoldTime = 0x02;//写保持时间设置(OMA=10ns)
/*
**t_as:写操作时地址的建立时间,取值范围 0~3,对应写操作时地址的建立时间0~3 个时钟周期
*/		
    FSMC_BankInitStructure.FSMC_AddrSetTime   = 0x02;//地址建立时间设置(OMA=0ns)
/*
**存储器数据总线位宽设置(与寄存器 SMTMGR_SETx 设置的时序相匹配)
*/		
    FSMC_BankInitStructure.FSMC_DataWidth     = FSMC_DataWidth_16bits;
    FSMC_NORSRAM_Bank_Init(&FSMC_BankInitStructure, FSMC_NORSRAM_BANK0);
/*
**SYSCFG 配置寄存器(SYSCFG_CFGR)
**[30:29] 
**FSMC 模式选择
**01:兼容 8080 协议接口
**00:兼容 NOR FLASH 接口
**1x:保留
*/
    FSMC_InitStructure.FSMC_Mode            = FSMC_Mode_8080;
/*
**REG_SELECT[2:0]:时序参数配置寄存器组选择
**000:选择 SMTMGR_SET0 寄存器来配置 BANK1 传输的时序参数
**001:选择 SMTMGR_SET1 寄存器来配置 BANK1 传输的时序参数
**010:选择 SMTMGR_SET2 寄存器来配置 BANK1 传输的时序参数
**其它:保留
*/
    FSMC_InitStructure.FSMC_TimingRegSelect = FSMC_TimingRegSelect_0;
/*
**MEM_SIZE[4:0]:外接设备容量
**00000:未连接任何设备
**00001: 64KB
**00010 :128KB
**00011:256KB
**00100:512KB
**00101:1MB
**00110:2MB
**00111:4MB
**01000:8MB
**01001:16MB
**01010:32MB
**01011:64MB
**其它:保留
*/		
    FSMC_InitStructure.FSMC_MemSize         = FSMC_MemSize_64MB;
/*
**MEM_TYPE[2:0]:外接设备类型
**001:SRAM
**010:NOR FLASH
**其他:保留
*/		
    FSMC_InitStructure.FSMC_MemType         = FSMC_MemType_NorSRAM;
/*
**FC_ODATAEN 
**FSMC 地址数据复用引脚只能作为数据使用
**1:仅作为数据引脚使用
**0:允许作为数据地址使用
*/		
    FSMC_InitStructure.FSMC_AddrDataMode    = FSMC_AddrDataMUX; 
    FSMC_NORSRAMInit(&FSMC_InitStructure);			
}

.LCD读写操作

/*
**当RS=0时,表示读写REG
**当RS=1时,表示读写RAM
*/
/*
**写指令
*/
/*加__inline为了优化代码,可以不需要 */
__inline void lcd_write_index(void *arg,unsigned short int index)
{
	(*(volatile unsigned short int *)FSM_BANK_PSRAM_ADDR)=index; 
}
/*
**写数据
*/
__inline void lcd_write_data(void *arg,unsigned short int data)
{
	//(0x1<<(An+1) @16bit_width  ->  1<<(18+1)=0x80000
	(*(volatile unsigned short int *)(FSM_BANK_PSRAM_ADDR|0x80000))=data; 
}
/*
**写寄存器
*/
void lcd_write_register(void *arg,unsigned short int index,unsigned short int data)
{
  lcd_write_index(0,index);
  lcd_write_data(0,data);
}
以下是MM32F3277G8P的FSMC配置代码,注释中对每行代码进行了详细解释说明: ```c #include "MM32F3277.h" void FSMC_NAND_Init(void) { // 使能FSMC时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); // 定义FSMC_NAND初始化结构体 FSMC_NANDInitTypeDef FSMC_NANDInitStructure; FSMC_NAND_PCCARDTimingInitTypeDef p; // 配置FSMC_NAND初始化结构体 p.FSMC_SetupTime = 0x1; p.FSMC_WaitSetupTime = 0x3; p.FSMC_HoldSetupTime = 0x2; p.FSMC_HiZSetupTime = 0x1; FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND; FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Disable; FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable; FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_256Bytes; FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00; FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00; FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p; FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p; // 初始化FSMC_NAND FSMC_NANDInit(&FSMC_NANDInitStructure); // 使能FSMC_NAND FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE); } ``` 解释说明如下: 1. `RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);`:使能FSMC时钟,使得FSMC模块能够正常工作。 2. `FSMC_NANDInitTypeDef FSMC_NANDInitStructure;`:定义FSMC_NAND初始化结构体。 3. `FSMC_NAND_PCCARDTimingInitTypeDef p;`:定义FSMC_NAND_PCCARDTiming初始化结构体。 4. `p.FSMC_SetupTime = 0x1;`:设置NAND芯片的SETUP时间为1个HCLK周期。 5. `p.FSMC_WaitSetupTime = 0x3;`:设置NAND芯片的WAIT时间为3个HCLK周期。 6. `p.FSMC_HoldSetupTime = 0x2;`:设置NAND芯片的HOLD时间为2个HCLK周期。 7. `p.FSMC_HiZSetupTime = 0x1;`:设置NAND芯片的HiZ时间为1个HCLK周期。 8. `FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;`:设置FSMC_NAND初始化结构体的FSMC_Bank成员为FSMC_Bank2_NAND,表示使用FSMC Bank2来连接NAND Flash。 9. `FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Disable;`:设置FSMC_NAND初始化结构体的FSMC_Waitfeature成员为FSMC_Waitfeature_Disable,表示禁用FSMC的等待特性。 10. `FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;`:设置FSMC_NAND初始化结构体的FSMC_MemoryDataWidth成员为FSMC_MemoryDataWidth_8b,表示使用8位数据总线。 11. `FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;`:设置FSMC_NAND初始化结构体的FSMC_ECC成员为FSMC_ECC_Enable,表示启用ECC校验功能。 12. `FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_256Bytes;`:设置FSMC_NAND初始化结构体的FSMC_ECCPageSize成员为FSMC_ECCPageSize_256Bytes,表示ECC校验的页面大小为256字节。 13. `FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;`:设置FSMC_NAND初始化结构体的FSMC_TCLRSetupTime成员为0,表示不需要设置CLE到RE的延时。 14. `FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;`:设置FSMC_NAND初始化结构体的FSMC_TARSetupTime成员为0,表示不需要设置ALE到RE的延时。 15. `FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;`:设置FSMC_NAND初始化结构体的FSMC_CommonSpaceTimingStruct成员为&p,表示使用前面定义的FSMC_NAND_PCCARDTiming初始化结构体来配置FSMC的时序参数。 16. `FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;`:设置FSMC_NAND初始化结构体的FSMC_AttributeSpaceTimingStruct成员为&p,表示使用前面定义的FSMC_NAND_PCCARDTiming初始化结构体来配置FSMC的时序参数。 17. `FSMC_NANDInit(&FSMC_NANDInitStructure);`:通过FSMC_NAND初始化结构体来初始化FSMC_NAND。 18. `FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);`:使能FSMC Bank2,使得NAND Flash能够正常读写。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KAMI STUDIO

若觉有用,甚幸!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值