坤遠遊森林 发表于 2012-9-27 14:35:52

enc28j60+ethercard库的一使用上的改变和问题

本帖最后由 坤遠遊森林 于 2012-9-28 13:16 编辑

之前用etherShield的库,跑通程序和硬件。

看了一下现在比较新的ethercard库,感觉调用函数的语句更精炼,阅读更方便,所以想使用这个库。
但是在运行Ethercard库的示例,上机无力。http://www.geek-workshop.com/thread-2044-1-1.html。具体为网络灯不亮,更像是中断/片选这类的问题。

所以翻阅比较了一下etherShield和ethercard里面的构建函数
发现:
etherShield里的enc28j60.h
#define ENC28J60_CONTROL_CS   10
#define SPI_MOSI                                11
#define SPI_MISO                                12
#define SPI_SCK                                        13
...
..
..

void enc28j60Init(uint8_t* macaddr)
{
        // initialize I/O
      // ss as output:
        pinMode(ENC28J60_CONTROL_CS, OUTPUT);
        CSPASSIVE; // ss=0
      //       
        pinMode(SPI_MOSI, OUTPUT);
       
        pinMode(SPI_SCK, OUTPUT);
       
        pinMode(SPI_MISO, INPUT);
       
       
        digitalWrite(SPI_MOSI, LOW);
       
        digitalWrite(SPI_SCK, LOW);
       
        /*DDRB|= 1<<PB3 | 1<<PB5; // mosi, sck output
        cbi(DDRB,PINB4); // MISO is input
      //
      cbi(PORTB,PB3); // MOSI low
      cbi(PORTB,PB5); // SCK low
*/
        //
        // initialize SPI interface
        // master mode and Fosc/2 clock:
      SPCR = (1<<SPE)|(1<<MSTR);
      SPSR |= (1<<SPI2X);
        // perform system reset
        enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
        delay(50);
        // check CLKRDY bit to see if reset is complete
      // The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.
        //while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));
        // do bank 0 stuff
        // initialize receive buffer
        // 16-bit transfers, must write low byte first
        // set receive buffer start address
        NextPacketPtr = RXSTART_INIT;
      // Rx start
        enc28j60Write(ERXSTL, RXSTART_INIT&0xFF);
        enc28j60Write(ERXSTH, RXSTART_INIT>>8);
        // set receive pointer address
        enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF);
        enc28j60Write(ERXRDPTH, RXSTART_INIT>>8);
        // RX end
        enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF);
        enc28j60Write(ERXNDH, RXSTOP_INIT>>8);
        // TX start
        enc28j60Write(ETXSTL, TXSTART_INIT&0xFF);
        enc28j60Write(ETXSTH, TXSTART_INIT>>8);
        // TX end
        enc28j60Write(ETXNDL, TXSTOP_INIT&0xFF);
        enc28j60Write(ETXNDH, TXSTOP_INIT>>8);
        // do bank 1 stuff, packet filter:
      // For broadcast packets we allow only ARP packtets
      // All other packets should be unicast only for our mac (MAADR)
      //
      // The pattern to match on is therefore
      // Type   ETH.DST
      // ARP      BROADCAST
      // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
      // in binary these poitions are:11 0000 0011 1111
      // This is hex 303F->EPMM0=0x3f,EPMM1=0x30
        enc28j60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);
        enc28j60Write(EPMM0, 0x3f);
        enc28j60Write(EPMM1, 0x30);
        enc28j60Write(EPMCSL, 0xf9);
        enc28j60Write(EPMCSH, 0xf7);
      //
      //
        // do bank 2 stuff
        // enable MAC receive
        enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
        // bring MAC out of reset
        enc28j60Write(MACON2, 0x00);
        // enable automatic padding to 60bytes and CRC operations
        enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
        // set inter-frame gap (non-back-to-back)
        enc28j60Write(MAIPGL, 0x12);
        enc28j60Write(MAIPGH, 0x0C);
        // set inter-frame gap (back-to-back)
        enc28j60Write(MABBIPG, 0x12);
        // Set the maximum packet size which the controller will accept
      // Do not send packets longer than MAX_FRAMELEN:
        enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF);       
        enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8);
        // do bank 3 stuff
      // write MAC address
      // NOTE: MAC address in ENC28J60 is byte-backward
      enc28j60Write(MAADR5, macaddr);
      enc28j60Write(MAADR4, macaddr);
      enc28j60Write(MAADR3, macaddr);
      enc28j60Write(MAADR2, macaddr);
      enc28j60Write(MAADR1, macaddr);
      enc28j60Write(MAADR0, macaddr);
        // no loopback of transmitted frames
        enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS);
        // switch to bank 0
        enc28j60SetBank(ECON1);
        // enable interrutps
        enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
        // enable packet reception
        enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
}


和 ethercard里的<enc28j60.cpp>
void ENC28J60::initSPI () {
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    const byte SPI_SS   = 53;
    const byte SPI_MOSI = 51;
    const byte SPI_MISO = 50;
    const byte SPI_SCK= 52;
#else
    const byte SPI_SS   = 10;
    const byte SPI_MOSI = 11;
    const byte SPI_MISO = 12;
    const byte SPI_SCK= 13;
#endif
   
    pinMode(SPI_SS, OUTPUT);
    pinMode(SPI_MOSI, OUTPUT);
    pinMode(SPI_SCK, OUTPUT);   
    pinMode(SPI_MISO, INPUT);
   
    digitalWrite(SPI_MOSI, HIGH);
    digitalWrite(SPI_MOSI, LOW);
    digitalWrite(SPI_SCK, LOW);

    SPCR = bit(SPE) | bit(MSTR); // 8 MHz @ 16
    bitSet(SPSR, SPI2X);
}
...
...
...
byte ENC28J60::initialize (word size, const byte* macaddr, byte csPin) {
    bufferSize = size;
    if (bitRead(SPCR, SPE) == 0)
      initSPI();
    selectBit = csPin - 8;
    bitSet(DDRB, selectBit);
    disableChip();
   
    writeOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
    delay(2); // errata B7/2
    while (!readOp(ENC28J60_READ_CTRL_REG, ESTAT) & ESTAT_CLKRDY)
      ;
      
    gNextPacketPtr = RXSTART_INIT;
    writeReg(ERXST, RXSTART_INIT);
    writeReg(ERXRDPT, RXSTART_INIT);
    writeReg(ERXND, RXSTOP_INIT);
    writeReg(ETXST, TXSTART_INIT);
    writeReg(ETXND, TXSTOP_INIT);
    enableBroadcast(); // change to add ERXFCON_BCEN recommended by epam
    writeReg(EPMM0, 0x303f);
    writeReg(EPMCS, 0xf7f9);
    writeRegByte(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
    writeRegByte(MACON2, 0x00);
    writeOp(ENC28J60_BIT_FIELD_SET, MACON3,
                        MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);
    writeReg(MAIPG, 0x0C12);
    writeRegByte(MABBIPG, 0x12);
    writeReg(MAMXFL, MAX_FRAMELEN);
    writeRegByte(MAADR5, macaddr);
    writeRegByte(MAADR4, macaddr);
    writeRegByte(MAADR3, macaddr);
    writeRegByte(MAADR2, macaddr);
    writeRegByte(MAADR1, macaddr);
    writeRegByte(MAADR0, macaddr);
    writePhy(PHCON2, PHCON2_HDLDIS);
    SetBank(ECON1);
    writeOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
    writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);

    byte rev = readRegByte(EREVID);
    // microchip forgot to step the number on the silcon when they
    // released the revision B7. 6 is now rev B7. We still have
    // to see what they do when they release B8. At the moment
    // there is no B8 out yet
    if (rev > 5) ++rev;
    return rev;
}

以及ethercard里的<enc28j60.c>
static uint8_t initialize (const uint16_t size, const uint8_t* macaddr,
                           uint8_t csPin =8);
...
...
...


static uint8_t doBIST(uint8_t csPin =8);



可见能够用ethershield里的cs和ethercard里的cs针脚定义是不同的,一个是10口,一个是8口。EC里的10口为ss,并且在int针口是cspin - 8,我也修改为cspin - 6

所以按照这个推论我又重新装接了针脚,28j60能够上机跑示例webclint,但是却又发生了一个串口监视器乱码的问题。头很大。


希望老师们能帮忙解决一下~~{:soso_e109:}

zcbzjx 发表于 2012-9-27 17:44:15

串口问题,听说是idebug你换别的波特率试试,我是用57600没问题,另外一个问题,你不要改库,改变你的接线,ss接D8就行了,如果你非要接10就用ether.begin(sizeof Ethernet::buffer, mymac,10)就ok了

坤遠遊森林 发表于 2012-9-28 00:06:52

zcbzjx 发表于 2012-9-27 17:44 static/image/common/back.gif
串口问题,听说是idebug你换别的波特率试试,我是用57600没问题,另外一个问题,你不要改库,改变你的接线, ...

:P
感谢老师,果然是波特率问题,我设置到9600,就没有乱码了~实在是太感谢了。

老师,有一个请求,能不能给做一个ethercard库的函数调用的方法和说明,虽然看库文件能理解一部分,但是有些函数的用法确实不清楚。实在很头疼。
最近又纠结于想做一个通过网络控制的小车,但是对这个想法有种束手无策的感觉。

zhangdeyue1 发表于 2012-9-28 10:05:08

波特率的问题~!
我之前也发现过:)

zhangdeyue1 发表于 2012-9-28 10:06:51

我也有些函数现在看不懂
我的办法是编译好的函数自己慢点去修改
看会产生什么不一样的效果
最后来确定函数的作用:(

坤遠遊森林 发表于 2012-9-28 13:01:24

zhangdeyue1 发表于 2012-9-28 10:06 static/image/common/back.gif
我也有些函数现在看不懂
我的办法是编译好的函数自己慢点去修改
看会产生什么不一样的效果


我是在先研究示例,一点点改。

我觉得ethercard比以前的ethershield看起来简单多了。。还是有希望突破的


张老师昨天出了一个教程了~就是专门对付enc28j60的ethercard库,在那个原英文链接的网站,收获还不少

gusi 发表于 2013-4-8 00:58:20

请问楼上提到的这个教程在什么地方啊?
页: [1]
查看完整版本: enc28j60+ethercard库的一使用上的改变和问题