我正在尝试为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。
答案 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};