本帖最后由 魅影迷踪 于 2015-8-6 19:38 编辑
这一节我们将讲解ksz8863和lan9303的两口交换机方案,其实你用一个phy芯片,不如直接用交换机芯片价格差不太多,可以多一个网口,值;虽然下面的例程用的是stm32的,但这一节讲的是硬件,软件方便只是说明,也就是说不管你是不是用其他phy芯片,配置的东西和内容步骤都是一样的。
调试方法也是基本类似。
1.选择开发环境和调试例程 1.1 开发环境mdk5 1.2 例程为st官网例程如下图 2.修改例程代码 2.1 修改晶振频率 2.2 根据原理图修改以太网的引脚配置 2.3 根据lan9303或ksz8836修改phy寄存器的地址以及配置phy寄存器 2.4 修改网络配置 3.结合例程分步调试 3.1 mii接口的引脚定义和波形分析 3.2 mii接口的引脚定义和波形分析 3.3 lan9303或者 ksz8863的输出引脚是否正常 3.4 stm32f407的输出引脚是否正常 4.综合调试分析波形 4.1分析代码配置以及硬件strap来对比初始化后的lan9303或ksz8863 4.2添加客户端程序不断发起tcp连接
5.经验和总结 5.1 引脚功能类似,波形应该类似 5.2 lan9303的同一寄存器读取的寄存器地址不一样 5.3 配置和状态要分清 5.4有关底层的驱动配置,要查看是否执行到寄存器
1选择开发环境和调试例程 这里我们使用mdk5开发环境和st官f4的固件库里面的例程LwIP_TCP_Echo_Server 1.1开发环境mdk5 file:///C:\Users\LIUJIQ~1\AppData\Local\Temp\ksohtml\wpsEB09.tmp.jpg 1.2 例程为st官网例程如下图 file:///C:\Users\LIUJIQ~1\AppData\Local\Temp\ksohtml\wpsEB19.tmp.jpg
[size=15.0000pt]2.修改例程代码
2.1 修改晶振频率 例程是25Mhz的外部晶振,而我们使用的是8Mhz外部晶振,需要修改 在main.c里面找到static void SystemClock_Config(void)函数,将pll的分频从25改为8,见下面代码红色改为绿色的代码 static void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; /* Enable Power Control clock */ __PWR_CLK_ENABLE(); /* The voltage scaling allows optimizing the power consumption when the device is clocked below the maximum system frequency, to update the voltage scaling value regarding system frequency refer to product datasheet. */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; //RCC_OscInitStruct.PLL.PLLM = 25; RCC_OscInitStruct.PLL.PLLM = 8; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); } 在stm32f4xx_hal_conf.h找到(可以搜素HSE_VLAUE) 将红色的外部高速晶振频率值从25000000改为绿色的8000000 #if !defined (HSE_VALUE) //#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ 2.2 根据原理图修改以太网的引脚配置 由于例程是基于144pin的stm32f407,而我们使用的是100pin的,引脚不兼容,需要修改。 将stm32f4xx_hal_eth.c里面的函数 void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) { GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIOs clocks */ __GPIOA_CLK_ENABLE(); __GPIOB_CLK_ENABLE(); __GPIOC_CLK_ENABLE(); __GPIOF_CLK_ENABLE(); __GPIOG_CLK_ENABLE(); __GPIOH_CLK_ENABLE(); __GPIOI_CLK_ENABLE(); /* Ethernet pins configuration ************************************************/ /* ETH_MDIO -------------------------> PA2 ETH_MDC --------------------------> PC1 ETH_PPS_OUT ----------------------> PB5 ETH_MII_CRS ----------------------> PH2 ETH_MII_COL ----------------------> PH3 ETH_MII_RX_ER --------------------> PI10 ETH_MII_RXD2 ---------------------> PH6 ETH_MII_RXD3 ---------------------> PH7 ETH_MII_TX_CLK -------------------> PC3 ETH_MII_TXD2 ---------------------> PC2 ETH_MII_TXD3 ---------------------> PB8 ETH_MII_RX_CLK/ETH_RMII_REF_CLK---> PA1 ETH_MII_RX_DV/ETH_RMII_CRS_DV ----> PA7 ETH_MII_RXD0/ETH_RMII_RXD0 -------> PC4 ETH_MII_RXD1/ETH_RMII_RXD1 -------> PC5 ETH_MII_TX_EN/ETH_RMII_TX_EN -----> PG11 ETH_MII_TXD0/ETH_RMII_TXD0 -------> PG13 ETH_MII_TXD1/ETH_RMII_TXD1 -------> PG14 */ /* Configure PA1, PA2 , PA7 */ GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7; GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; GPIO_InitStructure.Pull = GPIO_NOPULL ; GPIO_InitStructure.Alternate = GPIO_AF11_ETH; HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure PB5 and PB8 */ GPIO_InitStructure.Pin = GPIO_PIN_5 | GPIO_PIN_8; HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure PC1, PC2, PC3, PC4 and PC5 */ GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5; HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); /* Configure PG11, PG14 and PG13 */ GPIO_InitStructure.Pin = GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14; HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); /* Configure PH2, PH3, PH6, PH7 */ GPIO_InitStructure.Pin = GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_6 | GPIO_PIN_7; HAL_GPIO_Init(GPIOH, &GPIO_InitStructure); /* Configure PI10 */ GPIO_InitStructure.Pin = GPIO_PIN_10; HAL_GPIO_Init(GPIOI, &GPIO_InitStructure); /* Enable ETHERNET clock */ __ETH_CLK_ENABLE(); if (heth->Init.MediaInterface == ETH_MEDIA_INTERFACE_MII) { /* Output HSE clock (25MHz) on MCO pin (PA8) to clock the PHY */ HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1); } } 修改为 void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) { GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIOs clocks */ __GPIOA_CLK_ENABLE(); __GPIOB_CLK_ENABLE(); __GPIOC_CLK_ENABLE(); /* Ethernet pins configuration ************************************************/ /* ETH_MDIO -------------------------> PA2 ETH_MDC --------------------------> PC1 ETH_PPS_OUT ----------------------> PB5 ETH_MII_CRS ----------------------> PA0 ETH_MII_COL ----------------------> PA3 ETH_MII_RX_ER --------------------> PB10 ETH_MII_RXD2 ---------------------> PB0 ETH_MII_RXD3 ---------------------> PB1 ETH_MII_TX_CLK -------------------> PC3 ETH_MII_TXD2 ---------------------> PC2 ETH_MII_TXD3 ---------------------> PB8 ETH_MII_RX_CLK/ETH_RMII_REF_CLK---> PA1 ETH_MII_RX_DV/ETH_RMII_CRS_DV ----> PA7 ETH_MII_RXD0/ETH_RMII_RXD0 -------> PC4 ETH_MII_RXD1/ETH_RMII_RXD1 -------> PC5 ETH_MII_TX_EN/ETH_RMII_TX_EN -----> PB11 ETH_MII_TXD0/ETH_RMII_TXD0 -------> PB12 ETH_MII_TXD1/ETH_RMII_TXD1 -------> PB13 */ /* Configure PA1, PA2 , PA7 */ GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2| GPIO_PIN_3| GPIO_PIN_7; GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; GPIO_InitStructure.Pull = GPIO_NOPULL ; GPIO_InitStructure.Alternate = GPIO_AF11_ETH; HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure PB5 and PB8 */ GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1| GPIO_PIN_2| GPIO_PIN_5| GPIO_PIN_8| GPIO_PIN_11| GPIO_PIN_12| GPIO_PIN_13; HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure PC1, PC2, PC3, PC4 and PC5 */ GPIO_InitStructure.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5; HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); /* Enable ETHERNET clock */ __ETH_CLK_ENABLE(); if (heth->Init.MediaInterface == ETH_MEDIA_INTERFACE_MII) { /* Output HSE clock (25MHz) on MCO pin (PA8) to clock the PHY */ HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1); } } 2.3 根据lan9303或ksz8836修改phy寄存器的地址以及配置phy寄存器 修改phy寄存器地址以及对应的位,由于是mac对phy的操作,所以修改的值参照lan9303的datasheet。 在stm32f4xx_hal_conf.h文件中找到 对于lan9303 /* Section 4: Extended PHY Registers */ //#define PHY_SR ((uint16_t)0x10) /*!< PHY #define PHY_SR ((uint16_t)0x1f) /*!< PHY status register Offset */ #define PHY_MICR ((uint16_t)0x11) /*!< MII Interrupt Control Register */ #define PHY_MISR ((uint16_t)0x12) /*!< MII Interrupt Status and Misc. Control Register */ #define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask //#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY #define PHY_SPEED_STATUS ((uint16_t)0x0004) /*!< PHY Speed mask */ //#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY #define PHY_DUPLEX_STATUS ((uint16_t)0x0010) /*!< PHY Duplex mask */ #define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ #define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ #define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ #define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ 将红色部分修改为绿色部分 对于ksz8863 /* Section 4: Extended PHY Registers */ //#define PHY_SR ((uint16_t)0x10) /*!< PHY #define PHY_SR ((uint16_t)0x06) /*!< PHY status register Offset */ #define PHY_MICR ((uint16_t)0x11) /*!< MII Interrupt Control Register */ #define PHY_MISR ((uint16_t)0x12) /*!< MII Interrupt Status and Misc. Control Register */ #define PHY_LINK_STATUS ((uint16_t)0x0001) /*!< PHY Link mask //#define PHY_SPEED_STATUS ((uint16_t)0x0002) /*!< PHY #define PHY_SPEED_STATUS ((uint16_t)0x0010) /*!< PHY Speed mask */ //#define PHY_DUPLEX_STATUS ((uint16_t)0x0004) /*!< PHY #define PHY_DUPLEX_STATUS ((uint16_t)0x0040) /*!< PHY Duplex mask */ #define PHY_MICR_INT_EN ((uint16_t)0x0002) /*!< PHY Enable interrupts */ #define PHY_MICR_INT_OE ((uint16_t)0x0001) /*!< PHY Enable output interrupt events */ #define PHY_MISR_LINK_INT_EN ((uint16_t)0x0020) /*!< Enable Interrupt on change of link status */ #define PHY_LINK_INTERRUPT ((uint16_t)0x2000) /*!< PHY link status interrupt mask */ 将红色部分修改为绿色部分 2.4 修改网络配置 在main.h中将红色部分改为绿色部分 #define DEST_IP_ADDR0 192 #define DEST_IP_ADDR1 168 //#define DEST_IP_ADDR2 0 //#define DEST_IP_ADDR3 11 #define DEST_IP_ADDR2 1 #define DEST_IP_ADDR3 126 #define DEST_PORT 7 /*Static IP ADDRESS: IP_ADDR0.IP_ADDR1.IP_ADDR2.IP_ADDR3 */ #define IP_ADDR0 192 #define IP_ADDR1 168 //#define IP_ADDR2 0 //#define IP_ADDR3 10 #define IP_ADDR2 1 #define IP_ADDR3 35 /*NETMASK*/ #define NETMASK_ADDR0 255 #define NETMASK_ADDR1 255 #define NETMASK_ADDR2 255 #define NETMASK_ADDR3 0 /*Gateway Address*/ #define GW_ADDR0 192 #define GW_ADDR1 168 //#define GW_ADDR2 0 //#define GW_ADDR3 1 #define GW_ADDR2 1 #define GW_ADDR3 1 [size=15.0000pt]3.结合例程分步调试 3.1 mii接口的引脚定义和波形分析 TXD(Transmit Data)[3:0]:数据发送信号,共4根信号线; RXD(Receive Data)[3:0]:数据接收信号,共4根信号线; TX_ER(Transmit Error):发送数据错误提示信号,同步于TX_CLK,高电平有效,表示TX_ER有效期内传输的数据无效。对于10Mbps速率下,TX_ER不起作用; RX_ER(Receive Error):接收数据错误提示信号,同步于RX_CLK,高电平有效,表示RX_ER有效期内传输的数据无效。对于10Mbps速率下,RX_ER不起作用; TX_EN(Transmit Enable): 发送使能信号,只有在TX_EN有效期内传的数据才有效; RX_DV(Reveive Data Valid): 接收数据有效信号,作用类型于发送通道的TX_EN; TX_CLK:发送参考时钟,100Mbps速率下,时钟频率为25MHz,10Mbps速率下,时钟频率为2.5MHz。注意,TX_CLK时钟的方向是从PHY侧指向MAC侧的,因此此时钟是由PHY提供的。 RX_CLK:接收数据参考时钟,100Mbps速率下,时钟频率为25MHz,10Mbps速率下,时钟频率为2.5MHz。RX_CLK也是由PHY侧提供的。 CRS:Carrier Sense,载波侦测信号,不需要同步于参考时钟,只要有数据传输,CRS就有效,另外,CRS只有PHY在半双工模式下有效; COL:Collision Detectd,冲突检测信号,不需要同步于参考时钟,只有PHY在半双工模式下有效。 MII接口一共有16根线。
3.2调试smi接口是否是正常的 在以太网初始化中,要通过smi接口对phy进行配置和协商,所以我们可以在初始化的时候观看mdio信号和mdc信号是否正常,若正常则继续调试代码,读取phy寄存器的值,通过串口打印出来和寄存器的默认值以及引脚strap配置的值是否一样,当然可以自己改寄存器值来读取lan9303的id,这里我们读出来的id就是0x9303XXXX。 3.3lan9303的输出引脚是否正常 这里lan9303的port1和port2是工作正常的,我们可以将port1或者port2接到有数据发送的路由器上或者直接接电脑网口,我们会在lan9303的mii接口的TXEN, 3.4stm32f407的输出引脚是否正常 这里我们可以在代码中添加客户端程序代码,这样我们可以通过mac不断地发起tcp连接,这样就可以在mac的mii接口上用示波器观察波形。
4.综合调试分析波形 4.1分析代码配置以及硬件strap来对比初始化后的lan9303或ksz8863 在对lan9303的phy的自动协商和初始化后,读出lan9303的值的和配置的或者默认的值是否一致,同时通过mdk view窗口下的system view看以太网的寄存器配置是否对,如下图 file:///C:\Users\LIUJIQ~1\AppData\Local\Temp\ksohtml\wpsEB2A.tmp.jpgfile:///C:\Users\LIUJIQ~1\AppData\Local\Temp\ksohtml\wpsEB3A.tmp.jpg 例如这里DM的值勾上,为1,表示是全双工模式,FES为1,表示的是工作在100M。 4.2添加客户端程序不断发起tcp连接 在程序里添加客户端程序不断发起tcp连接看mii接口是否有数据发出,若没有则说明程序底层驱动有问题,若有对比其他功能正常的mii接口波形,观察是否一致。
[size=15.0000pt]5.经验和总结 5.1 引脚功能类似,波形应该类似 在用示波器调试过程中发现TXD3和TXD2的波形是方波,而TXD1和TXD0的波形带有梯形,感性认识可能是有串扰或者是短路等,用万用表测果然在stm32这边的芯片的引脚有短路。 5.2 lan9303的同一寄存器读取的寄存器地址不一样 lan9303的iic读寄存器的地址和smi去读的地址是不一样的,由于最开始用了iic操作了lan9303的寄存器,然后用smi去操作结果不同,后来通过分析smi的帧格式发现,smi的寄存器操作范围只有0-31一共32个寄存器,而我操作的寄存器地址明显大于这个范围,后来查看lan9303的datasheet才发现,不同接口操的的寄存器地址是不一样的。 5.3 配置和状态要分清 比如lan9303里面的10M\100M的配置和状态,配置的是1表示100M,而状态是1表示10M。 5.4 有关底层的驱动配置,要查看是否执行到寄存器 由于lan9303的状态表示在代码中是1表示一百兆,我们配置的是100M,结果lan9303配置到了100M,而stm32f407这边却配置了10M。
等下次什么时候有空我做个飞思卡尔的板子,我在将例程改成飞思卡尔的,方法大家先参考
|