当前位置: 首页 > article >正文

stm32 移植RTL8201F(正点原子例程为例)

最近在工作中需要使用RTL8201F,在网上找了很多帖子,没有找到合适的,自己翻资料移植了一个。
模板工程使用的是正点原子的f407探索版的例程,原子使用的是LAN8720,需要把他的驱动修改成为我们自己用的RTL8201F。
1.将PHY_TYPE改成我们自己需要的RTL8201
图片
2.根据RTL8201芯片手册修改SR寄存器速度和模式
在这里插入图片描述

我们可以从手册看到,SR寄存器地址和speed和DUPLEX的比特位
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

根据手册修改成我们需要的值,
定义PHY_ID寄存器地址
在这里插入图片描述通过读取该地址查找我们的PHY地址和判断PHY是否启动
定义页选择寄存器、RMII模式设置寄存器、省电模式寄存器
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
相关定义如下
在这里插入图片描述
3.在PHY初始化设置位置修改成我们自己的代码
在这里插入图片描述

  //查找PHY_addr
  for(int i = 0 ;i <31;i++)
  {
		phyreg = 0;
		heth->Init.PhyAddress = i;
		HAL_ETH_ReadPHYRegister(heth, PHY_ID, &phyreg);
		if(phyreg == 0x1c)
		{
			heth->Init.PhyAddress = i;
			break;
		}
		HAL_Delay(PHY_RESET_DELAY);
  }
  
 //设置页寄第七页准备配置RMII模式
  if((HAL_ETH_WritePHYRegister(heth,PHY_PAGE_ADDR,PHY_PAGE_7)) != HAL_OK)
{
		/* In case of write timeout */
		err = ETH_ERROR;

		/* Config MAC and DMA */
		ETH_MACDMAConfig(heth, err);

		/* Set the ETH peripheral state to READY */
		heth->State = HAL_ETH_STATE_READY;

		/* Return HAL_ERROR */
		return HAL_ERROR;
}

在这里插入图片描述

我的板子需要PHY提供REF_CLK,大家如果有外部时钟,可以直接填手册上写的7FFB


//设置RMII模式
if((HAL_ETH_WritePHYRegister(heth,PHY_PAGE_7_MODE,0x6ffb)) != HAL_OK)
	{
		/* In case of write timeout */
		err = ETH_ERROR;

		/* Config MAC and DMA */
		ETH_MACDMAConfig(heth, err);

		/* Set the ETH peripheral state to READY */
		heth->State = HAL_ETH_STATE_READY;

		/* Return HAL_ERROR */
		return HAL_ERROR;
	} 
回到第0if((HAL_ETH_WritePHYRegister(heth,PHY_PAGE_ADDR,0)) != HAL_OK)
{
	/* In case of write timeout */
	err = ETH_ERROR;

	/* Config MAC and DMA */
	ETH_MACDMAConfig(heth, err);

	/* Set the ETH peripheral state to READY */
	heth->State = HAL_ETH_STATE_READY;
	printf("ETH reset timeout!! \r\n");
	/* Return HAL_ERROR */
	return HAL_ERROR;
} 

配置PMSR寄存器
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/3e5120700be04172a24269fb93c76cae.webp#pic_center)

我这里的REF_CLK是OUTPUT模式需要关闭省电模式,如果大家不是则不需要配置该项
//

```c
if((HAL_ETH_WritePHYRegister(heth,PHY_PSMR,0x8000)) != HAL_OK)
{
	/* In case of write timeout */
	err = ETH_ERROR;

	/* Config MAC and DMA */
	ETH_MACDMAConfig(heth, err);

	/* Set the ETH peripheral state to READY */
	heth->State = HAL_ETH_STATE_READY;
	printf("ETH reset timeout!! \r\n");
	/* Return HAL_ERROR */
	return HAL_ERROR;
} 

4.配置ETH模式
在lwip_comm.c里的lwip_link_thread
这个函数是检测网线连接情况的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通过读取link status来判断网线是否插入
当有网线插入时,启动PHY自协模式,等待自协完成,读取PHY速度和双工模式,将对应的模式配置到ETH中,启动ETH
//

void lwip_link_thread( void * argument )
{
    uint32_t regval = 0;
    struct netif *netif = (struct netif *) argument;
    int link_again_num = 0;

    while(1)
    {
        /* 读取PHY状态寄存器,获取链接信息 */
        HAL_ETH_ReadPHYRegister(&g_eth_handler,PHY_BSR, &regval);

        /* 判断链接状态 */
        if((regval & PHY_LINKED_STATUS) == 0)
        {
            g_lwipdev.link_status = LWIP_LINK_OFF;

            link_again_num ++ ;

            if (link_again_num >= 2)                    /* 网线一段时间没有插入 */
            {
                continue;
            }
            else                                        /* 关闭虚拟网卡及以太网中断 */
            {
#if LWIP_DHCP                                           /* 如果使用DHCP的话 */
                g_lwip_dhcp_state = LWIP_DHCP_LINK_DOWN;

                dhcp_stop(netif);
#endif
                HAL_ETH_Stop(&g_eth_handler);
                netif_set_down(netif);
                netif_set_link_down(netif);
            }
        }
        else                                            /* 网线插入检测 */
        {
            link_again_num = 0;
//			printf("检测到有网线插入 \r\n");
            if (g_lwipdev.link_status == LWIP_LINK_OFF)/* 开启以太网及虚拟网卡 */
            {
				HAL_ETH_WritePHYRegister(&g_eth_handler, PHY_BCR, PHY_AUTONEGOTIATION);
				uint8_t timeout = 100;
				do{
					HAL_ETH_ReadPHYRegister(&g_eth_handler,PHY_BSR, &regval);
					vTaskDelay(1);
					timeout--;
					if(timeout==0)
					{
						g_lwipdev.link_status = LWIP_LINK_OFF;
						goto exit;
					}
				}while(((regval & PHY_AUTONEGO_COMPLETE) != PHY_AUTONEGO_COMPLETE));

				HAL_ETH_ReadPHYRegister(&g_eth_handler, PHY_SR, &regval);
				if(regval & PHY_SPEED_STATUS)
				{
					g_eth_handler.Init.Speed = ETH_SPEED_100M;
				}
				else
				{
					g_eth_handler.Init.Speed = ETH_SPEED_10M;
				}

				if(regval & PHY_DUPLEX_STATUS)
				{
					g_eth_handler.Init.DuplexMode = ETH_MODE_FULLDUPLEX;

				}
				else
				{
					g_eth_handler.Init.DuplexMode = ETH_MODE_HALFDUPLEX;
				}
                g_lwipdev.link_status = LWIP_LINK_ON;
                HAL_ETH_Start(&g_eth_handler);
                netif_set_up(netif);
                netif_set_link_up(netif);
				exit:;
            }
        }

        vTaskDelay(100);
    }
}

5.设置IP
正点原子的工程默认打开DHCP,如果想使用静态IP需要在,lwipopts.h关闭
在这里插入图片描述

在lwip_comm.c的lwip_comm_default_ip_set函数设置成自己需要的ip
在这里插入图片描述
在这里插入图片描述

6.测试
以上步骤做完之后,编译程序下载到板子里面,我们通过串口助手可以查看到初始化信息
在这里插入图片描述

打开命令行PING 一下看看
在这里插入图片描述

可以ping通的
我们继续使用网络助手
在这里插入图片描述

可以连接上
在这里插入图片描述

串口助手页提示有ip连接到
在这里插入图片描述

我们的移植工作就完成了。


http://www.kler.cn/a/470780.html

相关文章:

  • visual studio 自动调整代码格式的问题:
  • 性能测试01|性能测试理论
  • Python编程实例-特征向量与特征值编程实现
  • 【算法】查找与排序
  • 大数据组件(三)快速入门实时计算平台Dinky
  • 什么样的人适合从事FPGA开发的工作?
  • Easyexcel-4.0.3读取文件内容时遇到“java.lang.ClassNotFoundException”
  • 《从入门到精通:蓝桥杯编程大赛知识点全攻略》(二)-递归实现组合型枚举、带分数问题
  • libaom 源码分析线程结构
  • uni-app 页面生命周期及组件生命周期汇总(Vue2、Vue3)
  • 特征点检测与匹配——MATLAB R2022b
  • 2025资源从哪里来!
  • vue3-dom-diff算法
  • Postman接口测试02|接口用例设计
  • 云原生周刊:K8s 生态系统的五大趋势预测
  • IDEA中Lombok不能使用,找不到get方法
  • 乾元通渠道商中标玉溪市自然灾害应急能力提升项目
  • 【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
  • Flink-CDC 全面解析
  • 【pytorch-lightning】架构一览
  • 复杂园区网基本分支的构建
  • 工控主板ESM7000/6800E支持远程桌面控制
  • GolangWeb开发-好用的HTTP客户端httplib(beego)
  • 对智能手表进行逆向工程
  • 数据结构:二叉搜索树详解
  • 搭建SSL邮件服务器