目录
1:概述
2:enc28j60初始化
1、概述
1.1:以太网是实现LAN的一种技术,它允许嵌入式系统连接到一个LAN中,并可通过使用网关经Internet连接到外部世界,以太网的主要目的是向LAN发送和从LAN接收以太网帧,在TCP/IP协议族中,不包括以太网协议,可以理解它为TCP/IP中的网络接口层(物理层和数据链路层),为TCP/IP中的上层协议(比如:IP协议和ARP协议)提供服务;
1.2:ENC28J60是带SPI接口的以太网控制器,支持IEEE802.3协议,当然,也兼容Ethernet第二版的协议,此协议帧结构简单,被大量使用;
1.3:以太网帧结构:目的mac地址+源mac地址+协议类型+数据;
1.4:本篇编写ENC28J60驱动,实现以太网控制,将我们的嵌入式设备连接到LAN中,并使用ping命令进行测试;
1.5:enc28j60驱动实现需完成三步:(1)读写缓冲区函数实现;(2)发送和接受缓冲器实现;(3)enc28j60初始化,本篇实现最后一步;
1.6:参考项目:AVRNET项目
1.7:开发板:STM32F103ZERT 奋斗开发板V5 软件环境:KEIL MDK5
1.8:代码分享
2、enc28j60初始化
2.1:初始化主要包括以下步骤:1:设置接收和发送缓冲区;2:设置接收过滤器;3:MAC初始化设置;4:PHY初始化设置;
2.2:最大帧设置:一般设置为最大帧长度为1518字节(源MAC地址(6)+目的MAC地址(6)+协议类型(2)+数据(46~1500)+校验位(4))
2.3:填充设置:本文设置为60字节的填充;
2.4:半双工、全双工:参考电路图,需设置成全双工;
2.5:不要忘记使能接受;
2.6:更多设置需参考中文版datasheet;
enc28j60.c
void enc28j60Init(char* macaddr)
{
/* 禁止ENC28J60 */
CS_HIGH();
/* ENC28J60软件复位*/
enc28j60Write_instruction(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
/*查询ESTAT.CLKRDY位 ESTAT.CLKRDY=1时,PHY准备就绪*/
while(!(enc28j60Read_ctrl_register(ESTAT) & ESTAT_CLKRDY));
/* 设置接收缓冲区起始地址 该变量用于每次读取缓冲区时保留下一个包的首地址 */
NextPacketPtr = RXSTART_INIT;
;
/*接受缓冲器是一个循环FIFO缓冲器,寄存器对ERXSTH:ERXSTL和ERXNDH:ERXNDL作为指针,定义缓冲器的容量和其在存储器中的位置;
*ERXWRPTH:ERXWRPTL寄存器定义硬件向FIFO中的哪个位置写入其接收到的数据,当成功接受到一个数据包后,硬件会自动跟新这个指针,用户不需要处理,
*用户可以使用这个指针判断FIFO剩余空间的大小;*/
/* 设置接收缓冲区 起始指针*/
enc28j60Write_ctl_register(ERXSTL, RXSTART_INIT & 0xFF);
enc28j60Write_ctl_register(ERXSTH, RXSTART_INIT >> 8);
/* 设置接收缓冲区 结束指针 */
enc28j60Write_ctl_register(ERXNDL, RXSTOP_INIT&0xFF);
enc28j60Write_ctl_register(ERXNDH, RXSTOP_INIT>>8);
/* 设置接收缓冲区 读指针*/
enc28j60Write_ctl_register(ERXRDPTL, RXSTART_INIT&0xFF);
enc28j60Write_ctl_register(ERXRDPTH, RXSTART_INIT>>8);
/* 设置发送缓冲区 起始指针 */
enc28j60Write_ctl_register(ETXSTL, TXSTART_INIT&0xFF);
enc28j60Write_ctl_register(ETXSTH, TXSTART_INIT>>8);
/* 设置发送缓冲区 结束指针 */
enc28j60Write_ctl_register(ETXNDL, TXSTOP_INIT&0xFF);
enc28j60Write_ctl_register(ETXNDH, TXSTOP_INIT>>8);
/*广播过滤使能位,上电复位置1使能*/
/* 使能单播过滤,使能CRC校验,使能格式匹配自动过滤,广播过滤使能位默认置1,不用使能*/
enc28j60Write_ctl_register(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);
/*格式匹配自动过滤工程设置*/
enc28j60Write_ctl_register(EPMM0, 0x3f);
enc28j60Write_ctl_register(EPMM1, 0x30);
enc28j60Write_ctl_register(EPMCSL, 0xf9);
enc28j60Write_ctl_register(EPMCSH, 0xf7);
/* 使能MAC接收,如果是全双工模式,需要将TXPAUS和RXPAUS置1*/
enc28j60Write_ctl_register(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
/* 退出复位状态 */
enc28j60Write_ctl_register(MACON2, 0x00);
/* 用0填充所有短帧至60字节长 并追加一个CRC 发送CRC使能 帧长度校验使能 MAC全双工使能*/
/* 提示 由于ENC28J60不支持802.3的自动协商机制, 所以对端的网络卡需要强制设置为全双工 */
enc28j60Write_ctl_register(MACON3,MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN|MACON3_FULDPX);
/* 填入默认值 手册提供*/
enc28j60Write_ctl_register(MAIPGL, 0x12);
/* 填入默认值 手册提供*/
enc28j60Write_ctl_register(MAIPGH, 0x0C);
/* 填入默认值 手册提供*/
enc28j60Write_ctl_register(MABBIPG, 0x15);
/* 最大帧长度 */
enc28j60Write_ctl_register(MAMXFLL, MAX_FRAMELEN & 0xFF);
enc28j60Write_ctl_register(MAMXFLH, MAX_FRAMELEN >> 8);
/* 写入MAC地址 */
enc28j60Write_ctl_register(MAADR5, macaddr[0]);
enc28j60Write_ctl_register(MAADR4, macaddr[1]);
enc28j60Write_ctl_register(MAADR3, macaddr[2]);
enc28j60Write_ctl_register(MAADR2, macaddr[3]);
enc28j60Write_ctl_register(MAADR1, macaddr[4]);
enc28j60Write_ctl_register(MAADR0, macaddr[5]);
/* 配置PHY为全双工 LEDB为拉电流 */
enc28j60Write_phy_register(PHCON1, PHCON1_PDPXMD);
/* LED状态 LEDA:显示链接状态 LEDB:显示发送和接受活动*/
enc28j60Write_phy_register(PHLCON,0x0476);
/* 半双工回环禁止 */
enc28j60Write_phy_register(PHCON2, PHCON2_HDLDIS);
/* 返回BANK0 */
enc28j60SetBank(ECON1);
/* 使能中断 全局中断 接收中断 接收错误中断 */
enc28j60Write_instruction(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE|EIE_RXERIE);
/* 接收使能位 */
enc28j60Write_instruction(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);
enc28j60Write_instruction(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_AUTOINC);
}
|