OpenEdv-开源电子网

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

uip主动发数据

[复制链接]

15

主题

88

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2012-12-5
在线时间
1 小时
发表于 2014-5-7 20:19:07 | 显示全部楼层 |阅读模式
5金钱
目前正在做个网络相关的项目,用的uip。现在遇到个问题,当产生数据时不知道怎样直接将数据发送到网络上
目前知道一种方法是利用uip的轮询,当定时器超时时可以向网络上发数据。但是我需要一有数据立马发送,怎样才能做到?
各位大大有懂uip的吗?可否指点一二。

最佳答案

查看完整内容[请看2#楼]

我们的例程,就可以主动发送数据啊: [mw_shl_code=c,true]int main(void) { u8 key; u8 tcnt=0; u8 tcp_server_tsta=0XFF; u8 tcp_client_tsta=0XFF; uip_ipaddr_t ipaddr; Stm32_Clock_Init(9); //系统时钟设置 uart_init(72,9600); //串口初始化为9600 delay_init(72); //延时初始化 LED_Init(); //初始化与LED连接的硬件接口 LCD_Init(); //初始化LCD KEY_Init(); // ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165462
金钱
165462
注册时间
2010-12-1
在线时间
2114 小时
发表于 2014-5-7 20:19:08 | 显示全部楼层
我们的例程,就可以主动发送数据啊:
[mw_shl_code=c,true]int main(void) { u8 key; u8 tcnt=0; u8 tcp_server_tsta=0XFF; u8 tcp_client_tsta=0XFF; uip_ipaddr_t ipaddr; Stm32_Clock_Init(9); //系统时钟设置 uart_init(72,9600); //串口初始化为9600 delay_init(72); //延时初始化 LED_Init(); //初始化与LED连接的硬件接口 LCD_Init(); //初始化LCD KEY_Init(); //初始化按键 RTC_Init(); //初始化RTC Adc_Init(); //初始化ADC usmart_dev.init(72); //初始化USMART POINT_COLOR=RED; //设置为红色 LCD_ShowString(60,10,200,16,16,"WarShip STM32"); LCD_ShowString(60,30,200,16,16,"ENC28J60 TEST"); LCD_ShowString(60,50,200,16,16,"ATOM@ALIENTEK"); while(tapdev_init()) //初始化ENC28J60错误 { LCD_ShowString(60,70,200,16,16,"ENC28J60 Init Error!"); delay_ms(200); LCD_Fill(60,70,240,86,WHITE);//清除之前显示 }; uip_init(); //uIP初始化 LCD_ShowString(60,70,200,16,16,"KEY0:Server Send Msg"); LCD_ShowString(60,90,200,16,16,"KEY2:Client Send Msg"); LCD_ShowString(60,110,200,16,16,"IP:192.168.1.16"); LCD_ShowString(60,130,200,16,16,"MASK:255.255.255.0"); LCD_ShowString(60,150,200,16,16,"GATEWAY:192.168.1.1"); LCD_ShowString(30,200,200,16,16,"TCP RX:"); LCD_ShowString(30,220,200,16,16,"TCP TX:"); LCD_ShowString(30,270,200,16,16,"TCP RX:"); LCD_ShowString(30,290,200,16,16,"TCP TX:"); POINT_COLOR=BLUE; uip_ipaddr(ipaddr, 192,168,1,16); //设置本地设置IP地址 uip_sethostaddr(ipaddr); uip_ipaddr(ipaddr, 192,168,1,1); //设置网关IP地址(其实就是你路由器的IP地址) uip_setdraddr(ipaddr); uip_ipaddr(ipaddr, 255,255,255,0); //设置网络掩码 uip_setnetmask(ipaddr); uip_listen(HTONS(1200)); //监听1200端口,用于TCP Server uip_listen(HTONS(80)); //监听80端口,用于Web Server tcp_client_reconnect(); //尝试连接到TCP Server端,用于TCP Client while (1) { uip_polling(); //处理uip事件,必须插入到用户程序的循环体中 key=KEY_Scan(0); if(tcp_server_tsta!=tcp_server_sta)//TCP Server状态改变 { if(tcp_server_sta&(1<<7))LCD_ShowString(30,180,200,16,16,"TCP Server Connected "); else LCD_ShowString(30,180,200,16,16,"TCP Server Disconnected"); if(tcp_server_sta&(1<<6)) //收到新数据 { LCD_Fill(86,200,240,216,WHITE); //清除之前显示 LCD_ShowString(86,200,154,16,16,tcp_server_databuf); printf("TCP Server RX:%s\r\n",tcp_server_databuf);//打印数据 tcp_server_sta&=~(1<<6); //标记数据已经被处理 } tcp_server_tsta=tcp_server_sta; } if(key==KEY_RIGHT)//TCP Server 请求发送数据 { if(tcp_server_sta&(1<<7)) //连接还存在 { sprintf((char*)tcp_server_databuf,"TCP Server OK %d\r\n",tcnt); LCD_Fill(86,220,240,236,WHITE); //清除之前显示 LCD_ShowString(86,220,154,16,16,tcp_server_databuf);//显示当前发送数据 tcp_server_sta|=1<<5;//标记有数据需要发送 tcnt++; } } if(tcp_client_tsta!=tcp_client_sta)//TCP Client状态改变 { if(tcp_client_sta&(1<<7))LCD_ShowString(30,250,200,16,16,"TCP Client Connected "); else LCD_ShowString(30,250,200,16,16,"TCP Client Disconnected"); if(tcp_client_sta&(1<<6)) //收到新数据 { LCD_Fill(86,270,240,286,WHITE); //清除之前显示 LCD_ShowString(86,270,154,16,16,tcp_client_databuf); printf("TCP Client RX:%s\r\n",tcp_client_databuf);//打印数据 tcp_client_sta&=~(1<<6); //标记数据已经被处理 } tcp_client_tsta=tcp_client_sta; } if(key==KEY_LEFT)//TCP Client 请求发送数据 { if(tcp_client_sta&(1<<7)) //连接还存在 { sprintf((char*)tcp_client_databuf,"TCP Client OK %d\r\n",tcnt); LCD_Fill(86,290,240,306,WHITE); //清除之前显示 LCD_ShowString(86,290,154,16,16,tcp_client_databuf);//显示当前发送数据 tcp_client_sta|=1<<5;//标记有数据需要发送 tcnt++; } } delay_ms(1); } } //uip事件处理函数 //必须将该函数插入用户主循环,循环调用. void uip_polling(void) { u8 i; static struct timer periodic_timer, arp_timer; static u8 timer_ok=0; if(timer_ok==0)//仅初始化一次 { timer_ok = 1; timer_set(&periodic_timer,CLOCK_SECOND/2); //创建1个0.5秒的定时器 timer_set(&arp_timer,CLOCK_SECOND*10); //创建1个10秒的定时器 } uip_len=tapdev_read(); //从网络设备读取一个IP包,得到数据长度.uip_len在uip.c中定义 if(uip_len>0) //有数据 { //处理IP数据包(只有校验通过的IP包才会被接收) if(BUF->type == htons(UIP_ETHTYPE_IP))//是否是IP包? { uip_arp_ipin(); //去除以太网头结构,更新ARP表 uip_input(); //IP包处理 //当上面的函数执行后,如果需要发送数据,则全局变量 uip_len > 0 //需要发送的数据在uip_buf, 长度是uip_len (这是2个全局变量) if(uip_len>0)//需要回应数据 { uip_arp_out();//加以太网头结构,在主动连接时可能要构造ARP请求 tapdev_send();//发送数据到以太网 } }else if (BUF->type==htons(UIP_ETHTYPE_ARP))//处理arp报文,是否是ARP请求包? { uip_arp_arpin(); //当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0 //需要发送的数据在uip_buf, 长度是uip_len(这是2个全局变量) if(uip_len>0)tapdev_send();//需要发送数据,则通过tapdev_send发送 } }else if(timer_expired(&periodic_timer)) //0.5秒定时器超时 { timer_reset(&periodic_timer); //复位0.5秒定时器 //轮流处理每个TCP连接, UIP_CONNS缺省是40个 for(i=0;i<UIP_CONNS;i++) { uip_periodic(i); //处理TCP通信事件 //当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0 //需要发送的数据在uip_buf, 长度是uip_len (这是2个全局变量) if(uip_len>0) { uip_arp_out();//加以太网头结构,在主动连接时可能要构造ARP请求 tapdev_send();//发送数据到以太网 } } #if UIP_UDP //UIP_UDP //轮流处理每个UDP连接, UIP_UDP_CONNS缺省是10个 for(i=0;i<UIP_UDP_CONNS;i++) { uip_udp_periodic(i); //处理UDP通信事件 //当上面的函数执行后,如果需要发送数据,则全局变量uip_len>0 //需要发送的数据在uip_buf, 长度是uip_len (这是2个全局变量) if(uip_len > 0) { uip_arp_out();//加以太网头结构,在主动连接时可能要构造ARP请求 tapdev_send();//发送数据到以太网 } } #endif //每隔10秒调用1次ARP定时器函数 用于定期ARP处理,ARP表10秒更新一次,旧的条目会被抛弃 if(timer_expired(&arp_timer)) { timer_reset(&arp_timer); uip_arp_timer(); } } }[/mw_shl_code]

我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165462
金钱
165462
注册时间
2010-12-1
在线时间
2114 小时
发表于 2014-5-7 23:01:09 | 显示全部楼层
按下按键,立马发送数据.
不过也是在uip_polling里面发送的.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

15

主题

88

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2012-12-5
在线时间
1 小时
 楼主| 发表于 2014-5-8 09:53:28 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
原子哥,uip_polling这个函数的定时器超时发送我试过了,但是项目需要有数据了就发出去,而不经过uip中timer的定时器超时,能不能做到?
回复

使用道具 举报

15

主题

88

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2012-12-5
在线时间
1 小时
 楼主| 发表于 2014-5-8 10:24:23 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
谢谢原子哥,我懂了。按键触发那个是不需要经过定时器超时的。
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2016-3-4
在线时间
5 小时
发表于 2016-3-5 12:45:46 | 显示全部楼层
我也遇到和楼主一样的问题,板子做服务器可以连上网络调试软件,板子作为客户端就连不上,初始化的时候添加了

               uip_ipaddr_t ipaddr;       
   
        timer_set(&periodic_timer, CLOCK_SECOND / 2);
        timer_set(&arp_timer, CLOCK_SECOND * 10);

        tapdev_init();
        uip_arp_init;
        uip_init();                                                                       
        uip_ipaddr(ipaddr, 192,168,1,16);       
        uip_sethostaddr(ipaddr);                                            
        uip_ipaddr(ipaddr, 192,168,1,1);        
        uip_setdraddr(ipaddr);                                                 
        uip_ipaddr(ipaddr, 255,255,255,0);       
        uip_setnetmask(ipaddr);
        uip_listen(HTONS(1200));
        uip_listen(HTONS(80));                               
               uip_ipaddr(&ipaddr,192,168,1,100);       
        uip_connect(&ipaddr,htons(1400));          
但是作为客户端连接不上服务器,请大神帮帮忙呗,我现在弄的都快崩溃了
   switch(uip_conn->lport)
        {
                case HTONS(80):                                   
                        //httpd_appcall();
                        break;
                case HTONS(1200):                               
                    tcp_test_appcall();
                        break;
        }
        switch(uip_conn->rport)       
        {
            case HTONS(1400):
                         tcp_client_demo_appcall();
               break;
            default:
               break;
        }
这个也添加了,但是就是连接不上服务器          
回复

使用道具 举报

12

主题

336

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1576
金钱
1576
注册时间
2015-8-9
在线时间
625 小时
发表于 2016-3-5 21:18:06 | 显示全部楼层
如果时间充足的话,可以先跳去学习一下lwip,把原子的视频教程过一遍,然后再回来看uip,就会发现uip很多东西都不难理解
回复

使用道具 举报

21

主题

58

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
219
金钱
219
注册时间
2016-2-19
在线时间
46 小时
发表于 2016-4-18 14:49:26 | 显示全部楼层
玄心空月 发表于 2014-5-8 10:24
回复【3楼】正点原子:
---------------------------------
谢谢原子哥,我懂了。按键触发那个是不需要经过 ...

按键触发后不需要定时器吗?我感觉要啊
回复

使用道具 举报

21

主题

58

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
219
金钱
219
注册时间
2016-2-19
在线时间
46 小时
发表于 2016-4-18 14:50:20 | 显示全部楼层
正点原子 发表于 2014-5-7 23:01
按下按键,立马发送数据.
不过也是在uip_polling里面发送的.

原子哥,Uip怎么才能做到主动发数据啊?实在弄不懂了,uip_poll()该怎么用啊?
回复

使用道具 举报

4

主题

29

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
441
金钱
441
注册时间
2013-7-16
在线时间
71 小时
发表于 2016-10-27 21:28:06 | 显示全部楼层
正点原子 发表于 2014-5-7 20:19
我们的例程,就可以主动发送数据啊:

[mw_shl_code=c,true]int main(void)

请问 原子哥  此例程具体是那个开发板的例程?例程名是什么呢?
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2017-12-31
在线时间
9 小时
发表于 2016-12-29 10:12:50 | 显示全部楼层
例子中有些函数找不到的,能不能把整个应用贴出来?
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2017-8-1
在线时间
0 小时
发表于 2017-8-1 17:49:54 | 显示全部楼层
怎样可以像wifi模块一样及时地通过底层串口立马把数据发送出去,而不是通过while(1)最上面的uip_polling()函数呢?原子哥
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-4-20 02:40

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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