|
楼主 |
发表于 2014-7-19 19:54:51
|
显示全部楼层
本帖最后由 xhly 于 2014-7-19 19:56 编辑
您好,毕竟是项目代码,完整的不方便提供,我再把主要的相关代码贴出来供大家分析一下吧。
有一个主线程,while循环里是一个状态机switch case 结构,根据当前状态执行不同事务,大概的说有一个发送UDP数据包的case,还有一个空闲状态的case,在这个空闲状态里让网卡进入掉电模式:
- whie(1)
- {
- switch(cmd)
- {
- case CMD_UDP_SEND:
- udp_sendto(srvr_udp_pcb,p,&srvr_ip,srvr_port);
- break;
- case CMD_NONE:
- p->payload=pt;
- enc28j60_powersave_enter();//enc28j60进入掉电模式
- led_mode=LED_MODE_BOTH_OFF;//指示灯全灭
- }
- udp_sendto(srvr_udp_pcb,p,&srvr_ip,srvr_port);
- rt_sem_take(sem_udp_rcv,RT_TICK_PER_SECOND);//最多等待服务器1s
- }
复制代码
这里还有一个使用定时器的周期任务,每隔一个固定的周期,调用回调函数,回调函数如果发现当前是空闲状态就切换到UDP汇报状态,系统通过UDP发送一个汇报数据包。
- void timer1_callback(void* parameter)
- {
- //rt_timer_stop(timer1);
- if(butn_cmd == CMD_NONE)//当前没有其他任务
- {
- butn_cmd = CMD_REPORT_RQST;//timer1超时,启动定时汇报
- enc28j60_powersave_exit();//enc28j60退出掉电模式
- }
- }
复制代码
其中,enc28j60进入和退出掉电模式的函数在前面的帖子中已经给出:
- void enc28j60_powersave_enter(void)//进入掉电模式
- {
- struct netif *netif = netif_list;
- rt_uint8_t dat;
- spi_write_op(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXEN);//禁止接收数据包
- do{
- dat=spi_read_op(ENC28J60_READ_CTRL_REG, ESTAT);//等待接收完毕
- }while(dat&ESTAT_RXBUSY);
- do{
- dat=spi_read_op(ENC28J60_READ_CTRL_REG, ECON1);//等待发送完毕
- }while(dat&ECON1_TXRTS);
- spi_write_op(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PWRSV|ECON2_VRPS);//进入掉电模式
- while( netif != RT_NULL )
- {
- //netif_set_down(netif);
- netif=netif->next;
- }
- }
- void enc28j60_powersave_exit(void)//退出掉电模式
- {
- struct netif *netif = netif_list;
- rt_uint16_t dat;
- spi_write_op(ENC28J60_BIT_FIELD_CLR, ECON2, ECON2_PWRSV);//退出掉电模式
- do{
- dat=spi_read_op(ENC28J60_READ_CTRL_REG, ESTAT);//等待PHY时钟稳定
- }while(!(dat&ESTAT_CLKRDY));
- spi_write_op(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);//允许接收数据包
- do{
- dat=enc28j60_phy_read(PHSTAT2);//等待连接建立
- }while(!(dat&PHSTAT2_LSTAT));
- while( netif != RT_NULL )
- {
- //netif_set_up(netif);
- dhcp_start(netif);
- netif=netif->next;
- }
- }
复制代码 |
|