Ming_Yan 2021-12-23 23:39 采纳率: 100%
浏览 141
已结题

enc28j60 + UIP + STM32F103C6T6 电脑端接收数据错误,导致不能通讯问题

问题遇到的现象和发生背景

问题出现在arp阶段,MCU可以正常接收arp数,并且使用UIP解析正常,但是向电脑端响应arp请求时,通过Wireshark发现接收到的响应arp包数据格式不正常!

img

img

问题相关代码,请勿粘贴截图

        #define UIP_BUF ((struct uip_eth_hdr *)&uip_buf[0])

    tapdev_init();//初始化enc28j60
    print("init enc28j60 success!");
    uip_init();
    uip_ipaddr_t ipaddr;
    uip_ipaddr(ipaddr, 192, 168, 1, 8);
    uip_sethostaddr(ipaddr);
    uip_ipaddr(ipaddr, 192, 168, 1, 1);
    uip_setdraddr(ipaddr);
    uip_ipaddr(ipaddr, 255, 255, 252, 0);
    uip_setnetmask(ipaddr);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
        uip_len = tapdev_read();//uip_len在uip.c中声明
        if(uip_len == 0){
            continue;
        }
        print("ok");
        if(UIP_BUF->type == htons(UIP_ETHTYPE_ARP)) {
            uip_arp_arpin();
            if(uip_len>0){
                print("rarp package send!!!");
                print3((char*)uip_buf, uip_len);
                tapdev_send();
            }
        }
    /* USER CODE BEGIN 3 */
  }

tapdev.c 实现enc28j60收发代码:

#include <tapdev.h>
#include "enc28j60.h"
#include <uip.h>


//引用uip.c中声明的uip_ethaddr
extern struct uip_eth_addr uip_ethaddr;
//MAC
unsigned char my_mac[6] = {0x29, 0x7C, 0x07, 0x37, 0x24, 0x63};
void tapdev_init(void)
{
    enc28j60Init(my_mac);
    
     for (int i = 0; i < 6; i++)
     {
         uip_ethaddr.addr[i] = my_mac[i];
     }
}

unsigned int tapdev_read(void)
{
    enc28j60PacketReceive(MAX_FRAMELEN, uip_buf);
}


void tapdev_send(void)
{
    enc28j60PacketSend(uip_len, uip_buf);
}

更详细代码已上上传到蓝奏云,如果不愿下载,请评论通知我,我会尽快回复!
怀疑是用cubemx 生成代码时,SPI配置有问题,请帮忙确认, 非常感谢!

img

全部代码:
https://wwb.lanzouw.com/iNiJSxx0bah 密码:e5bk
使用cubemx + keil5

运行结果及报错内容
我的解答思路和尝试过的方法
我想要达到的结果

目前就想用uip ,实现电脑可以ping通的效果。
本人第一次使用SPI接口,非常希望各位能给一些解决办法的思路,非常感谢!

  • 写回答

4条回答 默认 最新

  • Ming_Yan 2021-12-26 00:03
    关注

    问题已解决,在调用驱动的写缓冲区操作(enc28j60WriteBuffer)时,写数据前,没有先执行写缓冲区命令,直接写入的数据,导致数据不正常:

    void enc28j60WriteBuffer(unsigned int len, unsigned char* data)
        {
        ENC28J60_CSL();
        // issue write command
            /* 通过SPI发送写取缓冲区命令*/
        SPI1_ReadWrite(ENC28J60_WRITE_BUF_MEM);//没有调用这句
        
        while(len)
            {
            len--;
            SPI1_ReadWrite(*data);
            data++;
            }
        ENC28J60_CSH();
        }
    

    遇见这种问题,如果想测试发送包是否正常,可以先手动调用enc28j60PacketSend(len, data)函数,比如调用enc28j60PacketSend发送0xAA,0xBB,0xCC十六进制数据,通过Wireshark拦截消息,看是否有接收到MCU发送数据包,并且发送数据包数据是否为0xAA,0xBB,0xCC.如果可以正常接收并且准确接收AA,BB,CC,表示驱动发送功能正常。
    最后有些驱动函数名称有些区别,贴一下enc28j60PacketSend实现:

    void enc28j60PacketSend(unsigned int len, unsigned char* packet)
        {
        // Set the write pointer to start of transmit buffer area
        enc28j60Write(EWRPTL, TXSTART_INIT&0xFF);
        enc28j60Write(EWRPTH, TXSTART_INIT>>8);
    
        // Set the TXND pointer to correspond to the packet size given
        enc28j60Write(ETXNDL, (TXSTART_INIT+len)&0xFF);
        enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8);
    
        // write per-packet control byte (0x00 means use macon3 settings)
        enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);
    
        // copy the packet into the transmit buffer
        enc28j60WriteBuffer(len, packet);
    
        // send the contents of the transmit buffer onto the network
        enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
    
        // Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.
        if( (enc28j60Read(EIR) & EIR_TXERIF) )
            {
            enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
            }
        }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 3月23日
  • 已采纳回答 3月15日
  • 创建了问题 12月23日

悬赏问题

  • ¥15 BP神经网络控制倒立摆
  • ¥20 要这个数学建模编程的代码 并且能完整允许出来结果 完整的过程和数据的结果
  • ¥15 html5+css和javascript有人可以帮吗?图片要怎么插入代码里面啊
  • ¥30 Unity接入微信SDK 无法开启摄像头
  • ¥20 有偿 写代码 要用特定的软件anaconda 里的jvpyter 用python3写
  • ¥20 cad图纸,chx-3六轴码垛机器人
  • ¥15 移动摄像头专网需要解vlan
  • ¥20 access多表提取相同字段数据并合并
  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算