OpenEdv-开源电子网

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

STM32F103ZET6+ENC28J60+LWIP实现UDP组播

[复制链接]

6

主题

69

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1786
金钱
1786
注册时间
2015-4-20
在线时间
258 小时
发表于 2017-5-4 18:32:17 | 显示全部楼层 |阅读模式
移植正点原子的UDP通信历程。
1.将ENC28J60_Write(ERXFCON,ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);//能实现UDP,TCP的收发。但组播数据不行。

   修改为ENC28J60_Write(ERXFCON,ERXFCON_CRCEN);//实现组播

2.打开LWIP中的IGMP。在opt.h文件中    #define LWIP_IGMP                       1

3.在ethernetif.c中的static err_t low_level_init(struct netif *netif)中,添加NETIF_FLAG_IGMP

netif->flags = NETIF_FLAG_BROADCAST|NETIF_FLAG_ETHARP|NETIF_FLAG_LINK_UP|NETIF_FLAG_IGMP;//添加IGMP

4.在lwip_comm.c中的void lwip_periodic_handle()中加入

#if LWIP_IGMP
        if(lwip_localtime-IGMPTimer >= IGMP_TMR_INTERVAL)
        {
                IGMPTimer = lwip_localtime;
                    igmp_tmr();
         }
#endif

周期性处理igmp_tmr();函数

5.UDP初始化

void Init_UDP_Server(void)
{
    IP4_ADDR(&ipgroup, 224,0,0,50);//组播IP地址  
#if LWIP_IGMP  
    igmp_joingroup(IP_ADDR_ANY,(struct ip_addr *)(&ipgroup));//组播加入当前  
#endif  
    udp_server_pcb = udp_new();  
    if(udp_server_pcb!=NULL){  
        udp_bind(udp_server_pcb,IP_ADDR_ANY,9999);//组播端口  
        udp_recv(udp_server_pcb,udp_demo_recv,NULL);//接收回调函数  
    }  
}

6.添加组播发送函数

void multicast_send_data(unsigned char * data,unsigned short len)  
{  
    struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT,len, PBUF_RAM);  
    memcpy(p->payload, data, len);
        udp_sendto(udp_server_pcb, p,(struct ip_addr *) (&ipgroup),9999);  
    pbuf_free(p);  
}

7.UDP接受回调函数

//UDP回调函数
void udp_demo_recv(void *arg,struct udp_pcb *upcb,struct pbuf *p,struct ip_addr *addr,u16_t port)
{
        u32 data_len = 0;
        struct pbuf *q;
        if(p!=NULL)        //接收到不为空的数据时
        {
                memset(udp_demo_recvbuf,0,UDP_DEMO_RX_BUFSIZE);  //数据接收缓冲区清零
                for(q=p;q!=NULL;q=q->next)  //遍历完整个pbuf链表
                {
                        //判断要拷贝到UDP_DEMO_RX_BUFSIZE中的数据是否大于UDP_DEMO_RX_BUFSIZE的剩余空间,如果大于
                        //的话就只拷贝UDP_DEMO_RX_BUFSIZE中剩余长度的数据,否则的话就拷贝所有的数据
                        if(q->len > (UDP_DEMO_RX_BUFSIZE-data_len)) memcpy(udp_demo_recvbuf+data_len,q->payload,(UDP_DEMO_RX_BUFSIZE-data_len));//拷贝数据
                        else memcpy(udp_demo_recvbuf+data_len,q->payload,q->len);
                        data_len += q->len;         
                        if(data_len > UDP_DEMO_RX_BUFSIZE) break; //超出TCP客户端接收数组,跳出       
                }
                upcb->remote_ip=*addr;                                 //记录远程主机的IP地址
                upcb->remote_port=port;                          //记录远程主机的端口号
                lwipdev.remoteip[0]=upcb->remote_ip.addr&0xff;                 //IADDR4
                lwipdev.remoteip[1]=(upcb->remote_ip.addr>>8)&0xff; //IADDR3
                lwipdev.remoteip[2]=(upcb->remote_ip.addr>>16)&0xff;//IADDR2
                lwipdev.remoteip[3]=(upcb->remote_ip.addr>>24)&0xff;//IADDR1
                udp_demo_flag|=1<<6;        //标记接收到数据了
                pbuf_free(p);//释放内存
        }else
        {
                udp_disconnect(upcb);
                udp_demo_flag &= ~(1<<5);        //标记连接断开
        }
}

8.编译会有几个错误,需要在def.h中加入

#define LWIP_RAND   rand

在lwipopts.h中

#define MEMP_NUM_SYS_TIMEOUT    6

在igmp.h中将group->timer = (LWIP_RAND() % (max_time - 1)) + 1;改为

group->timer = max_time + 1;

9.编译通过后运行,监听组播地址是224.0.0.50端口号是9999






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

使用道具 举报

6

主题

69

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1786
金钱
1786
注册时间
2015-4-20
在线时间
258 小时
 楼主| 发表于 2017-5-4 18:34:46 | 显示全部楼层
回复 支持 反对

使用道具 举报

6

主题

69

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1786
金钱
1786
注册时间
2015-4-20
在线时间
258 小时
 楼主| 发表于 2017-5-4 18:35:53 | 显示全部楼层
程序源码

STM32_ENC28J60.rar

6.47 MB, 下载次数: 1139

回复 支持 反对

使用道具 举报

17

主题

465

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2126
金钱
2126
注册时间
2013-1-11
在线时间
501 小时
发表于 2017-6-8 21:42:41 | 显示全部楼层
回复 支持 反对

使用道具 举报

16

主题

107

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
331
金钱
331
注册时间
2015-12-3
在线时间
54 小时
发表于 2017-10-16 17:42:24 | 显示全部楼层
学习了
回复 支持 反对

使用道具 举报

0

主题

11

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2017-6-19
在线时间
4 小时
发表于 2020-2-12 20:37:00 | 显示全部楼层
楼主大爱
回复 支持 反对

使用道具 举报

0

主题

11

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2017-6-19
在线时间
4 小时
发表于 2020-2-12 20:37:37 | 显示全部楼层
大爱楼主,谢分享
回复 支持 反对

使用道具 举报

0

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
62
金钱
62
注册时间
2020-5-5
在线时间
14 小时
发表于 2020-5-15 09:10:45 | 显示全部楼层
mark一下
回复 支持 反对

使用道具 举报

0

主题

31

帖子

0

精华

高级会员

Rank: 4

积分
501
金钱
501
注册时间
2014-12-8
在线时间
104 小时
发表于 2021-4-25 13:45:46 | 显示全部楼层
楼主,我现在也在测试组播功能,出现了只能接收10次数据的现象,超过10次,就无反应,遇到过类似的问题没
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-5-29 11:22

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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