STM32 的并口总线的所有接口类型解决方法

STM32 的并口总线的所有接口类型解决方法

STM32的并口总线支持NOR, SRAM, PSRAM,NAND接口,本文以PSRAM为例实现并口的同步非复用, 异步复用和异步非复用操作!以STM32F207IG(176脚)系列为例,步骤如下:
1.初始化并口的各个引脚
//Add[0-25] : F0-F5(6); F12-F15(4); G0-G5(6); D11-D13(3); E3-E6(4); E2(1); G13-G14(2)
//Data[0-15]: D14-D15(2); D0-1(2); E7-15(9); D8-10(3)
//FSMC_NIORD: F6NCfor PC CARD
//FSMC_NREG : F7NCfor PC CARD
//FSMC_NIOWR: F8NCfor PC CARD
//FSMC_CD: F9NCfor PC CARD
//FSMC_INTR : F10NCfor PC CARD
//FSMC_INT2 : G6NCfor COMMON
//FSMC_INT3 : G7NCfor COMMON
//FSMC_CLK: D3for NOR/PSRAM
//FSMC_NOE: D4for COMMON
//FSMC_NWE: D5for COMMON
//FSMC_NWAIT: D6for COMMON
//FSMC_NE1: D7FSMC_NCE2for NOR/PSRAMfor NAND
//FSMC_NE2: G9FSMC_NCE3for NOR/PSRAMfor NAND
//FSMC_NE3: G10NCfor NOR/PSRAM
//FSMC_NCE4 : G11NCfor NOR/PSRAM
//FSMC_NE4: G12NCfor NOR/PSRAM
//FSMC_NL: B7for NOR/PSRAM
//FSMC_NBL0 : E0for NOR/PSRAM
//FSMC_NBL1 : E1for NOR/PSRAM


void FsmcInit(void)
{
u8 i=0;

// 1.
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB| RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOG, ENABLE);

for(i=0; i{
GPIO_PinAFConfig((GPIO_TypeDef *)GPIOx,GPIO_PinSourceX, GPIO_AF_FSMC);
}

GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0 ;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);

for(i=0; i{
GPIO_InitStructure.GPIO_Pin= (1<GPIO_Init((GPIO_TypeDef *)GPIOx,&GPIO_InitStructure);
}

// FSMC_NWAIT: D6
【STM32 的并口总线的所有接口类型解决方法】GPIO_InitStructure.GPIO_Pin= GPIO_Pin_6 ;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);

FsmcBank1BusTypeInit(FSMC_TYPE_NOMUX_SYN, FSMC_Bank1_NORSRAM1, FSMC_MemoryType_PSRAM, FSMC_MemoryDataWidth_16b);
//FsmcBank1BusTypeInit(FSMC_TYPE_MUX_ASYN, FSMC_Bank1_NORSRAM1, FSMC_MemoryType_PSRAM, FSMC_MemoryDataWidth_16b);
// FsmcBank1BusTypeInit(FSMC_TYPE_NOMUX_ASYN, FSMC_Bank1_NORSRAM1, FSMC_MemoryType_PSRAM, FSMC_MemoryDataWidth_16b);
}



2. 初始化FSMC
u8 FsmcBank1BusTypeInit(u8 uchBusType, u32 uiBank1Numb, u32 uiMemType, u32 uiDataWide)
{
FSMC_NORSRAMInitTypeDefFSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDefFSMC_NORSRAMTimingRead;
FSMC_NORSRAMTimingInitTypeDefFSMC_NORSRAMTimingWrite;


if(((FSMC_TYPE_NOMUX_SYN == uchBusType)||(FSMC_TYPE_MUX_SYN == uchBusType)) &&(uiMemType == FSMC_MemoryType_NOR))
{//同步访问Nor 只支持读操作
return FSMC_OPT_FAIL;
}


// 0.默认初始化结构体,读写的时序
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTimingRead;
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct= &FSMC_NORSRAMTimingWrite;
FSMC_NORSRAMStructInit(&FSMC_NORSRAMInitStructure);


// 1. 总线类型初始化
FSMC_NORSRAMInitStructure.FSMC_Bank= uiBank1Numb;
FSMC_NORSRAMInitStructure.FSMC_MemoryType= uiMemType;
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth= uiDataWide;


// 2.根据芯片类型初始化
if((FSMC_TYPE_NOMUX_SYN == uchBusType)||(FSMC_TYPE_MUX_SYN == uchBusType))
{//同PSRAM, 同步非复用
//同步模式设置:
// 2.1 总线类型
if(FSMC_TYPE_MUX_SYN == uchBusType)
{
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux= FSMC_DataAddressMux_Enable;
}
else
{
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux= FSMC_DataAddressMux_Disable;
}
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode= FSMC_BurstAccessMode_Enable; //同步模式下使用,for NOR Flash(PSRAM)

// 2.2. 其他设置,burst模式禁用,burst mode disable: Paras. valid only when accessing Flash memories in burst mode
FSMC_NORSRAMInitStructure.FSMC_WriteBurst= FSMC_WriteBurst_Enable; //在同步模式下支持Write burst,但读时无效; 异步模式下设0,禁用,表示在异步模式下写操作总是容许的
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait= FSMC_AsynchronousWait_Disable; //异步操作时是否采用NWAIT信号来进行数据准备的延时
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode= FSMC_ExtendedMode_Disable; //是否支持扩展模式A,B,C,D,根据需要来设定
FSMC_NORSRAMInitStructure.FSMC_WaitSignal= FSMC_WaitSignal_Enable; //在burst模式下,是否插入NWAIT等待延时信号 ,同步必须插
FSMC_NORSRAMInitStructure.FSMC_WriteOperation= FSMC_WriteOperation_Enable; //是否支持写操作
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive= FSMC_WaitSignalActive_DuringWaitState; // 延时等待信号在FSMC_WaitSignalPolarity时表示正在等待,不是之前一个时钟周期类在等待
FSMC_NORSRAMInitStructure.FSMC_WrapMode= FSMC_WrapMode_Disable; //对总线宽度不一致时使用
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity= FSMC_WaitSignalPolarity_Low; //异步操作若开启延时,此表示延迟等待的电平,非此电平表示延时结束,for NOR Flash(PSRAM) WAITEN、WAITCFG、WAITPOL


// 2.3 延时时间设置,根据芯片来设计,同步模式,下列前三个不用设置
FSMC_NORSRAMTimingRead.FSMC_AddressSetupTime= 10; //地址建立时间的持续时间, 异步使用
FSMC_NORSRAMTimingRead.FSMC_AddressHoldTime= 5; //地址的建立后的保持时间, 异步使用
FSMC_NORSRAMTimingRead.FSMC_DataSetupTime= 10; //数据建立时间的持续时间,异步复用中使用
FSMC_NORSRAMTimingRead.FSMC_BusTurnAroundDuration= 2; //总线周转时间?!,复用模式使用
FSMC_NORSRAMTimingRead.FSMC_CLKDivision= 3; //定义输出时钟分频,同步使用, 0x0 to get CLK = HCLK(个别芯片不支持),0x1 to get CLK = 2 × HCLK,... , 0x0f; ==2,clk == 40M,==3,clk == 30M
FSMC_NORSRAMTimingRead.FSMC_DataLatency= 0; //内存时钟周期数,同步使用,DataLatency = 1 for NOR Flash; DataLatency = 0 for PSRAM
FSMC_NORSRAMTimingRead.FSMC_AccessMode= FSMC_AccessMode_A; //Specifies the asynchronous access mode


memcpy((u8 *)&FSMC_NORSRAMTimingWrite, (u8 *)&FSMC_NORSRAMTimingRead, sizeof(FSMC_NORSRAMTimingInitTypeDef));
}
else if((FSMC_TYPE_MUX_ASYN == uchBusType) || (FSMC_TYPE_NOMUX_ASYN == uchBusType))
{ //异步复用模式,异步非复用
// 2.1 总线类型
if(FSMC_TYPE_MUX_ASYN == uchBusType)
{
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux= FSMC_DataAddressMux_Enable;
}
else
{
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux= FSMC_DataAddressMux_Disable;
}
FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode= FSMC_BurstAccessMode_Disable; //同步模式下使用,for NOR Flash(PSRAM)

// 2.2. 其他设置,burst模式禁用,burst mode disable: Paras. valid only when accessing Flash memories in burst mode
FSMC_NORSRAMInitStructure.FSMC_WriteBurst= FSMC_WriteBurst_Disable; //在同步模式下支持Write burst ; 异步模式下设0,禁用,表示在异步模式下写操作总是容许的
FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait= FSMC_AsynchronousWait_Disable; //异步操作时是否采用NWAIT信号来进行数据准备的延时
FSMC_NORSRAMInitStructure.FSMC_ExtendedMode= FSMC_ExtendedMode_Disable; //是否支持扩展模式A,B,C,D,根据需要来设定
FSMC_NORSRAMInitStructure.FSMC_WaitSignal= FSMC_WaitSignal_Disable; //在burst模式下,是否插入NWAIT等待延时信号
FSMC_NORSRAMInitStructure.FSMC_WriteOperation= FSMC_WriteOperation_Enable; //是否支持写操作
FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive= FSMC_WaitSignalActive_BeforeWaitState; // 延时等待信号在FSMC_WaitSignalPolarity时表示正在等待,不是之前一个时钟周期类在等待
FSMC_NORSRAMInitStructure.FSMC_WrapMode= FSMC_WrapMode_Disable; //对总线宽度不一致时使用
FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity= FSMC_WaitSignalPolarity_High; //异步操作若开启延时,此表示延迟等待的电平,非此电平表示延时结束,for NOR Flash(PSRAM) WAITEN、WAITCFG、WAITPOL


// 2.3 延时时间设置,根据芯片来设计
FSMC_NORSRAMTimingRead.FSMC_AddressSetupTime= 20; //地址建立时间的持续时间, 异步使用
FSMC_NORSRAMTimingRead.FSMC_AddressHoldTime= 5; //地址的建立后的保持时间, 异步使用
FSMC_NORSRAMTimingRead.FSMC_DataSetupTime= 30; //数据建立时间的持续时间,异步复用中使用
FSMC_NORSRAMTimingRead.FSMC_BusTurnAroundDuration= 5; //总线周转时间?!,复用模式使用


FSMC_NORSRAMTimingRead.FSMC_CLKDivision= 1; //定义输出时钟分频,同步使用, 0x0 to get CLK = HCLK(个别芯片不支持),0x1 to get CLK = 2 × HCLK,... , 0x0f;
FSMC_NORSRAMTimingRead.FSMC_DataLatency= 0; //内存时钟周期数,同步使用,DataLatency = 1 for NOR Flash; DataLatency = 0 for PSRAM
FSMC_NORSRAMTimingRead.FSMC_AccessMode= FSMC_AccessMode_D; //Specifies the asynchronous access mode


memcpy((u8 *)&FSMC_NORSRAMTimingWrite, (u8 *)&FSMC_NORSRAMTimingRead, sizeof(FSMC_NORSRAMTimingInitTypeDef));
}
else//FSMC_TYPE_MUX_SYN: 同步复用
{
return FSMC_OPT_FAIL;
}

// 5.写配置到REG
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
FSMC_NORSRAMCmd(uiBank1Numb, ENABLE);


return FSMC_OPT_OK;
}


3. 函数的调用
void PsramWrite(u32 uiRegAddr, u16 ushValue)
{
// Transfer data to the memory
*(__IO u16 *) (cuistBank1BaseAddr[FSMC_FEC_BANK_NUMB] + (uiRegAddr<<1)) = ushValue;
}

u16 PsramRead(u32 uiRegAddr)
{
u16 ushVal = 0;
// Read data from the memory
ushVal = *(__IO u16*) (cuistBank1BaseAddr[FSMC_FEC_BANK_NUMB] + (uiRegAddr<<1));

return ushVal;
}



总结:一般异步模式下,需要调试建立时间,同步模式下则不用!
特别说明,对于非STM32标准的接口,如motorola和intel总线的并口,需要在调用PsramWrite和PsramRead时,手动进行片选FSMC_NEx的上拉和下拉!

    推荐阅读