这里讲一下lan8720网卡驱动。
其实也没啥好讲的,参考原子哥和野火的lwip教程中的裸机移植部分就可以了。
我直接贴代码了,结合lwip的教程以及stm32手册中的以太网部分,消化理解吧。
提供配套CUBE工程和技术支持。SOEM协议栈使用1.3.1版本。可配套NUCLEO-H743ZI开发板使用。支持DC同步。可配合汇川IS620N、三洋RS3、赛孚德ASD620B、埃斯顿ProNet、迈信EP3E、台达A2-E、伟创SD700、松下A5B/A6B和欧姆龙G5系列驱动器使用

有几点说一下:
1.以太网接收报文用的时轮询的方式,不是中断。即(ETH_Handler.Init.RxMode = ETH_RXPOLLING_MODE;//轮询接收模式)
2.注意lan8720的时钟配置,不同硬件平台是有差异的,注意看lan8720的芯片手册和原理图。


3.原子的f767开发板是有外部SDRAM的,以太网数据帧用的是外部SDRAM的空间。


4.如果用的是stm32片内的SDRAM的话,可以这么写:

5.如果是stm32f1x、stm32f4x之类的芯片,可以把下面红线部分删掉。

6.mac配置工作在混杂模式

基于原子f767开发板的代码
ETH_HandleTypeDef ETH_Handler; //以太网句柄

ETH_DMADescTypeDef *DMARxDscrTab; //以太网DMA接收描述符数据结构体指针
ETH_DMADescTypeDef *DMATxDscrTab; //以太网DMA发送描述符数据结构体指针
uint8_t *Rx_Buff; //以太网底层驱动接收buffers指针
uint8_t *Tx_Buff; //以太网底层驱动发送buffers指针

u32 interrupt_state(void)
{
int state;
state=(ETH_Handler.Instance->DMAIER);
return (u32)state;
}

//LAN8720初始化
//返回值:0,成功;
// 其他,失败
u8 LAN8720_Init(void)
{
// uint8_t macaddress[6]= { MAC_ADDR0, MAC_ADDR1, MAC_ADDR2, MAC_ADDR3, MAC_ADDR4, MAC_ADDR5 };

 u32 sn0;sn0=*(vu32*)(0x1FF0F420);//获取STM32的唯一ID的前24位作为MAC地址后三字节u8 macaddress[6];//MAC地址设置(高三字节固定为:2.0.0,低三字节用STM32唯一ID)macaddress[0]=2;//高三字节(IEEE称之为组织唯一ID,OUI)地址固定为:2.0.0macaddress[1]=0;macaddress[2]=0;macaddress[3]=(sn0>>16)&0XFF;//低三字节用STM32的唯一IDmacaddress[4]=(sn0>>8)&0XFFF;macaddress[5]=sn0&0XFF; INTX_DISABLE();                         //关闭所有中断,复位过程不能被打断!
PCF8574_WriteBit(ETH_RESET_IO,1);       //硬件复位
delay_ms(100);
PCF8574_WriteBit(ETH_RESET_IO,0);       //复位结束
delay_ms(100);
INTX_ENABLE();                          //开启所有中断ETH_Handler.Instance=ETH;

// ETH_Handler.Init.AutoNegotiation=ETH_AUTONEGOTIATION_ENABLE;//使能自协商模式
ETH_Handler.Init.AutoNegotiation=ETH_AUTONEGOTIATION_DISABLE;
ETH_Handler.Init.Speed=ETH_SPEED_100M;//速度100M,如果开启了自协商模式,此配置就无效
ETH_Handler.Init.DuplexMode=ETH_MODE_FULLDUPLEX;//全双工模式,如果开启了自协商模式,此配置就无效
ETH_Handler.Init.PhyAddress=LAN8720_PHY_ADDRESS;//LAN8720地址
ETH_Handler.Init.MACAddr=macaddress; //MAC地址
// ETH_Handler.Init.RxMode=ETH_RXINTERRUPT_MODE; //中断接收模式
ETH_Handler.Init.RxMode = ETH_RXPOLLING_MODE;//轮询接收模式
ETH_Handler.Init.ChecksumMode=ETH_CHECKSUM_BY_HARDWARE;//硬件帧校验
ETH_Handler.Init.MediaInterface=ETH_MEDIA_INTERFACE_RMII;//RMII接口
// if(HAL_ETH_Init(&ETH_Handler)==HAL_OK) return 0; //成功
// else return 1; //失败

 if(HAL_ETH_Init(&ETH_Handler)==HAL_OK) {HAL_ETH_DMATxDescListInit(&ETH_Handler,DMATxDscrTab,Tx_Buff,ETH_TXBUFNB);//初始化发送描述符HAL_ETH_DMARxDescListInit(&ETH_Handler,DMARxDscrTab,Rx_Buff,ETH_RXBUFNB);//初始化接收描述符/* 使能 MAC 和 DMA 发送和接收 */HAL_ETH_Start(&ETH_Handler);return 0;   //成功}else return 1;  //失败

}

//ETH底层驱动,时钟使能,引脚配置
//此函数会被HAL_ETH_Init()调用
//heth:以太网句柄
void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
{
GPIO_InitTypeDef GPIO_Initure;

__HAL_RCC_ETH_CLK_ENABLE();       //开启ETH时钟
__HAL_RCC_GPIOA_CLK_ENABLE();           //开启GPIOA时钟__HAL_RCC_GPIOB_CLK_ENABLE();            //开启GPIOB时钟
__HAL_RCC_GPIOC_CLK_ENABLE();           //开启GPIOC时钟
__HAL_RCC_GPIOG_CLK_ENABLE();           //开启GPIOG时钟/*网络引脚设置 RMII接口
ETH_MDIO -------------------------> PA2
ETH_MDC --------------------------> PC1
ETH_RMII_REF_CLK------------------> PA1
ETH_RMII_CRS_DV ------------------> PA7
ETH_RMII_RXD0 --------------------> PC4
ETH_RMII_RXD1 --------------------> PC5
ETH_RMII_TX_EN -------------------> PB11
ETH_RMII_TXD0 --------------------> PG13
ETH_RMII_TXD1 --------------------> PG14
ETH_RESET-------------------------> PCF8574扩展IO*///PA1,2,7
GPIO_Initure.Pin=GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7;
GPIO_Initure.Mode=GPIO_MODE_AF_PP;          //推挽复用
GPIO_Initure.Pull=GPIO_NOPULL;              //不带上下拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH;         //高速
GPIO_Initure.Alternate=GPIO_AF11_ETH;       //复用为ETH功能
HAL_GPIO_Init(GPIOA,&GPIO_Initure);         //初始化//PB11
GPIO_Initure.Pin=GPIO_PIN_11;               //PB11
HAL_GPIO_Init(GPIOB,&GPIO_Initure);         //始化//PC1,4,5
GPIO_Initure.Pin=GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5; //PC1,4,5
HAL_GPIO_Init(GPIOC,&GPIO_Initure);         //初始化//PG13,14
GPIO_Initure.Pin=GPIO_PIN_13|GPIO_PIN_14;   //PG13,14
HAL_GPIO_Init(GPIOG,&GPIO_Initure);         //初始化

}

//读取PHY寄存器值
u32 LAN8720_ReadPHY(u16 reg)
{
u32 regval;
HAL_ETH_ReadPHYRegister(&ETH_Handler,reg,&regval);
return regval;
}

//向LAN8720指定寄存器写入值
//reg:要写入的寄存器
//value:要写入的值
void LAN8720_WritePHY(u16 reg,u16 value)
{
u32 temp=value;
HAL_ETH_ReadPHYRegister(&ETH_Handler,reg,&temp);
}

//得到8720的速度模式
//返回值:
//001:10M半双工
//101:10M全双工
//010:100M半双工
//110:100M全双工
//其他:错误.
u8 LAN8720_Get_Speed(void)
{
u8 speed;
speed=((LAN8720_ReadPHY(31)&0x1C)>>2); //从LAN8720的31号寄存器中读取网络速度和双工模式
return speed;
}

extern void lwip_pkt_handle(void); //在lwip_comm.c里面定义

//中断服务函数
void ETH_IRQHandler(void)
{
printf(“进入中断\r\n”);
while(ETH_GetRxPktSize(ETH_Handler.RxDesc))
{
printf(“接收到数据\r\n”);
// lwip_pkt_handle();//处理以太网数据,即将数据提交给LWIP
}
//清除中断标志位
__HAL_ETH_DMA_CLEAR_IT(&ETH_Handler,ETH_DMA_IT_NIS);
__HAL_ETH_DMA_CLEAR_IT(&ETH_Handler,ETH_DMA_IT_R);

}

//获取接收到的帧长度
//DMARxDesc:接收DMA描述符
//返回值:接收到的帧长度
u32 ETH_GetRxPktSize(ETH_DMADescTypeDef *DMARxDesc)
{
u32 frameLength = 0;
if(((DMARxDesc->Status&ETH_DMARXDESC_OWN)(uint32_t)RESET) &&
((DMARxDesc->Status&ETH_DMARXDESC_ES)(uint32_t)RESET) &&
((DMARxDesc->Status&ETH_DMARXDESC_LS)!=(uint32_t)RESET))
{
frameLength=((DMARxDesc->Status&ETH_DMARXDESC_FL)>>ETH_DMARXDESC_FRAME_LENGTHSHIFT);
}
return frameLength;
}

//为ETH底层驱动申请内存
//返回值:0,正常
// 其他,失败
u8 ETH_Mem_Malloc(void)
{
DMARxDscrTab=mymalloc(SRAMDTCM,ETH_RXBUFNBsizeof(ETH_DMADescTypeDef));//申请内存
DMATxDscrTab=mymalloc(SRAMDTCM,ETH_TXBUFNB
sizeof(ETH_DMADescTypeDef));//申请内存
Rx_Buff=mymalloc(SRAMDTCM,ETH_RX_BUF_SIZEETH_RXBUFNB); //申请内存
Tx_Buff=mymalloc(SRAMDTCM,ETH_TX_BUF_SIZE
ETH_TXBUFNB); //申请内存
if(!(u32)&DMARxDscrTab||!(u32)&DMATxDscrTab||!(u32)&Rx_Buff||!(u32)&Tx_Buff)
{
ETH_Mem_Free();
return 1; //申请失败
}
return 0; //申请成功
}

//释放ETH 底层驱动申请的内存
void ETH_Mem_Free(void)
{
myfree(SRAMDTCM,DMARxDscrTab);//释放内存
myfree(SRAMDTCM,DMATxDscrTab);//释放内存
myfree(SRAMDTCM,Rx_Buff); //释放内存
myfree(SRAMDTCM,Tx_Buff); //释放内存
}

int EthWrPacket(void* pBuff, int Len)
{
uint8_t* pDmaBuff;
HAL_StatusTypeDef HalStatus;
/* Clean and Invalidate data cache /
SCB_CleanInvalidateDCache();
if ((ETH_Handler.TxDesc->Status & ETH_DMATXDESC_OWN) == (uint32_t)RESET)
{
pDmaBuff = (uint8_t
)(ETH_Handler.TxDesc->Buffer1Addr);
memcpy (pDmaBuff, pBuff, Len);
HalStatus = HAL_ETH_TransmitFrame(&ETH_Handler, Len);
if (HalStatus != HAL_OK)
{
printf (“HAL_ETH_TransmitFrame err %d\n”, HalStatus);
return NULL;
}
return Len;
}
else
{
return NULL;
}
}

int EthRdPacket(void* pBuff)
{
int Len;
uint8_t* pDmaBuff;
HAL_StatusTypeDef HalStatus;
HalStatus = HAL_ETH_GetReceivedFrame(&ETH_Handler); // check if a packet has been received
/* Clean and Invalidate data cache /
SCB_CleanInvalidateDCache();
if (HalStatus == HAL_OK) // packet received
{
Len = ETH_Handler.RxFrameInfos.length; // packet lenght
pDmaBuff = (uint8_t
)ETH_Handler.RxFrameInfos.buffer; // DMA buffer pointe
memcpy (pBuff, pDmaBuff, Len); // read the data
ETH_Handler.RxFrameInfos.FSRxDesc->Status |= ETH_DMARXDESC_OWN;// release the descriptor
ETH_Handler.RxFrameInfos.SegCount = 0; // reset segment count
return Len; // return the number of bytes read
}
else
{
return NULL; // no packet received
}
}

SOEM方案 STM32H743 EtherCAT主站 基于STM32H743芯片和SOEM的EtherCAT主站源码相关推荐

  1. 基于JAVA中小学教师培训管理系统计算机毕业设计源码+系统+数据库+lw文档+部署

    基于JAVA中小学教师培训管理系统计算机毕业设计源码+系统+数据库+lw文档+部署 基于JAVA中小学教师培训管理系统计算机毕业设计源码+系统+数据库+lw文档+部署 本源码技术栈: 项目架构:B/S ...

  2. 基于OpenCV的人脸识别自助商店(源码&部署视频)

    1.模块功能介绍 实现人脸识别模块.人脸登录与注册功能.商店显示和用户余额页显示功能 用GUl图形界面实现(pyqt)语言python windows下软件pycharm 1.用户登录模块:刷脸登录 ...

  3. Python基于OpenCV的人脸识别自助商店(源码&部署视频)

    1.模块功能介绍 实现人脸识别模块.人脸登录与注册功能.商店显示和用户余额页显示功能 用GUl图形界面实现(pyqt)语言python windows下软件pycharm 1.用户登录模块:刷脸登录 ...

  4. Python基于OpenCV监控老鼠蟑螂检测系统[完整源码&部署教程]

    1.视频演示: [项目分享]Python基于OpenCV监控老鼠蟑螂检测系统[完整源码&部署教程]_哔哩哔哩_bilibili 2.图片演示: 3.明厨亮灶: 餐饮企业的厨房卫生状况一直饱受消 ...

  5. 基于ET框架致敬LOL的Moba游戏源码,包含完整的客户端与服务端交互

    运行环境 编辑器:Unity 2020.3.12 LTS 客户端:.Net Framework 4.7.2 IDE:JetBrain Rider 2020 服务端:.Net Core 3.1 已实现功 ...

  6. 基于JAVA中小学生心理资讯系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署

    基于JAVA中小学生心理资讯系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署 基于JAVA中小学生心理资讯系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署 本源码技术栈: ...

  7. php 本地mysql 代码_基于本地数据库的 IP 地址查询 PHP 源码

    * 纯真 IP 数据库查询 * * 参考资料: * - 纯真 IP 数据库 http://www.cz88.net/ip/ * - PHP 读取纯真IP地址数据库 http://ju.outofmem ...

  8. 基于JAVA-超市会员积分管理系统-计算机毕业设计源码+系统+lw文档+部署

    基于JAVA-超市会员积分管理系统-计算机毕业设计源码+系统+lw文档+部署 技术栈 项目架构:B/S架构 开发语言:Java语言 开发软件:idea eclipse 前端技术:Layui.HTML. ...

  9. 【音乐检索】基于matlab音乐检索系统【含Matlab源码 435期】

    一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[音乐检索]基于matlab音乐检索系统[含Matlab源码 435期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: 付费专栏 ...

  10. 【图像修复】基于matlab损坏图像修复【含Matlab源码 731期】

    一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[图像修复]基于matlab损坏图像修复[含Matlab源码 731期] 点击上面蓝色字体,直接付费下载,即可. 获取代码方式2: 付费专栏 ...

最新文章

  1. 嵌入式视觉领域的机器学习
  2. 我是一个机箱 《转载》
  3. 适合python的笔记本配置-jupyter之配置自己喜欢的python环境
  4. 基于内容的图像检索CBIR部分数据库和源代码资料
  5. vsftpd的不同安装方式及服务控制脚本
  6. Vue-Cli Error: EACCES: permission denied 解决方案
  7. 【转】Dynamics 365中开发和注册插件介绍
  8. vue 仿二手交易app_Vue项目开发-仿蘑菇街电商APP
  9. C++ UNICODE 编程从入门到精通
  10. stm32f1的存储器与复位
  11. 直播预告丨Oracle 12C~19C统计信息的最佳实践
  12. Cloudarrow V2.0 正式发布!
  13. Bitset的一些总结
  14. ubuntu系统下如何查看opencv版本
  15. 教你制作一张漂亮的城市分布图 比如加油站分布地图
  16. 感知机学习:鸢尾花二分类
  17. 学习Python人工智能前景如何
  18. FANUC机器人Config系统配置中各项参数的功能描述及设定
  19. 知到网课异彩纷呈的民族文化期末考试单元试题答案分享!
  20. 二分查找板子(check()函数)

热门文章

  1. ubuntu 清空回收站
  2. 小程序wx.request通过post方式提交数据给服务器-小程序支付开发教程
  3. RL策略梯度方法之(十八): Importance Weighted Actor-Learner Architecture (IMPALA)
  4. c# winform 无边框窗体 移动办法
  5. Docker【部署 02】可视化工具DockerUI和Shipyard安装使用实例
  6. HTML5实现点击触发灯泡开关
  7. 微信开发生成测试签名--signature,并使用微信jssdk获取位置
  8. 获取高德POI(关键词搜索法 多边形搜索法 周边搜索法)综合运用 2022新版高德poi下载
  9. 第三周作业-循环与判断语句(网络131黄宇倩)
  10. 使用GANs生成时间序列数据:DoppelGANger论文详解