STM32入门开发: LWIP网络协议栈移植(网卡采用DM9000)
Posted DS小龙哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32入门开发: LWIP网络协议栈移植(网卡采用DM9000)相关的知识,希望对你有一定的参考价值。
一、环境介绍
MCU: STM32F103ZET6
代码开发工具: Keil5
TCP/IP协议栈: LWIP
网卡: DM9000
本篇文章主要讲解如何在STM32F103工程里添加移植LWIP协议,最终完成TCP服务器、TCP客户端的通信测试。 网卡采用的是DM9000,工程代码中,采用STM32的FSMC接口来驱动DM900网卡,DM9000是并口网卡,引脚多,但是速度快,也可以采用其他网卡,SPI协议的、UART协议的等。 比如:ENC28J60。 因为主要是讲LWIP协议栈的移植,所以网卡相关的代码就没有细说(需要准备一个网卡可以正常通信的工程,再移植)。
工程源码、LWIP资料包下载地址:https://download.csdn.net/download/xiaolong1126626497/19907087
资料包里的内容如下:
二、D9000网卡
2.1 DM9000简介
DM9000 是一款完全集成的、性价比高、引脚数少、带有通用处理器接口的单芯片快速以太网控制器。 自带一个 10/100M PHY 和 4K 双字的 SRAM ,DM9000A 为适应各种处理器提供了8位、16 位数据接口访问内部存储器,DM9000拥有自动协商功能,DM9000特性如下:
1、集成自适应10/100M收发器。
2、内置16k字节的SRAM。
3、支持硬件帧校验。
4、兼容3.3V和5.0V输入输出电压。
DM9000 有多种型号,有 100 引脚和 48 引脚的, 开发板选择的是 48 引脚的 DM9000,型号为 DM9000CEP。
2.2 DM9000 中断引脚电平设置
DM9000的34(INT)引脚为中断输出引脚,默认情况下该引脚高电平有效。可以通过设置DM9000 的 20(EECK)引脚来改变 INT 的有效电平,当 EECK 拉高以后, INT 低电平有效,否则的话 INT 是高电平有效的。开发板上 R66 电阻为 EECK 的上拉电阻,因此开发板上 DM9000 的 INT 引脚是低电平有效的。
2.3 DM9000 数据位宽设置
前面我们提了一下 DM9000 支持 8 位和 16 位两种数据位宽,可以通过 DM9000 的 21(EECS)引脚设置其数据位宽,当 EECS 上拉的时候 DM9000 选择 8 位数据位宽,否则的话选择 16 位数据位宽。开发板上的 R65 电阻为 EECS 的上拉电阻,但是此电阻并未焊接! DM9000 芯片的数据位宽为 16 位。
2.4 DM9000寄存器表
寄存器 | 描述 | 寄存器地址 | 默认值 | |
NCR | 网络控制寄存器。 | 00H | 00H | |
NSR | 网络状态寄存器。 | 01H | 00H | |
TCR | 发送控制寄存器。 | 02H | 00H | |
TSR I | 发送状态寄存器 I。 | 03H | 00H | |
TSR II | 发送状态寄存器 II。 | 04H | 00H | |
RCR | 接收控制寄存器。 | 05H | 00H | |
RSR | 接收状态寄存器。 | 06H | 00H | |
ROCR | 接收溢出计数寄存器。 | 07H | 00H | |
BPTR | 背压门限寄存器。 | 08H | 37H | |
FCTR | 溢出控制门限寄存器。 | 09H | 38H | |
FCR | TX/RX 流量控制寄存器。 | 0AH | 00H | |
EPCR | EEPROM/PHY 控制寄存器。 | 0BH | 00H | |
EPAR | EEPROM/PHY 地址寄存器。 | 0CH | 40H | |
EPDRL | EEPROM/PHY 数据寄存器低位。 | 0DH | XXH | |
EPDRH | EEPROM/PHY 数据寄存器高位。 | 0EH | XXH | |
WCR | 唤醒控制寄存器。 | 0FH | 00H | |
PAR | 物理地址寄存器。 | 10H~15H | 由 EEPROM 决定 | |
MAR | 广播地址寄存器。 | 16H~1DH | XXH | |
GPCR | 通用目的控制寄存器(8bit 模式)。 | 1EH | 01H | |
GPR | 通用目的寄存器。 | 1FH | XXH | |
TRPAL | TX SRAM 读指针地址低字节。 | 22H | 00H | |
TRPAH | TX SRAM 读指针地址高字节。 | 23H | 00H | |
RWPAL | RX SRAM 写指针地址低字节。 | 24H | 00H | |
RWRAH | RX SRAM 写指针地址高字节。 | 25H | 0CH | |
VID | 厂家 ID。 | 28H~29H | 0A46H | |
PID | 产品 ID。 | 2AH~2BH | 9000H | |
CHIPR | 芯片版本。 | 2CH | 18H | |
TCR2 | 发送控制寄存器 2。 | 2DH | 00H | |
OCR | 操作控制寄存器。 | 2EH | 00H | |
SMCR | 特殊模式控制寄存器。 | 2FH | 00H | |
ETXCSR | 即将发送控制/状态寄存器。 | 30H | 00H | |
TCSCR | 发送校验和控制寄存器。 | 31H | 00H | |
RCSCSR | 接收校验和控制状态寄存器。 | 32H | 00H | |
MRCMDX | 内存数据预取读命令寄存器(地址不加 1)。 | F0H | XXH | |
MRCMDX1 | 内存数据读命令寄存器(地址不加 1)。 | F1H | XXH | |
MRCMD | 内存数据读命令寄存器(地址加 1)。 | F2H | XXH | |
MRRL | 内存数据读地址寄存器低字节。 | F4H | 00H | |
MRRH | 内存数据读地址寄存器高字节。 | F5H | 00H | |
MWCMDX | 内存数据写命令寄存器(地址不加 1) | F6H | XXH | |
MWCMD | 内存数据写命令寄存器(地址加 1)。 | F8H | XXH | |
MWRL | 内存数据写地址寄存器低字节。 | FAH | 00H | |
MWRH | 内存数据写地址寄存器高字节。 | FBH | 00H | |
TXPLL | TX 数据包长度低字节寄存器。 | FCH | XXH | |
TXPLH | TX 数据包长度高字节寄存器。 | FDH | XXH | |
ISR | 中断状态寄存器。 | FEH | 00H | |
IMR | 中断屏蔽寄存器。 | FFH | 00H | |
2.5 DM9000常用寄存器介绍
NCR、 NSR、 TCR、 RCR、 FCTR、 BPTR、 TCR2、 ISR、 IMR。
NCR(网络控制寄存器)寄存器
BIT | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
名称 | RESERVED | WAKEEN | RESERVED | FCOL | FDX | LBK | RST |
FCOL:强制冲突模式,用于检测。
FDX:内部 PHY 全双工模式。
LBK:回环模式(LoopBack)
00 正常;
01 MAC 内部回环;
10 内部 PHY100M 模式数字回环;
11 保留;
RST:置 1 软件复位, 10us 后自动清零。
NSR 寄存器(网络状态寄存器)
BIT | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
名 称 | SPEED | LINKST | WAKEST | RESERVED | TX2END | TX1END | RXOV | RESERVED |
SPEED:网络速度,在使用内部 PHY 情况下,0 表示 100Mbps,1 表示 100Mbps,当 LINKST=0时,此位无意义。
LINKST:连接状态, 0 为连接失败, 1 位已连接。
TX2END: TX(发送)数据包 2 完成标志,读取或写 1 将清零该位。
TX1END: TX(发送)数据包 1 完成标志,读取或写 1 将清零该位。
RXOV: RX(接收)FIFO 溢出标志。
TCR 寄存器(发送控制寄存器)
BIT | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
名 称 | RESERVED | TJDIS | EXCECM | PAD_DIS2 | CRC_DIS2 | PAD_DIS1 | CRC_DIS1 | TXREQ |
TJDIS: Jabber 传输禁止。
1,禁止 Jabber 传输定时器(2048 字节)。
0,使能。
EXCECM:严重冲突模式控制
0,当冲突计数多于 15 则终止本次数据包。
1,始终尝试发送本次数据包。
PAD_DIS2:禁止为数据包 II 添加填充。
CRC_DIS2:禁止为数据包 II 添加 CRC 校验。
PAD_DIS1:禁止为数据包 I 添加填充。
CRC_DIS1:禁止为数据包 I 添加 CRC 校验。
TXREQ: TX(发送)请求,发送完成后自动清零该位
RCR 寄存器(发送控制寄存器)
BIT | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
名称 | RESERVED | WTDIS | DIS_LONG | DIS_CRC | ALL | RUNT | PRMSC | RXEN |
WTDIS:看门狗定时器(2048 字节)禁止。
1,进制
0,使能
DIS_LONG:丢弃长数据包, 1,丢弃数据包长度超过 1522 字节的数据包。
DIS_CRC:丢弃 CRC 校验错误数据包。
ALL:允许广播。
RUNT:允许小于最小长度的数据包。
PRMSC:各种模式。
RXEN:接收使能。
FCTR 寄存器(流控制阈值寄存器)
BIT | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
名称 | HWOT | HWOT | HWOT | HWOT | LWOT | LWOT | LWOT | LWOT |
HWOT:RX FIFO 缓存高位溢出门限
当 RX SRAM 空闲空间小于该门限值时则发送一个暂停时间为 FFFFH 的暂停包,若该值为 0,则无接收控件。 1=1k 字节,默认值为 3H,即 3K 字节空闲空间,不要超过 S RAM 大小。
LWOT:RX FIFO 缓存低位溢出门限当 RX SRAM 空闲空间大于该门限值时则发送一个暂停时间为 0000H 的暂停包。
当溢出门限最高值的暂停包发送之后,溢出门限最低值的暂停包才有效,默认值为 8K,不要超过 SRAM 大小。
BPTR 寄存器(背压阈值寄存器)
BIT | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
名称 | BPHW | JPT |
BPHW:背压阈值最高值当接收 SRAM 空闲空间低于该阈值,则 MAC 将产生一个拥挤状态, 1=1k 字节。默认值为 3H,即 3K 字节空闲空间,不要超过 SRAM 大小。
JPT:拥挤状态时间,模式为 200us, JPT 值与其对应的拥挤状态时间表
JPT 值 | 拥挤状态时间(us) | JPT 值 | 拥挤状态时间(us) |
0000 | 5 | 1000 | 250 |
0001 | 10 | 1001 | 300 |
0010 | 15 | 1010 | 350 |
0011 | 25 | 1011 | 400 |
0100 | 50 | 1100 | 450 |
0101 | 100 | 1101 | 500 |
0110 | 150 | 1110 | 550 |
0111 | 200 | 1111 | 600 |
TCR2 寄存器(发送控制寄存器 2)
BIT | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
名称 | LED | RLCP | DTU | ONEPM | IFGS |
LED: LED 模式
1,设置 LED 引脚为模式 1
0,设置 LED 引脚为模式 0 或根据 EEPROM 的设定。
RLCP:重试冲突延时数据包, 1 重新发送有冲突延迟的数据包。
DTU: 1 禁止重新发送“underruned”数据包。
ONEPM:单包模式。
1,发送完成前发送一个数据包的命令能被执行。
0,发送完成前发送最多两个数据包的命令能被执行。
IFGS:帧间间隔设置。
0XXX 为 96bit, 1000 为 64bit, 1001 为 72bit
1010 为 80bit, 1011 为 88bit, 1100 为 96bit
1101 为 104bit, 1110 位 112bit, 1111 为 120bit
ISR 寄存器(中断状态寄存器)
BIT | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
名称 | IOMODE | RESERVED | LNKCHG | UDRUN | ROO | ROS | PT | PR |
IOMODE: 0,16 位模式; 1,8 位模式。
LNKCHG:连接状态改变。
UDRUN:发送“Underrun”
ROO:接收溢出计数器溢出
ROS:接收溢出。
PT:数据包发送。
PR:数据包接收。
IMR 寄存器(中断状态寄存器)
BIT | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
名称 | PAR | RESERVED | LNKCHGI | UDRUNI | ROOI | ROSI | PTI | PRI |
PAR:使能 SRAM 的读/写指针在指针地址超过 SRAM 的大小时自动跳回起始位置。需要驱动程序设置该位,若设置该位, REG_F5 将自动置为 0XH。
LNKCHGI:使能连接状态改变中断。
UDRUNI:使能发送“Underrun”中断。
ROOI:使能接收溢出计数器溢出中断。
ROI:使能接收溢出中断。
PTI:使能数据包发送中断。
PRI:使能数据包接收中断。
2.6 DM9000 直接内存访问控制(DMAC)
DM9000 直接内存访问控制(DMAC)
DM9000 支持 DMA 方式简化对内部存储器的访问。在我们编程写好内部存储器地址后,就可以用一个读/写命令伪指令把当前数据加载到内部数据缓冲区,这样,内部存储器指定位置就可以被读/写命令寄存器访问。存储器地址将会自动增加,增加的大小与当前总线操作模式相同(比如:8-bit、 16-bit 或 32-bit),接着下一个地址数据将会自动加载到内部数据缓冲区。要注意的是在连续突发式第一次访问的数据应该被忽略,因为,这个数据是最后一次读写命令的内容。内部存储器空间大小 16K 字节。前 3K 字节单元用作发送包的缓冲区,其他 13K 字节用作接收包的缓冲区。所以在写存储器操作时,如果地址越界(即超出 3K 空间),在 IMR 寄存器 bit7 置位的情况下,地址指针将会返回到存储器 0 地址处。同样,在读存储器操作时,如果地址越界(即超出 16K 空间),在 IMR 寄存器 bit7 置位的情况下,地址指针将会返回到存储器 0x0C00 地址处。
DM9000 数据包发送
DM9000 有两个发送数据包: index1 和 index2,同时存储在 TX SRAM 中。发送控制寄存器(02h)控制循环冗余校验码(CRC)和填充(pads)的插入,其状态分别记录在发送状态寄存器I(03H)和发送状态寄存器 II(04H)中。发送器的起始地址为 0x00H,在软件或硬件复位后,默认的数据发送包为 index1。首先,使用 DMA 端口将数据写 TX SRAM 中,然后,在发送数据包长度寄存器中把数据字节数写入字节计数寄存器。置位发送控制寄存器的 bit0 位,则 DM9000 开始发送 index1 数据包。在 index1数据包发送结束之前,数据发送包 index2 被移入 TX SRAM 中。在 index1 数据包发送结束后,将 index2 数据字节数写入字节计数寄存器中,然后,置位发送控制寄存器的 bit0 位,则 index2数据包开始发送。以此类推,后面的数据包都以此方式进行发送。
DM9000 数据包接收
RX SRAM 是一个环形数据结构。在软件或硬件复位后, RX SRAM 的起始地址为 0X0C00。每个接收数据包都包含有 CRC 校验域,数据域,以及紧跟其后的 4 字节包头域。 4 字节包头格式为: 01h、状态、 BYTE_COUNT 低、 BYTE_COUNT 高。请注意:每个接收包的起始地址处在适当的地址边界,这取决于当前总线操作模式(8bit 或者 16bit)
2.7 DM9000原理图介绍
各信号线描述如下:
PWRST: DM9000 复位信号。
CS: DM9000 的片选信号。
WR(IOW): 处理器写命令。
RD(IOR): 处理器读命令。
CMD: 命令/数据标志, 0,读写命令; 1,读写数据。
SD0~SD15: 16 位双向数据线。
信号线对应的GPIO口对应关系
引脚名称 | GPIO口 | 功能说明 |
PWRST-->DM9000_RST | PD7 | 复位信号 |
CS-->FSMC_NE2 | PG9 | 片选信号 |
WR(IOW)-->FSMC_NWE | PD5 | 处理器写命令 | <