搜索
bottom↓
回复: 7

STM32+RT-Thread+ENC28J60+LWIP用DHCP时网卡不能从掉电模式恢复

[复制链接]

出0入0汤圆

发表于 2014-7-19 11:31:14 | 显示全部楼层 |阅读模式
目前一个应用中,参考使用了RT-Thread的方案,网卡ENC28J60功耗很大,发热严重,因此在系统空闲时考虑让其进入掉电模式(通过配置网卡的相关寄存器,具体程序附于文末)。

如果使用静态IP模式,配置寄存器进入掉电模式后,只需重新配置寄存器让网卡退出掉电模式即可,程序里不需要任何其他操作(只操作了ENC28J60的相关寄存器,无需修改LWIP或者RTT)就可以正常恢复数据收发。

但是如果使用DHCP,则网卡进入掉电模式后,重新退出掉电模式就不能正常收发数据了(确认网卡是退出掉电模式了,因为又开始发热了),程序中尝试了dhcp_start(),netif_set_up()等方式,都不能正常恢复通信。

请问应该如何处理啊?

  1. void enc28j60_powersave_enter(void)//进入掉电模式
  2. {
  3.         struct netif *netif = netif_list;
  4.         rt_uint8_t dat;
  5.         spi_write_op(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXEN);//禁止接收数据包
  6.         do{
  7.                 dat=spi_read_op(ENC28J60_READ_CTRL_REG, ESTAT);//等待接收完毕
  8.         }while(dat&ESTAT_RXBUSY);
  9.         do{
  10.                 dat=spi_read_op(ENC28J60_READ_CTRL_REG, ECON1);//等待发送完毕
  11.         }while(dat&ECON1_TXRTS);
  12.         spi_write_op(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV|ECON2_VRPS);//进入掉电模式
  13.     while( netif != RT_NULL )
  14.     {
  15.                 //netif_set_down(netif);
  16.                 netif=netif->next;
  17.         }
  18. }

  19. void enc28j60_powersave_exit(void)//退出掉电模式
  20. {
  21.         struct netif *netif = netif_list;
  22.         rt_uint16_t dat;
  23.         spi_write_op(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV);//退出掉电模式
  24.         do{
  25.                 dat=spi_read_op(ENC28J60_READ_CTRL_REG, ESTAT);//等待PHY时钟稳定
  26.         }while(!(dat&ESTAT_CLKRDY));
  27.         spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);//允许接收数据包
  28.         do{
  29.                 dat=enc28j60_phy_read(PHSTAT2);//等待连接建立:为什么这里会死循环?
  30.         }while(!(dat&PHSTAT2_LSTAT));

  31.     while( netif != RT_NULL )
  32.     {
  33.                 //netif_set_up(netif);
  34.                 dhcp_start(netif);
  35.                 netif=netif->next;
  36.         }
  37. }
复制代码

出0入0汤圆

 楼主| 发表于 2014-7-19 12:28:53 来自手机 | 显示全部楼层
求解答呀

出0入0汤圆

发表于 2014-7-19 14:30:49 | 显示全部楼层
能否提供完整的代码,让大伙有争对性的的分析或参考下

出0入0汤圆

 楼主| 发表于 2014-7-19 19:54:51 | 显示全部楼层
本帖最后由 xhly 于 2014-7-19 19:56 编辑
lpdpzc 发表于 2014-7-19 14:30
能否提供完整的代码,让大伙有争对性的的分析或参考下


您好,毕竟是项目代码,完整的不方便提供,我再把主要的相关代码贴出来供大家分析一下吧。

有一个主线程,while循环里是一个状态机switch case 结构,根据当前状态执行不同事务,大概的说有一个发送UDP数据包的case,还有一个空闲状态的case,在这个空闲状态里让网卡进入掉电模式:

  1. whie(1)
  2. {
  3.                 switch(cmd)
  4.                 {
  5.                         case CMD_UDP_SEND:
  6.                                 udp_sendto(srvr_udp_pcb,p,&srvr_ip,srvr_port);
  7.                                 break;
  8.                         case CMD_NONE:
  9.                                 p->payload=pt;
  10.                                 enc28j60_powersave_enter();//enc28j60进入掉电模式
  11.                                 led_mode=LED_MODE_BOTH_OFF;//指示灯全灭
  12.                 }
  13.                 udp_sendto(srvr_udp_pcb,p,&srvr_ip,srvr_port);
  14.                 rt_sem_take(sem_udp_rcv,RT_TICK_PER_SECOND);//最多等待服务器1s
  15. }
复制代码


这里还有一个使用定时器的周期任务,每隔一个固定的周期,调用回调函数,回调函数如果发现当前是空闲状态就切换到UDP汇报状态,系统通过UDP发送一个汇报数据包。
  1. void timer1_callback(void* parameter)
  2. {
  3.         //rt_timer_stop(timer1);
  4.         if(butn_cmd == CMD_NONE)//当前没有其他任务
  5.         {
  6.                 butn_cmd = CMD_REPORT_RQST;//timer1超时,启动定时汇报
  7.                 enc28j60_powersave_exit();//enc28j60退出掉电模式
  8.         }
  9. }
复制代码


其中,enc28j60进入和退出掉电模式的函数在前面的帖子中已经给出:
  1. void enc28j60_powersave_enter(void)//进入掉电模式
  2. {
  3.         struct netif *netif = netif_list;
  4.         rt_uint8_t dat;
  5.         spi_write_op(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXEN);//禁止接收数据包
  6.         do{
  7.                 dat=spi_read_op(ENC28J60_READ_CTRL_REG, ESTAT);//等待接收完毕
  8.         }while(dat&ESTAT_RXBUSY);
  9.         do{
  10.                 dat=spi_read_op(ENC28J60_READ_CTRL_REG, ECON1);//等待发送完毕
  11.         }while(dat&ECON1_TXRTS);
  12.         spi_write_op(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV|ECON2_VRPS);//进入掉电模式
  13.     while( netif != RT_NULL )
  14.     {
  15.                 //netif_set_down(netif);
  16.                 netif=netif->next;
  17.         }
  18. }

  19. void enc28j60_powersave_exit(void)//退出掉电模式
  20. {
  21.         struct netif *netif = netif_list;
  22.         rt_uint16_t dat;
  23.         spi_write_op(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV);//退出掉电模式
  24.         do{
  25.                 dat=spi_read_op(ENC28J60_READ_CTRL_REG, ESTAT);//等待PHY时钟稳定
  26.         }while(!(dat&ESTAT_CLKRDY));
  27.         spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);//允许接收数据包
  28.         do{
  29.                 dat=enc28j60_phy_read(PHSTAT2);//等待连接建立
  30.         }while(!(dat&PHSTAT2_LSTAT));

  31.     while( netif != RT_NULL )
  32.     {
  33.                 //netif_set_up(netif);
  34.                 dhcp_start(netif);
  35.                 netif=netif->next;
  36.         }
  37. }
复制代码

出0入0汤圆

 楼主| 发表于 2014-7-20 09:22:27 来自手机 | 显示全部楼层
试来试去还是不行啊……

出0入0汤圆

 楼主| 发表于 2014-7-21 21:43:04 | 显示全部楼层
帖子好冷清……

出0入0汤圆

发表于 2014-7-25 17:26:53 | 显示全部楼层
也在调这个片子,发现老不稳定,还在找原因

出0入0汤圆

发表于 2014-9-26 12:25:12 | 显示全部楼层

新出W5500模块,硬件TCP/IP以太网模块,有需要的坛友购买前说是在论坛上看到信息的,一律50元包邮,有兴趣请点击一下链接,谢谢支持。
http://item.taobao.com/item.htm? ... &id=40933615687
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-11 04:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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