STM32之KSZ8851的FMC配置问题——H7的单片机版本

tech2022-10-28  158

上一篇忘了说了一个问题,那就是时钟,M4单片机采用的是168MHZ主频,所以这里的配置按照如下:

这是查芯片手册得来的,而到了H7主频则为400MHZ,需要换算一下,下面给出H7的FMC驱动程序,H7的单片机型号为STM32H743IITx:

基本上三部走:配置IO、配置MPU、配置FMC

/* ********************************************************************************************************* * * 模块名称 : ksz8851并口驱动 * 文件名称 : bsp_fmc_ksz8851.c * 版 本 : * 说 明 : * * ********************************************************************************************************* */ #include "stm32h7xx_hal.h" #include "stm32h7xx_ll_fmc.h" #include "bsp_fmc_ksz8851.h" #include "ksz8851.h" /* KSZ8851 的 GPIO : PD0/FSMC_D2 PD1/FSMC_D3 PD4/FSMC_NOE PD5/FSMC_NWE PD8/FSMC_D13 PD9/FSMC_D14 PD10/FSMC_D15 PD14/FSMC_D0 PD15/FSMC_D1 PE7/FSMC_D4 PE8/FSMC_D5 PE9/FSMC_D6 PE10/FSMC_D7 PE11/FSMC_D8 PE12/FSMC_D9 PE13/FSMC_D10 PE14/FSMC_D11 PE15/FSMC_D12 PF0/FSMC_A0 PD7/FSMC_NE1 --- ksz8851_1片选主信号 PG9/FSMC_NE2 --- ksz8851_2片选主信号 */ /* ********************************************************************************************************* * 函 数 名: bsp_InitKSZ8851 * 功能说明: 配置连接KSZ8851的GPIO和FSMC * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ NOR_HandleTypeDef eth1,eth2; void bsp_Initfmc_ksz8851(void) { FMC_NORSRAM_TimingTypeDef ReadTiming; FMC_NORSRAM_TimingTypeDef WriteTiming; GPIO_InitTypeDef GPIO_InitStruct; MPU_Region_InitTypeDef MPU_InitStruct; /** Peripheral clock enable */ __HAL_RCC_FMC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); GPIO_InitStruct.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_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_FMC; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_FMC; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_FMC; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15 | GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF12_FMC; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); /** Disable the MPU */ HAL_MPU_Disable(); /* 配置FMC驱动屏幕的MPU属性为Device或者Strongly Ordered */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = KSZ8851_BASE_A; MPU_InitStruct.Size = MPU_REGION_SIZE_64MB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = KSZ8851_BASE_B; MPU_InitStruct.Size = MPU_REGION_SIZE_64MB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; 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); HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); /* -- FSMC Configuration ------------------------------------------------------*/ WriteTiming.AddressSetupTime = 10U; /* 根据M4所配置时间,400MHz换算168MHz比例而来*/ WriteTiming.AddressHoldTime = 8U; WriteTiming.DataSetupTime = 51U; /* 50个HLCK周期,125ns>100ns建立时间 */ WriteTiming.BusTurnAroundDuration = 0U; WriteTiming.CLKDivision = 0U; WriteTiming.DataLatency = 0U; WriteTiming.AccessMode = FMC_ACCESS_MODE_A; ReadTiming.AddressSetupTime = 10U; /* 根据M4所配置时间,400MHz换算168MHz比例而来*/ ReadTiming.AddressHoldTime = 8U; ReadTiming.DataSetupTime = 51U; /* 50个HLCK周期,125ns>100ns建立时间 */ ReadTiming.BusTurnAroundDuration = 0U; ReadTiming.CLKDivision = 0U; ReadTiming.DataLatency = 0U; ReadTiming.AccessMode = FMC_ACCESS_MODE_A; eth1.Instance = FMC_NORSRAM_DEVICE; eth1.Extended = FMC_NORSRAM_EXTENDED_DEVICE; /** hsram2.Init */ eth1.Init.NSBank = FMC_NORSRAM_BANK1; /** 选择设置的BANK及片选信号 */ eth1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE; /** 设置是否数据地址总线分时复用 */ eth1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM; /** 设置存储器类型 */ eth1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16; /** FMC_MemoryDataWidth_16b; 设置数据宽度 */ eth1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE; /** 设置是否采用并发访问模式 */ eth1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW; /** 设置wait信号有效电平 */ eth1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS; /** 设置wait信号有效时机 */ eth1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE; /** 设置是否使能写操作 */ eth1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE; /** 设置是否使用wait信号 */ eth1.Init.ExtendedMode = FMC_EXTENDED_MODE_ENABLE; /** 设定是否使用单独的写时序 */ eth1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE; eth1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE; /** 设定是否使用写并发模式 */ eth1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ASYNC;/** FMC_CONTINUOUS_CLOCK_SYNC_ONLY; */ eth1.Init.WriteFifo = FMC_WRITE_FIFO_DISABLE;/** FMC_WRITE_FIFO_ENABLE; */ eth1.Init.PageSize = FMC_PAGE_SIZE_NONE; eth2.Instance = FMC_NORSRAM_DEVICE; eth2.Extended = FMC_NORSRAM_EXTENDED_DEVICE; /** hsram2.Init */ eth2.Init.NSBank = FMC_NORSRAM_BANK2; /** 选择设置的BANK及片选信号 */ eth2.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE; /** 设置是否数据地址总线分时复用 */ eth2.Init.MemoryType = FMC_MEMORY_TYPE_SRAM; /** 设置存储器类型 */ eth2.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16; /** FMC_MemoryDataWidth_16b; 设置数据宽度 */ eth2.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE; /** 设置是否采用并发访问模式 */ eth2.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW; /** 设置wait信号有效电平 */ eth2.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS; /** 设置wait信号有效时机 */ eth2.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE; /** 设置是否使能写操作 */ eth2.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE; /** 设置是否使用wait信号 */ eth2.Init.ExtendedMode = FMC_EXTENDED_MODE_ENABLE; /** 设定是否使用单独的写时序 */ eth2.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE; eth2.Init.WriteBurst = FMC_WRITE_BURST_DISABLE; /** 设定是否使用写并发模式 */ eth2.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ASYNC;/** FMC_CONTINUOUS_CLOCK_SYNC_ONLY; */ eth2.Init.WriteFifo = FMC_WRITE_FIFO_DISABLE;/** FMC_WRITE_FIFO_ENABLE; */ eth2.Init.PageSize = FMC_PAGE_SIZE_NONE; if (HAL_NOR_Init(&eth1, &ReadTiming, &WriteTiming) != HAL_OK) { while (1) {} } else {} if (HAL_NOR_Init(&eth2, &ReadTiming, &WriteTiming) != HAL_OK) { while (1) {} } else {} } /* ************************************************* (END OF FILE) *********************************/

然后就是初始化8851使用了

bsp_Initfmc_ksz8851(); /* 初始化KSZ8851并口*/ ksz8851_init(); /* ksz8851初始化*/ void ksz8851_init(void) { GPIO_Config(); EXTILine_Config(); /* */ KSZ8851_Reset(); uint8 ok = 0; if (ksz8851_init_b() != NULL_) { ok++; } else { } if (ksz8851_init_a() != NULL_) { ok++; } else { } }

多干了一些事情,关于8851外部控制引脚的配置

const static S_GpioCtrl KSZ8851_RESET[2] = { {RCC_AHB4ENR_GPIOGEN, GPIOG, GPIO_PIN_2}, {RCC_AHB4ENR_GPIODEN, GPIOD, GPIO_PIN_13} }; const static S_GpioCtrl KSZ8851_PME[2] = { {RCC_AHB4ENR_GPIOGEN, GPIOG, GPIO_PIN_3}, {RCC_AHB4ENR_GPIODEN, GPIOD, GPIO_PIN_12} }; static void GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIOG clock */ __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); GPIO_InitStructure.Pin = (uint32)(KSZ8851_RESET[0].GPIOxPinx); GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(KSZ8851_RESET[0].GPIOx, &GPIO_InitStructure); GPIO_InitStructure.Pin = (uint32)(KSZ8851_RESET[1].GPIOxPinx); GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(KSZ8851_RESET[1].GPIOx, &GPIO_InitStructure); GPIO_InitStructure.Pin = (uint32)(KSZ8851_PME[0].GPIOxPinx); GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(KSZ8851_PME[0].GPIOx, &GPIO_InitStructure); GPIO_InitStructure.Pin = (uint32)(KSZ8851_PME[1].GPIOxPinx); GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(KSZ8851_PME[1].GPIOx, &GPIO_InitStructure); } static void KSZ8851_Reset(void) { //复位 HAL_GPIO_WritePin(KSZ8851_RESET[0].GPIOx, KSZ8851_RESET[0].GPIOxPinx,0); HAL_GPIO_WritePin(KSZ8851_RESET[1].GPIOx, KSZ8851_RESET[1].GPIOxPinx,0); DelayMs(20); HAL_GPIO_WritePin(KSZ8851_RESET[0].GPIOx, KSZ8851_RESET[0].GPIOxPinx,1); HAL_GPIO_WritePin(KSZ8851_RESET[1].GPIOx, KSZ8851_RESET[1].GPIOxPinx,1); //设置为非电源唤醒状态 HAL_GPIO_WritePin(KSZ8851_PME[0].GPIOx, KSZ8851_PME[0].GPIOxPinx,1); HAL_GPIO_WritePin(KSZ8851_PME[1].GPIOx, KSZ8851_PME[1].GPIOxPinx,1); } /* ********************************************************************************************************* * 函 数 名: EXTILine8_Config * 功能说明: 初始化外部中断,用到的外部中断有PG4-ENET1, PD11-ENET2 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void EXTILine_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIOG clock */ __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); /* Enable SYSCFG clock */ __HAL_RCC_SYSCFG_CLK_ENABLE(); /* Configure PG15 pin as input floating */ GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING; GPIO_InitStructure.Pull = GPIO_PULLUP; GPIO_InitStructure.Pin = (uint32)(GPIO_PIN_4); HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); GPIO_InitStructure.Pin = (uint32)(GPIO_PIN_11); HAL_GPIO_Init(GPIOD, &GPIO_InitStructure); /* EXTI interrupt init*/ HAL_NVIC_SetPriority(EXTI15_10_IRQn, 1, 0); HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); /* EXTI interrupt init*/ HAL_NVIC_SetPriority(EXTI4_IRQn, 1, 0); HAL_NVIC_EnableIRQ(EXTI4_IRQn); }

8851初始化还有一部分函数贴出来

void * ksz8851_init_a(void) { uint32 i; memset((void *)&ksz8851_a, 0, sizeof(S_BOARD_INFO)); for (i= 0U; i<LEP_MAC_ADDR_LEN; i++) /* */ { ksz8851_a.mac_addr[i] = MC_MACA[i]; } ksz8851_a.phw_addr = (uint16 IO__ *)KSZ8851_BASE_A; ksz8851_a.phw_addr_cmd = (uint16 IO__ *)KSZ8851_A_CMD; if (ks8851_probe(&ksz8851_a) == 0) /* */ { ks_net_open(&ksz8851_a); return (void *)&ksz8851_a; /* search board and register */ } else { return NULL_; } } /* ********************************************************************************************************* * 函 数 名: ksz8851_init_b * 功能说明: 8851_b 初始化 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ void * ksz8851_init_b(void) { uint32 i; memset((void *)&ksz8851_b, 0, sizeof(S_BOARD_INFO)); for (i= 0U; i<LEP_MAC_ADDR_LEN; i++) /* */ { ksz8851_b.mac_addr[i] = MC_MACB[i]; } ksz8851_b.phw_addr = (uint16 IO__ *)KSZ8851_BASE_B; ksz8851_b.phw_addr_cmd = (uint16 IO__ *)KSZ8851_B_CMD; if (ks8851_probe(&ksz8851_b) == 0) /* */ { ks_net_open(&ksz8851_b); return (void *)&ksz8851_b; /* search board and register */ } else { return NULL_; } }

 

最新回复(0)