avr - ENC28J60 返回错误(意外)值

标签 avr ethernet

我正在尝试为 ENC28J60 创建自己的库。是的,我知道有几个现成的库,但我喜欢从头开始做事情,所以我了解发生了什么,它是如何工作的。

所以,我才刚刚开始,已经发现了一些我不明白的东西。 我的第一个测试是发送 RCR 命令来读取 BANK0。我收到的结果好坏参半。 通过 UART( super 终端)我得到以下结果:

USART Ready
SPI Ready
1 RCR-ERDPTL Send: 0 "(sending RCR|ERDPTL = 0 over SPI)"
0   11111010    11111010    OK   
1   101         101         OK
2   0           0           OK
3   0           0           OK
4   0           0           OK
5   0           0           OK
6   0           0           OK
7   0           0           OK
8   1000        11111010    ERROR
9   101         101         OK
10  11111111    11111111    OK
11  11111       11111       OK
12  110001      11111010    ERROR
13  110011      101         ERROR
14  0           0           OK
15  0           0           OK

第一列是字节数或者BANK0的寄存器数, 第二列是我从 ENC 芯片获得的值(根据数据表), 第三个是我应该得到的值, 第四个只是简单的检查以发现不匹配。

如您所见,有 3 个值与数据表不符。 为什么?

我的代码如下:

#include <define.h>
#include <ENC28J60.h>

#define ENC28J60        PB3
#define ENC28J61        PB4
#define DUMMY           0x00
unsigned char i, data, data0[] = {}, data1[] = {}, data2[] = {}, 
data3[16] = {0b11111010, 0b00000101, 0,0,0,0,0,0,0b11111010,0b00000101,255,0b00011111,0b11111010,0b00000101,0,0};


void ENC28J60_CS(void)              // ENC28J60 Select
{
    SPI_PORT &= ~(1<<ENC28J60);
}

void ENC28J60_DS(void)              // ENC28J60 DeSelect
{
    SPI_PORT |= (1<<ENC28J60);
}

void ENC28J61_CS(void)              // ENC28J60 Select
{
    SPI_PORT &= ~(1<<ENC28J61);
}

void ENC28J61_DS(void)              // ENC28J60 DeSelect
{
    SPI_PORT |= (1<<ENC28J61);
}

void ENC28J60_SRC(void)             // System Reset Command (Soft Reset) 
{
    ENC28J60_CS();                  // Enable
    SPIWR(0xFF);
    ENC28J60_DS();                  // Disable
    _delay_ms(50);
}

int main(void)
{
_delay_ms(3000);
USART0_Init(12);
USART0_TX_String("USART Ready");
USART0_TXD(10);                     
USART0_TXD(13);

SPI_Init();
PORTB ^= 1<<PINB0;
USART0_TX_String("SPI Ready");
USART0_TXD(10);                     
USART0_TXD(13);

ENC28J60_DS();
ENC28J61_DS();
_delay_ms(250);

ENC28J60_SRC();
ENC28J61_CS();                  // Enable
SPIWR(0xFF);
ENC28J61_DS();                  // Disable
_delay_ms(250);

ENC28J60_CS();
SPIWR(RCR|ERDPTL);
PORTB ^= 1<<PINB0;
USART0_TX_String("1 RCR-ERDPTL Send: ");
itoa(RCR|ERDPTL, StringA, 10);
USART0_TX_String(StringA);
USART0_TXD(10);                     
USART0_TXD(13);
data = SPIWRD(0xFF);

for(i = 0;i<15;i++)
{
    data0[i] = SPIWRD(0xFF);
}

ENC28J60_DS();


for(i = 0;i<16;i++)
{
    PORTB ^= 1<<PINB0;
    itoa(i, StringA, 10);
    USART0_TX_String(StringA);
    USART0_TXD(9);

    itoa(data0[i], StringA, 2);
    USART0_TX_String(StringA);
    USART0_TXD(9);
    USART0_TXD(9);

    itoa(data3[i], StringA, 2);
    USART0_TX_String(StringA);
    USART0_TXD(9);

    if(data0[i] == data3[i])
    {
        USART0_TX_String("OK");
    }
    else
    {
        USART0_TX_String("ERROR");
    }

    USART0_TXD(10);                     
    USART0_TXD(13);
}

PORTB |= 1<<PINB0;

    while(1)
    {

    }
}

还有一件事让我头疼。 我必须在第 71 行添加一个额外的 SPI 垃圾传输,因为如果我没有这样做,我会得到第一个结果两次,所以其余的结果就会出问题。 根据数据表(第 4.2.1 节),仅通过从 MAC 或 MII 寄存器读取,我才能获得虚拟字节。 这是怎么回事?

我正在使用 AVR ATMega1284P 和 WinAVR。

最佳答案

看来问题又出在代码中。

在我的变量(data0 到 2)的声明中,我没有设置它们的大小:

unsigned char i, data, data0[] = {}, data1[] = {}, data2[] = {}, 
data3[16] = {0b11111010, 0b00000101,0,0,0,0,0,0,0b11111010,0b00000101,
255,0b00011111,0b11111010,0b00000101,0,0};

我应该这样做:

unsigned char i, data, data0[16] = {}, data1[16] = {}, data2[16] = {}, 
data3[16] = {0b11111010, 0b00000101, 0,0,0,0,0,0,0b11111010,0b00000101,
255,0b00011111,0b11111010,0b00000101,0,0};

关于avr - ENC28J60 返回错误(意外)值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24281888/

相关文章:

c - 中断发送和接收字符串

c - 终端仿真器通过 UART ATmega328p 从未知源接收字节

c - AVR C 编程 - 为什么 while 循环之后的代码没有执行?

Android 同时连接以太网和 Wi-Fi

linux-kernel - 我需要构建什么才能在内核级别直接访问以太网帧位?

c - ATMEGA 2560 uart 代码未在 minicom 上给出正确的输出

c - 在 Mac 上使用 'brew install avr-libc' 命令产生错误 'no formulae found in taps'

linux - 当我在内核命令中添加选项 net.ifnames=0 biosdevname=0 时,IP 路由错误

c - C 代码中打印的 MAC 不正确

networking - 了解对数据包的 vlan 处理