OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 1270|回复: 1

STM32F107 + DP83848网线插拔检测

[复制链接]

4

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
123
金钱
123
注册时间
2018-4-18
在线时间
26 小时
发表于 2023-12-18 11:35:51 | 显示全部楼层 |阅读模式
1金钱
我在做STM32F107VCT6驱动DP83848以太网PHY的时候,想做一个检测网线插拔的功能。但目前发现,将DP83848的7引脚初始化为中断模式后,插拔网线的时候,DP83848的7引脚未产生电平变化,请各位有遇到相关问题的同学帮忙解答一下。
硬件原理图:

DP83848的7引脚上拉10K欧姆的电阻。

软件初始化RMII接口的代码如下:
void HAL_ETH_MspInit(ETH_HandleTypeDef* ethHandle)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* GPIO Ports Clock Enable */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();

    if (ethHandle->Instance == ETH) {
        __HAL_RCC_ETH_CLK_ENABLE();

        /**ETH GPIO Configuration
        PC1     ------> ETH_MDC
        PA1     ------> ETH_REF_CLK
        PA2     ------> ETH_MDIO
        PA7     ------> ETH_CRS_DV
        PC4     ------> ETH_RXD0
        PC5     ------> ETH_RXD1
        PB11     ------> ETH_TX_EN
        PB12     ------> ETH_TXD0
        PB13     ------> ETH_TXD1
        */
        GPIO_InitStruct.Pin = GPIO_PIN_1;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

        GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        GPIO_InitStruct.Pin = GPIO_PIN_2;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

        GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
        GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

        GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

       // DP83848 INT引脚
        GPIO_InitStruct.Pin = GPIO_PIN_6;
        GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;              /* 上升沿触发 */
        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);                  /* WKUP配置为上升沿触发 */

        HAL_NVIC_SetPriority(EXTI9_5_IRQn, 2, 0);                /* 抢占2,子优先级0 */
        HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);                        /* 使能中断线0 */

        /* Peripheral interrupt init */
        HAL_NVIC_SetPriority(ETH_IRQn, 3, 0);
        HAL_NVIC_EnableIRQ(ETH_IRQn);
    }
}

DP83848初始化流程如下:
int DP83848_Init(void)
{
    uint32_t uid;
    uint32_t regvalue = 0;
    HAL_StatusTypeDef hal_eth_init_status;

    // 根据器件ID生成MAC地址
    uid = HAL_GetUIDw0() + HAL_GetUIDw1() + HAL_GetUIDw2();
    memcpy(dp83848_mac + 3, &uid, 3);

    heth.Instance             = ETH;
    heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_DISABLE;
    heth.Init.Speed           = ETH_SPEED_10M;
    heth.Init.DuplexMode      = ETH_MODE_FULLDUPLEX;
    heth.Init.PhyAddress      = DP83848_PHY_ADDRESS;
    heth.Init.MACAddr         = dp83848_mac;
    heth.Init.RxMode          = ETH_RXPOLLING_MODE;
    heth.Init.ChecksumMode    = ETH_CHECKSUM_BY_HARDWARE;
    heth.Init.MediaInterface  = ETH_MEDIA_INTERFACE_RMII;

    hal_eth_init_status       = HAL_ETH_Init(&heth);

    if (hal_eth_init_status != HAL_OK) {
        printf("PHY Init Failed!\n");
        return -1;
    }

    /**** Configure PHY to generate an interrupt when Eth Link state changes ****/
    /* Read Register Configuration */
    HAL_ETH_ReadPHYRegister(&heth, PHY_MICR, &regvalue);
    printf("1. PHY_MICR is %x\n", regvalue);

    /* Enable Interrupts */
    HAL_ETH_WritePHYRegister(&heth, PHY_MICR, PHY_MICR_INT_OE | PHY_MICR_INT_EN);

    /* Read Register Configuration */
    HAL_ETH_ReadPHYRegister(&heth, PHY_MISR, &regvalue);
    printf("3. PHY_MISR is %x\n", regvalue);

    /* Enable Interrupt on change of link status */
    HAL_ETH_WritePHYRegister(&heth, PHY_MISR, PHY_MISR_LINK_INT_EN);

    /* Initialize Tx Descriptors list: Chain Mode */
    HAL_ETH_DMATxDescListInit(&heth, dp83848_tx, &dp83848_txbuf, ETH_TXBUFNB);

    /* Initialize Rx Descriptors list: Chain Mode  */
    HAL_ETH_DMARxDescListInit(&heth, dp83848_rx, &dp83848_rxbuf, ETH_RXBUFNB);

    printf("PHY Init Succeed!\n");
    return 0;
}

INT引脚中断服务函数如下:
void EXTI9_5_IRQHandler(void)
{
    /* USER CODE BEGIN EXTI9_5_IRQn 0 */

    /* USER CODE END EXTI9_5_IRQn 0 */
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
    /* USER CODE BEGIN EXTI9_5_IRQn 1 */
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_6);
    /* USER CODE END EXTI9_5_IRQn 1 */
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
        switch(GPIO_Pin){
                case GPIO_PIN_6:
                        printf("GPIOA PIN 6 Interrupt\n");
                break;
                default:
                break;
        }
}


请各位有遇到相关问题的同学指导一下。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

25

主题

180

帖子

0

精华

高级会员

Rank: 4

积分
596
金钱
596
注册时间
2015-1-14
在线时间
152 小时
发表于 2024-1-22 11:18:04 | 显示全部楼层
我记得phy芯片有个寄存器可以读取是否有网线连接的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 13:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表