ENC28J60返回错误(意外)值

时间:2014-06-18 09:28:00

标签: avr ethernet

我正在尝试为ENC28J60创建自己的库。是的,我知道有几个随时可以使用的库,但我喜欢从头做事,所以我理解发生了什么,它是如何工作的。

所以,我只是在挣扎,已经找到了一些我不明白的东西。 我的第一个测试是发送RCR命令来读取BANK0。我收到了不一样的结果。 通过UART(HyperTerminal)我得到了以下结果:

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。

1 个答案:

答案 0 :(得分:2)

问题似乎再次出现在代码中。

在我的变量声明(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};