Lan8720 网线插拔状态检测_lan8720热插拔_玩转物联网的博客-程序员资料

技术标签: Lwip学习  

目的:能够实时的检测网线的插拔状态。并能够根据网线的插拔状态通知到到应用层,让应用层做相应的处理。

1.解决问题的根本方法就是看lan8720的数据手册!!!!

如果说你用过一款芯片,而没有去研究过它的数据手册时,可以说你没有用过这个芯片。

Lan8720数据手册的第48页给出了这个芯片的控制和状态寄存器资料。因为我们是要用来检测lan8720连接网线的状态,所以这个状态应该是属于Basic Status Register这个类别的。

我们跳转到这个寄存器的说明:

红色框框圈出来的是Lan8720的速度以及状态,因为这个是一款10/100M自适应的以太网芯片,所以就有了10M和100M的速度模式的检测。我们可以看到LinK Status状态位是这个寄存器的第2位,我们只需要读取这个寄存器得到的值,然后对这个值的第二位进行与1运算,该位与1得到1则说明网线连接正常,该位与1得到0则说明网线连接断开。

在刚开始验证RTT的这部分代码时,没有细看这个功能,后来想到这个问题的时候,重新看了一遍代码,发现RTT也做了这部分的检测,只是我们没有把调试日志打开,所以没有看到这部分的功能。

检测的代码如下:[摘自RTT]

/* PHY: LAN8720 */
static uint8_t phy_speed = 0;
#define PHY_LINK_MASK       (1<<0)    //1左移0位,结果还是1
#define PHY_100M_MASK       (1<<1)    //1左移1位,结果是2
#define PHY_DUPLEX_MASK     (1<<2)    //1左移2位,结果是4
static void phy_monitor_thread_entry(void *parameter)
{
    uint8_t phy_addr = 0xFF;
    uint8_t phy_speed_new = 0;

    /* phy search */
    {
        rt_uint32_t i;
        rt_uint16_t temp;

        for(i=0; i<=0x1F; i++)
        {
            temp = ETH_ReadPHYRegister(i, 0x02);

            if( temp != 0xFFFF )
            {
                phy_addr = i;
                break;
            }
        }
    } /* phy search */

    if(phy_addr == 0xFF)
    {
        STM32_ETH_PRINTF("phy not probe!\r\n");
        return;
    }
    else
    {
        STM32_ETH_PRINTF("found a phy, address:0x%02X\r\n", phy_addr);
    }

    /* RESET PHY */
    STM32_ETH_PRINTF("RESET PHY!\r\n");
    ETH_WritePHYRegister(phy_addr, PHY_BCR, PHY_Reset);
    rt_thread_delay(RT_TICK_PER_SECOND * 2);
    ETH_WritePHYRegister(phy_addr, PHY_BCR, PHY_AutoNegotiation);

    while(1)
    {
        uint16_t status  = ETH_ReadPHYRegister(phy_addr, PHY_BSR);//读取Basic Status Register的值
        STM32_ETH_PRINTF("LAN8720 status:0x%04X\r\n", status);

        phy_speed_new = 0;

        if(status & (PHY_AutoNego_Complete | PHY_Linked_Status))
        {
            uint16_t SR;

            SR = ETH_ReadPHYRegister(phy_addr, 31);
            STM32_ETH_PRINTF("LAN8720 REG 31:0x%04X\r\n", SR);

            SR = (SR >> 2) & 0x07; /* LAN8720, REG31[4:2], Speed Indication. */
            phy_speed_new = PHY_LINK_MASK;

            if((SR & 0x03) == 2)
            {
                phy_speed_new |= PHY_100M_MASK;
            }

            if(SR & 0x04)
            {
                phy_speed_new |= PHY_DUPLEX_MASK;
            }
        }

        /* linkchange */
        if(phy_speed_new != phy_speed)
        {
            if(phy_speed_new & PHY_LINK_MASK)//和1进行&运算,得1,则代表连接。否则,断开
            {
                STM32_ETH_PRINTF("link up ");

                if(phy_speed_new & PHY_100M_MASK)
                {
                    STM32_ETH_PRINTF("100Mbps");
                    stm32_eth_device.ETH_Speed = ETH_Speed_100M;
                }
                else
                {
                    stm32_eth_device.ETH_Speed = ETH_Speed_10M;
                    STM32_ETH_PRINTF("10Mbps");
                }

                if(phy_speed_new & PHY_DUPLEX_MASK)
                {
                    STM32_ETH_PRINTF(" full-duplex\r\n");
                    stm32_eth_device.ETH_Mode = ETH_Mode_FullDuplex;
                }
                else
                {
                    STM32_ETH_PRINTF(" half-duplex\r\n");
                    stm32_eth_device.ETH_Mode = ETH_Mode_HalfDuplex;
                }
                rt_stm32_eth_init((rt_device_t)&stm32_eth_device);

                /* send link up. */
                //网线正常连接,通知上层应用
                //可以根据自己的需求进行修改
                eth_device_linkchange(&stm32_eth_device.parent, RT_TRUE);
            } /* link up. */
            else
            {
                STM32_ETH_PRINTF("link down\r\n");
                /* send link down. */
                //网线断开,通知上层应用
                可以根据自己的需求进行修改
                eth_device_linkchange(&stm32_eth_device.parent, RT_FALSE);
            } /* link down. */

            phy_speed = phy_speed_new;
        } /* linkchange */

        rt_thread_delay(RT_TICK_PER_SECOND);
    } /* while(1) */
}

只需要其一个线程来实时监测即可。

如果是裸机代码,把while循环去掉,里面相关延时去掉。将其放入主程序的大循环中,定时器起一个标志定时检测即可。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u011522841/article/details/102870279

智能推荐

查找二叉树的任意节点的所有父节点_二叉树任一节点的所有父子节点_梦在未名湖畔的博客-程序员资料

该问题可以利用非递归的后序遍历加以修改一点即可完成:void GetParent(BiTree Tree,char data,char Path[]){ BiTree p = (BiTree)malloc(sizeof(tree)); BiTree IsPri = (BiTree)malloc(sizeof(tree)); int PathCount = 0; IsP

java.lang.NoClassDefFoundError: javax/servlet/ServletContext_橙子cch的博客-程序员资料

@java.lang.NoClassDefFoundError: javax/servlet/ServletContextTOCjava.lang.NoClassDefFoundError: javax/servlet/ServletContext使用idea 开发项目,启动时报如下错误"D:\Program Files\Java\jdk1.8.0_211\bin\java.exe" "-javaagent:D:\Program Files\IntelliJ IDEA Community Editi

史上最全的程序员求职渠道总结_yuwang668的博客-程序员资料

我前前后后写过多篇与程序员找工作相关的文章,比如程序员跳槽神级攻略,找工作的辟邪剑谱,任性,春节前辞职,程序员该不该考虑初创公司,这些文章都收录在我的漫谈程序员专栏里,它们从跳槽时机、跳槽原因、简历优化等不同侧面讨论了程序员找工作的那些事儿,受到很多人的关注。今天呢,我准备专门分析一下程序员求职渠道,有料是必须的,就算你搜遍互联网深挖全宇宙,也会发现这篇文章将是史上最全、最强、最有针对性的程序员求

java解析过程_【JVM系列】一步步解析java执行过程_令和时代的柯南的博客-程序员资料

对于任何一门语言,要想达到精通的水平,研究它的执行原理(或者叫底层机制)不失为一种良好的方式。在本篇文章中,将重点研究java源代码的执行原理,即从程序员编写JAVA源代码,到最终形成产品,在整个过程中,都经历了什么?每一步又是怎么执行的?执行原理又是什么?.....当然,本篇文章的粒度可能稍微侧重于宏观方面,更细粒度的技术分析,需要在接下来的该系列文章中与大家分享....一 编写java源程序j...

Android9.0无法加载http的url,net::ERR_CLEARTEXT_NOT_PERMITTED_一只小白程序员的博客-程序员资料

从Android 9.0(API级别28)开始,默认情况下禁用明文支持。因此http的url均无法在webview中加载附上我使用的解决办法:&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&amp;lt;manifest ...&amp;gt; &amp;lt;uses-permission android:name=&quot;android.permission...

使用HTML5+CSS+JS框架有那些好处_js+css的优势_qianduankuangjia的博客-程序员资料

相信很多程序猿朋友都用过框架,不过你是否知道你用的是HTML框架、CSS框架还是JS框架,其实这都不重要,重要的是使用框架的目的是什么?是不是节约了开发项目时间陈本,这事多么伟大的一箱工程,根据几年前的一片文章中写到,使用前端框架的优劣势,从这边文章中整理出一部分分享给大家。

随便推点

Android-APP隐私合规检测Camille(安卓root模拟器)_camille运行没作用_Alex_z0897的博客-程序员资料

根据隐私合规的场景,辅助检查是否符合隐私合规标准.android studio模拟器(root权限)python3环境下载camille下载pc端frida(pip)手工下载安卓端frida

初识前端框架Vue.js_初识vue.js在哪写_Chasel IBM的博客-程序员资料

Vue.js作为目前最热门最具前景的前端框架之一,其提供了一种帮助我们快速构建并开发前端项目的新的思维模式。本文旨在帮助大家认识Vue.js,了解Vue.js的开发流程,并进一步理解如何通过Vue.js来构建一个中大型的前端项目,同时做好相应的部署与优化工作。文章将以PPT图片附加文字介绍的形式展开,不会涉及知识点的具体代码,点到为止。有兴趣的同学可以查看相应的文档进行了解。Vue.js简介从上图...

极速SpringCloud开发-Dalston版本_spring cloud dalston_白黑黑白的博客-程序员资料

服务的注册与发现(Eureka )在这里,我们需要用的的组件上Spring Cloud Netflix的Eureka ,eureka是一个服务注册和发现模块。Eureka介绍官方的介绍在这里Eureka wiki。Eureka是Netflix开源的一个RESTful服务,主要用于服务的注册发现。Eureka由两个组件组成:Eureka服务器和Eureka客户端。Eureka服务器用作服务注...

深度学习Deep Learning 101_with the explosion of big data——a new product_GarfieldEr007的博客-程序员资料

Deep learning has become something of a buzzword in recent years with the explosion of 'big data', 'data science', and their derivatives mentioned in the media. Justifiably, deep learning approaches h

Nt vs. Zw - Clearing Confusion On The Native API _yebikangfu的博客-程序员资料

The NT native API is nothing new. It’s been discussed ad nauseum, it’s been exploited by umpteen different utilities, and portions of it have even migrated into the realm of the fully documented and s

推荐文章

热门文章

相关标签