目录
使用LWIP通信原因:
最早做的项目都是RS232和上位机通信的,这样做的最大问题就是连的设备越多,线就越多,端口不够用,如果用一体机的话,还有一个问题就是链接不稳定;调试上位机软件要人命;
后来采用串口服务器这样的设备,虽然下位机还是用串口,但是一个串口服务器可以接多台设备,一个交换机又可以接多台串口服务器,但只需要一台电脑。。。。一根网线!
然而两个月前,碰到了个问题,下位机需要实时50字节/ms的速度一直传输数据给上位机,手上的串口服务器要么丢数据,要么不能实时传输,只有串口直连电脑才可以实现这个速度;也许是我买的串口服务器太差了吧;为了给公司省下2毛5分钱,但又不能走最早做项目的老路,因为一根网线联机调试实在是太方便了;
所以呢,就开启了狗咬乌龟...无从下手的道路,学历不高,技能自修,无门无派;
本来直接用LAN8742这个芯片的话,应该就没有那么坎坷了;结果不学好,为了layout好画一点,为了焊板的时候好焊点,就选了DP83848这个大封装;差一点就酿成千古恨; 用STM32H7系列的人应该都知道为什么了;
吹了这么多牛皮,下面进入正题;
DP83848原理图:
CubeIDE配置及说明
大家一定必须要注意CubeIDE的版本,1.8和最新版本1.12还是有些差异的;
CPU工作时钟根据大家的心情配置就好; 我的DP83848复位引脚是PE14;
接下来就是这两个版本的通用配置:
这个中断必须开启,不然ping不同的,
接下来需要修改lan8342.c文件 int32_t LAN8742_Init(lan8742_Object_t *pObj)
修改lan8342.c文件下的 int32_t LAN8742_GetLinkState(lan8742_Object_t *pObj)
下面是代码方便复制粘贴;
int32_t LAN8742_GetLinkState(lan8742_Object_t *pObj)
{
uint32_t readval = 0;
/* Read Status register */
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0)
{
return LAN8742_STATUS_READ_ERROR;
}
/* Read Status register again */
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0)
{
return LAN8742_STATUS_READ_ERROR;
}
if((readval & LAN8742_BSR_LINK_STATUS) == 0)
{
/* Return Link Down status */
return LAN8742_STATUS_LINK_DOWN;
}
/* Check Auto negotiaition */
if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) < 0)//读取基本控制寄存器0x00
{
return LAN8742_STATUS_READ_ERROR;
}
if((readval & LAN8742_BCR_AUTONEGO_EN) != LAN8742_BCR_AUTONEGO_EN) //未启用自动协商
{
if(((readval & LAN8742_BCR_SPEED_SELECT) == LAN8742_BCR_SPEED_SELECT) && ((readval & LAN8742_BCR_DUPLEX_MODE) == LAN8742_BCR_DUPLEX_MODE))
{
return LAN8742_STATUS_100MBITS_FULLDUPLEX;
}
else if ((readval & LAN8742_BCR_SPEED_SELECT) == LAN8742_BCR_SPEED_SELECT)
{
return LAN8742_STATUS_100MBITS_HALFDUPLEX;
}
else if ((readval & LAN8742_BCR_DUPLEX_MODE) == LAN8742_BCR_DUPLEX_MODE)
{
return LAN8742_STATUS_10MBITS_FULLDUPLEX;
}
else
{
return LAN8742_STATUS_10MBITS_HALFDUPLEX;
}
}
else /* Auto Nego enabled */
{
//DP83848
if(pObj->IO.ReadReg(pObj->DevAddr, 0x10, &readval) < 0) //DP83848,PHY状态寄存器(PHYSTS) 地址0x10
{
return LAN8742_STATUS_READ_ERROR;
}
/* Check if auto nego not done */
if((readval & 0x0010) == 0) //bit4, Auto-Negotiation Complete
{
return LAN8742_STATUS_AUTONEGO_NOTDONE;//自动协商未完成
}
if((readval & 0x0006) == 0x04)//bit2,bit1, 100 Mb/s mode,Full duplex mode
{
return LAN8742_STATUS_100MBITS_FULLDUPLEX;
}
else if ((readval & 0x0006) == 0x00)//bit2,bit1, 100 Mb/s mode,Half duplex mode.
{
return LAN8742_STATUS_100MBITS_HALFDUPLEX;
}
else if ((readval & 0x0006) == 0x06)//bit2,bit1, 10 Mb/s mode,Half duplex mode.
{
return LAN8742_STATUS_10MBITS_FULLDUPLEX;
}
else
{
return LAN8742_STATUS_10MBITS_HALFDUPLEX; //10 Mb/s mode,Half duplex mode.
}
}
}
main函数里添加 __HAL_RCC_D2SRAM3_CLK_ENABLE();
这是我在线程里增加了LED闪烁,方便确认行程是否正常
在ethernetif.c文件的 static void low_level_init(struct netif *netif)里添加DP83848复位动作
最关键的修改来了;给ETH指定发送接收地址;
下面需要手动增加缓冲区地址,Cube没有自动生成;
在STM32H743VGTX_FLASH.ld文件里
.lwip_sec (NOLOAD) : {
. = ABSOLUTE(0x30040000);
*(.RxDecripSection)
. = ABSOLUTE(0x30040060);
*(.TxDecripSection)
. = ABSOLUTE(0x30040200);
*(.RxArraySection)
} >RAM_D2 AT> FLASH
通过以上配置就可以ping通IP了
下一篇在写TCP服务器通信吧!
本人知识有限,有哪里不对,望多多包涵!