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

上一篇忘了说了一个问题,那就是时钟,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_;
  }
}

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值