|
楼主 |
发表于 2020-3-17 09:38:59
|
显示全部楼层
硬汉哥真是爱心大使啊,原理图如下:
代码如下:基于“V7-022_FMC总线扩展32路高速IO”的工程进行修改而来,所以大部分内容跟原工程一致
附注:所访问地址,不管是否左移1位,均得不到正确结果。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define LAN9252_READ(offset) (*(__IO uint32_t *)(LAM9252_REG_BASE + (offset<<1)))
int main(void)
{
uint8_t ucKeyCode; /* 按键代码 */
uint32_t *u32Ptr;
bsp_Init(); /* 硬件初始化 */
/* 进入主程序循环体 */
while (1)
{
bsp_Idle(); /* 这个函数在bsp.c文件。用户可以修改这个函数实现CPU休眠和喂狗 */
/* FMC device read test */
g_u32Temp = LAN9252_READ(0x64);//*u32Ptr;
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void bsp_Init(void)
{
/* 配置MPU */
MPU_Config();
/* 使能L1 Cache */
CPU_CACHE_Enable();
/*
STM32H7xx HAL 库初始化,此时系统用的还是H7自带的64MHz,HSI时钟:
- 调用函数HAL_InitTick,初始化滴答时钟中断1ms。
- 设置NVIV优先级分组为4。
*/
HAL_Init();
/*
配置系统时钟到400MHz
- 切换使用HSE。
- 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。
*/
SystemClock_Config();
/*
Event Recorder:
- 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。
- 默认不开启,如果要使能此选项,务必看V7开发板用户手册第8章
*/
#if Enable_EventRecorder == 1
/* 初始化EventRecorder并开启 */
EventRecorderInitialize(EventRecordAll, 1U);
EventRecorderStart();
#endif
// bsp_InitKey(); /* 按键初始化,要放在滴答定时器之前,因为按钮检测是通过滴答定时器扫描 */
bsp_InitTimer(); /* 初始化滴答定时器 */
// bsp_InitUart(); /* 初始化串口 */
bsp_InitExtIO(); /* 初始化FMC总线74HC574扩展IO. 必须在 bsp_InitLed()前执行 */
// bsp_InitLed(); /* 初始化LED */
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
*********************************************************************************************************
* 函 数 名: MPU_Config
* 功能说明: 配置MPU
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void MPU_Config( void )
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* 禁止 MPU */
HAL_MPU_Disable();
/* 配置AXI SRAM的MPU属性为Write back, Read allocate,Write allocate */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = D1_AXISRAM_BASE;//0x24000000;//change @20200120
MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* 配置FMC扩展IO的MPU属性为Device或者Strongly Ordered */
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x60000000;/* FMC_BANK1_BASE */
MPU_InitStruct.Size = ARM_MPU_REGION_SIZE_64KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; /* 不能用MPU_ACCESS_CACHEABLE,会出现2次CS、WE信号 */
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/*使能 MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
/********************************************************************************************************
* 函 数 名: bsp_InitExtIO
* 功能说明: 配置扩展IO相关的GPIO. 上电只能执行一次。
* 形 参: 无
* 返 回 值: 无
********************************************************************************************************/
void bsp_InitExtIO(void)
{
/* commment @ 20200120 */
// HC574_ConfigGPIO();
// HC574_ConfigFMC();
/* add @ 20200120 */
lan9252_ConfigGPIO();
lan9252_ConfigFMC();
/* commment @ 20200120 */
// /* 将开发板一些片选,LED口设置为高 */
// g_HC574 = (NRF24L01_CE | VS1053_XDCS | LED1 | LED2 | LED3 | LED4);
// HC574_PORT = g_HC574; /* 写硬件端口,更改IO状态 */
}
/*********************************************************************************************************
* 函 数 名: lan9252_ConfigGPIO
* 功能说明: 配置GPIO,FMC管脚设置为复用功能
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************/
static void lan9252_ConfigGPIO(void)
{
/*
demo board v1:
PD14/FMC_DA0
PD15/FMC_DA1
PD0/FMC_DA2
PD1/FMC_DA3
PE7/FMC_DA4
PE8/FMC_DA5
PE9/FMC_DA6
PE10/FMC_DA7
PE11/FMC_DA8
PE12/FMC_DA9
PE13/FMC_DA10
PE14/FMC_DA11
PE15/FMC_DA12
PD8/FMC_DA13
PD9/FMC_DA14
PD10/FMC_DA15
PD4/FMC_NOE ---- 读控制信号,OE = Output Enable , N 表示低有效
PD5/FMC_NWE -XX- 写控制信号,
PC7/FMC_NE1 --- 主片选(Bank1)
PB7/FMC_NL --- 地址有效信号,区分地址与数据 ALELO
+-------------------+------------------+
+ 16-bits Multiplex Mode: AD0-AD15 +
+-------------------+------------------+
*/
GPIO_InitTypeDef gpio_init_structure;
/* 使能 GPIO时钟 */
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/* 使能FMC时钟 */
__HAL_RCC_FMC_CLK_ENABLE();
/* 设置 GPIOD 相关的IO为复用推挽输出 */
gpio_init_structure.Mode = GPIO_MODE_AF_PP;
gpio_init_structure.Pull = GPIO_PULLUP;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
gpio_init_structure.Alternate = GPIO_AF12_FMC;
/* 配置GPIOB */
gpio_init_structure.Pin = GPIO_PIN_7;
HAL_GPIO_Init(GPIOB, &gpio_init_structure);
/* 配置GPIOD */
gpio_init_structure.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;
HAL_GPIO_Init(GPIOD, &gpio_init_structure);
/* 配置GPIOE */
gpio_init_structure.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;
HAL_GPIO_Init(GPIOE, &gpio_init_structure);
/* 配置GPIOC ECAT_CS */
gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_structure.Pull = GPIO_PULLUP;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
gpio_init_structure.Pin = GPIO_PIN_7;
gpio_init_structure.Alternate = GPIO_AF9_FMC;
HAL_GPIO_Init(GPIOC, &gpio_init_structure);
}
/*
*********************************************************************************************************
* 函 数 名: lan9252_ConfigFMC
* 功能说明: 配置FMC并口访问时序
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void lan9252_ConfigFMC(void)
{
SRAM_HandleTypeDef hsram = {0};
FMC_NORSRAM_TimingTypeDef SRAM_Timing = {0};
hsram.Instance = FMC_NORSRAM_DEVICE;
hsram.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
/* FMC使用的HCLK3,主频240MHz,1个FMC时钟周期就是4.1667ns */
/* SRAM 总线时序配置 4-1-2-1-2-2 不稳定,5-2-2-1-2-2 稳定 */
SRAM_Timing.AddressSetupTime = 3; /* 地址建立时间,min(LAN9252)=10ns=>3*4.16667=12.4ns,3个FMC时钟周期 */
SRAM_Timing.AddressHoldTime = 2; /* 地址保持时间,min(LAN9252)=5ns=>2*4.16667=8.333ns,模式A时用不到此参数 */
SRAM_Timing.DataSetupTime = 2; /* 数据保持时间,min(LAN9252)=5ns=>2*4.16667=8.333ns,2个FMC时钟周期 */
SRAM_Timing.BusTurnAroundDuration = 1; /* 此配置用不到这个参数 */
SRAM_Timing.CLKDivision = 11; /* 此配置用不到这个参数 -- 安富莱的这个注释不对,这个参数有用的,设置FMC时钟周期*/
SRAM_Timing.DataLatency = 2; /* 此配置用不到这个参数 */
SRAM_Timing.AccessMode = FMC_ACCESS_MODE_A; /* 配置为模式A 扩展模式禁止时实为模式1-SRAM/PSRAM */
hsram.Init.NSBank = FMC_NORSRAM_BANK1; /* 使用的BANK1,即使用的片选FMC_NE1 */
hsram.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_ENABLE; /* 使能地址数据复用 */
hsram.Init.MemoryType = FMC_MEMORY_TYPE_NOR;//PSRAM; /* 存储器类型SRAM *///FMC_MEMORY_TYPE_PSRAM
hsram.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16; /* 16位总线宽度 */
hsram.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE; /* 关闭突发模式 */
hsram.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW; /* 用于设置等待信号的极性,关闭突发模式,此参数无效 */
hsram.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS; /* 关闭突发模式,此参数无效 */
hsram.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE; /* 用于使能或者禁止写操作 - 该位只是FMC是否使能/禁止在存储区域内写入 */
hsram.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE; /* 关闭突发模式,此参数无效 */
hsram.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE; /* 禁止扩展模式 */
hsram.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE; /* 用于异步传输期间,使能或者禁止等待信号,这里选择关闭 */
hsram.Init.WriteBurst = FMC_WRITE_BURST_DISABLE; /* 禁止写突发 */
hsram.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY; /* 仅同步模式才做时钟输出 - 即异步模式时不输出时钟 */
hsram.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE; /* 使能写FIFO(复位后的默认值) */
/* 初始化SRAM控制器 */
if (HAL_SRAM_Init(&hsram, &SRAM_Timing, &SRAM_Timing) != HAL_OK)
{
/* 初始化错误 */
Error_Handler(__FILE__, __LINE__);
}
}
|
|