




已阅读5页,还剩72页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
毕业设计(论文)(2013届)题 目:基于AVR+ENC28J60的互联网基本协议栈实现专业名称: 通信工程 姓 名: 刘丽 学 号: 1013127244 班 级: 通信工程 指导教师: 张军 年 月 日摘 要物联网是新一代信息技术的重要组成部分。其英文名称是“The Internet of things”。由此,顾名思义,“物联网就是物物相连的互联网”。这有两层意思:第一,物联网的核心和基础仍然是互联网,是在互联网基础上的延伸和扩展的网络;第二,其用户端延伸和扩展到了任何物品与物品之间,进行信息交换和通信。物联网就是“物物相连的互联网”。物联网通过智能感知、识别技术与普适计算、泛在网络的融合应用,被称为继计算机、互联网之后世界信息产业发展的第三次浪潮。物联网是互联网的应用拓展,与其说物联网是网络,不如说物联网是业务和应用。因此,应用创新是物联网发展的核心,以用户体验为核心的创新2.0是物联网发展的灵魂。因此,发展微控制下的联网方案非常必要,所以必须开发出一套基本协议,这起始包括物理层,电气规则决定了整个系统的其他部件的设计,直到传输层TCP/UDP,高层协议预留开发接口,或使得互联网设备成为从机,方便更多的开发。虽然网上有著名的UIP协议栈,但模块没有分离,使用FS进行数据交换,不方便二次开发,所以,开发这个项目,就非常必要了。这里将从基础开发到实际应用,完全解释物联网的应用和基础内核开发。关键词:物联网,内核开发,通信协议目录第一章 平台选型61.1MCU平台分析61.1.1MSP430超低功耗微控制器61.1.2STC89C5x系列51传统单片机61.1.3STC90L5x低电压51单片机61.1.4宽电压PicPower技术AVR61.1.5Tiva新型ARM微控制器71.1.6Cypress最容易开发的微控制器71.2 为什么选择ENC28J6071.2.1W5100的优劣势分析71.2.2工业以太网现状分析71.2.3ENC28J60价廉物美81.2.4总体成本分析81.3 调试SPI接口91.3.1串行外设接口基础91.3.2串行外设接口配置实践101.3.3串行外设SS引脚详解121.3.4串行外设接口寄存器131.3.5串行外设接口数据模式141.4 电气设计141.4.1焊接测试141.4.2引脚参考151.4.3路由配置17第二章 硬件内核开发192.1 实现基本初始化通信192.1.1SPI调试192.1.2ENC28J60的寄存器的详细配置242.1.3ENC28J60寄存器汇总292.1.4ENC28J60基本上电初始化312.2 实现基本数据包发送接收332.2.1发送数据包332.2.1接收数据包342.3 IP协议的实现352.3.1协议分析352.3.2代码实现362.4 UDP协议的实现382.4.1协议分析392.4.2代码实现392.5 ARP协议的实现402.5.1协议分析402.5.2代码实现412.6 ICMP协议的实现442.6.1协议分析442.6.2代码实现452.7 DHCP协议的实现462.7.1协议分析462.7.2过程实现472.7.3代码实现492.8 其他功能512.8.1校验和计算512.8.2函数整合和文件分离52第三章 基于Arduino开源硬件的移植543.1 从AVR到Arduino平台543.1.1 为什么选用Arduino543.1.2 从C语言到C+543.1.3 从C+ 到 Arduino553.1.4 从Arduino到AVR563.1.5 附加函数概览573.2 从Arduino开始实践583.2.1 ICMP回显583.2.2 使用DHCP593.2.3 作为Web客户端603.2.4 WOL613.2.5 Web服务器623.2.6 DDNS633.2.7 LED灯控制633.2.8 LED灯图片按钮控制643.2.9 LED灯大图片按钮控制653.2.10 NTP时间同步663.2.11 开发方法总结673.2.12基于底层的二次开发68第四章 其他开发思想694.1 低功耗开发思想694.1.1 使用MSP430进行设备唤醒694.1.2 使用RTC进行设备唤醒694.2 实际项目开发思想694.2.1 使用WDT保证程序稳定性694.2.2 最迷你的硬件焊接与实际项目69第五章 总结715.1 遇到的问题与解决715.1.1 DNS屏蔽715.1.2 TCP连接数过大715.1.3 生成HEX文件批量生成715.1.4 DHCP无法使用725.1.5 DNS无法使用725.1.6 Arduino + Visual Studio 开发725.1.7 程序调试725.1.8 程序烧写到AVR上无法运行735.1.9 ENC28J60无法启动735.1.10 SPI无效735.1.11 Timer定时器计数735.2 应用解决方案735.2.1 串口转以太网735.2.2 家用物联网745.2.3 黑客设备74附录 参考文献75第一章 平台选型1.1 MCU平台分析1.1.1MSP430超低功耗微控制器德州仪器的超低功耗 16 位 RISC 混合信号处理器的MSP430微处理器平台为各种低功耗和便携式应用提供了最终解决方案。TI 为 MSP430 微处理器提供了包括技术文档、培训、工具和软件在内的功能强大的设计支持。但笔者们接入有线网络,考虑的应该不是高度节能,一句话说,MSP430是一个很省吃,但也干不了什么大活,是给一些便携的移动设备提供的。既然是便携式设备,怎么不考虑接入无线网络呢?另外F5/F6系列会非常贵,大概普通售价100元人民币一颗,TQFP封装.1.1.2STC89C5x系列51传统单片机虽然51单片机价格很便宜,而且STC的51单片机也支持IDLE模式,但就算是C58也不能满足需要的空间支持,速度也很慢,在以前的项目中知道,十二分频,或者六分频,都是慢得足以让系统认为网络设备超时,而且传统51单片机的供电电压也不满足大多数芯片的3.3V逻辑,还不如多花几毛钱买MSP430Gx系列呢,当然,几百字节的SRAM远远不足,虽然可以跑外部的RAM,但是成本也就提上去了.1.1.3STC90L5x低电压51单片机虽然51核心也有低压系列,但是速度就更加慢了,以至于笔者们无法忍受,而且功耗这个嘛,虽然长期供电,但是价格竟然比MSP430还贵。这么说来好像MSP430真是个不错的平台,可是他的内存大小实在无法忍受,虽然模拟思绪也能读取外部RAM,但是这毕竟性能和开发难度问题,也就只好用不选择了.1.1.4宽电压PicPower技术AVR宽电压AVR支持1.8V 5.5V逻辑,速度也能达到25MIPS,实测超频时候可以到达40MIPS,如果轮询数据包,那是效率非常高,虽然被人抛弃,被Cortex-M3遗弃,但也不表明他什么用途都没有,AVR虽然偏贵一点,但是对比ARM来说,那算什么呢?而且AVR是Atmel生产的,稳定性也非常不错的说。1.1.5Tiva新型ARM微控制器32位ARM,基于Cortex-M4F,问题是,笔者不涉及浮点运算,是不是有点浪费呢?所以,这个被忽略了,虽然你有专用定时器用于跑操作系统,但也不是笔者们想玩的。如果做的是主机芯片,那么还是非常有可能的。不过,笔者们小项目,用这个可能会出现严重的性能浪费.1.1.6Cypress最容易开发的微控制器不可否认,一行代码都不用写,就能写Cypress的程序,问题是,笔者们这里的程序逻辑这么复杂,他能满足吗?而且出了BUG还不能让笔者自己来修补,怎么能放心选用呢。1.2为什么选择ENC28J601.2.1W5100的优劣势分析W5100这个产品是硬件TCP/IP协议栈+MAC+PHY,也就是W5100里面用硬件逻辑电路实现了TCP/IP的协议栈结构,不需要向ENC28J60这样的网络控制器那样还需要一个资源较大的MCU跑软件协议栈。你直接把W5100当外部RAM使用,MCU初始化一下I/O,寄存器等就能使用了。是一种简易快速拓展Ethernet的方案,在稳定性及高效性方面表现也非常突出。” W5100是很多厂商以太网扩展板的选择,各种库文件都很齐全规范,使用起来也很容易。大多数人选择W5100的一个很大的原因在于W5100能有效释放主控单片机有限的内存资源,并且嵌入了经过市场验证的、成熟的硬件协议栈。关于价格的问题,因为高度集成了以太网协议栈,所以价格会偏高,不是笔者们需要的价廉物美,而且,如果协议开发得妥当,结构合理,还是很简单的说。1.2.2工业以太网现状分析现在工业以太网一般是10Mbps左右,温度范围-20 - 85。只要MCU和以太网控制芯片不结露,看门狗正常,一般不会出任何问题。W5100完全满足,只是价格太高,批量生产的话,划不过来,W5100的价格是ENC28J60价格的2 3倍。如图1-2-2-1.图1-2-2-1如果选择ENC28J60虽然要自己设计电路,但其实便宜很多了。SOP的ENC228J60图1-2-2-2。图1-2-2-21.2.3ENC28J60价廉物美上面已经说明了ENC28J60的廉价,因为他没有集成任何协议,所以可以开发出更多的东西,比如现在的IPv6,本文会稍有说明的,虽然ENC28J60开发的失误随时能造成网络风暴等很多不可预知的事件,不过,不用担心,本论文将一步一步说明协议的开发。另外ENC28J60一样可以兼容HR911105A变压器(带RJ45头),还有内置的MAC+PHY,一样省了不少元器件。1.2.4总体成本分析笔者们的微控制器是Atmel AVR,虽然看起来很贵,但是稳定性很好,之前已经分析过了,计算式Atmel MEGA2560也就是100元以内,加上ENC28J60都很便宜,这里做的是伴随嘛,选的比较低配的Atmel Mega8或者低压的Atmel Mega8L,开发测试为了方便使用Atmel Mega16嘛,编程器也可以自己制作,一点压力都没有。如果后期笔者还可以走Atmel Mega328P,容量大体积小各种优势。而且可以封装Arduino库文件,这样就可以在Atmel Mega328上跑一些类似操作系统的东西玩了,当然,那不是操作系统,但是这样将可以让Arduino使用ENC28J60,此前,所有Arduino接入互联网都是使用W5100的。虽然,Arduino比较便宜,或者说不太适合底层开发,但是在底层做好库文件,然后上层提高快速建模,也是非常方便的。1.3调试SPI接口1.3.1串行外设接口基础接口SPI 允许ATmega和外设或其他AVR 器件进行高速的同步数据传输。 他有很多常规的特性,如下:n 全双工,三线同步。n 主机或从机操作。n LSB/MSB操作n 可编程比特率n 传输结束置位中断n 写碰撞检测n 可以进入IDLE模式n 具有倍速模式图1-3-1-1 主机和从机之间的SPI 连接如SPI主从互连逻辑图所示,系统包括两个移位寄存器和一个主机时钟发生器。通过将需要的从机的 SS 引脚拉低,主机启动一次通讯过程。主机和从机将需要发送的数据放入相应的移位寄存器。主机在SCK 引脚上产生时钟脉冲以交换数据。主机的数据从主机的MOSI 移出,从从机的MOSI 移入;从机的数据从从机的MISO 移出,从主机的MISO 移入。主机通过将从机的SS 拉高实现与从机的同步。配置为SPI 主机时, SPI 接口不自动控制 SS 引脚,必须由用户软件来处理。 对 SPI 数据寄存器写入数据即启动SPI 时钟,将8 比特的数据移入从机。传输结束后SPI 时钟停止,传输结束标志SPIF 置位。如果此时SPCR 寄存器的SPI 中断使能位SPIE 置位,中断就会发生。主机可以继续往SPDR 写入数据以移位到从机中去,或者是将从机的SS 拉高以说明数据包发送完成。最后进来的数据将一直保存于缓冲寄存器里。配置为从机时,只要SS 为高,SPI 接口将一直保持睡眠状态,并保持MISO 为三态。在这个状态下软件可以更新SPI 数据寄存器SPDR 的内容。即使此时SCK 引脚有输入时钟,SPDR 的数据也不会移出,直至SS 被拉低。一个字节完全移出之后,传输结束标志SPIF置位。如果此时SPCR寄存器的SPI中断使能位SPIE置位,就会产生中断请求。在读取移入的数据之前从机可以继续往SPDR 写入数据。最后进来的数据将一直保存于缓冲寄存器里。图1-3-1-2SPI 系统的发送方向只有一个缓冲器,而在接收方向有两个缓冲器。也就是说,在发送时一定要等到移位过程全部结束后才能对SPI 数据寄存器执行写操作。而在接收数据时,需要在下一个字符移位过程结束之前通过访问SPI 数据寄存器读取当前接收到的字符。否则第一个字节将丢失。工作于SPI 从机模式时,控制逻辑对SCK 引脚的输入信号进行采样。为了保证对时钟信号的正确采样, SPI 时钟不能超过fosc/4。SPI 使能后,MOSI、MISO、SCK 和SS 引脚的数据方向将按照引脚映射表所示自动进行配置。引脚SPI主机SPI从机MOSI用户定义输入MISO输入用户定义SCK用户定义输入SS用户定义输入1.3.2串行外设接口配置实践下面的例程说明如何将SPI 初始化为主机,以及如何进行简单的数据发送。例子中DDR_SPI必须由实际的数据方向寄存器代替;DD_MOSI、DD_MISO和DD_SCK必须由实际的数据方向代替。比如说, MOSI 为PB5 引脚,则DD_MOSI 要用DDB5 取代,DDR_SPI 则用DDRB 取代。汇编语言:SPI_MasterInit:; 设置MOSI 和SCK 为输出,其他为输入ldi r17,(1DD_MOSI)|(1DD_SCK)out DDR_SPI,r17; 使能SPI 主机模式,设置时钟速率为fck/16ldi r17,(1SPE)|(1MSTR)|(1SPR0)out SPCR,r17retSPI_MasterTransmit:; 启动数据传输(r16)out SPDR,r16Wait_Transmit:; 等待传输结束sbis SPSR,SPIFrjmp Wait_TransmitretC语言:void SPI_MasterInit(void)/* 设置MOSI 和SCK 为输出,其他为输入 */DDR_SPI = (1DD_MOSI)|(1DD_SCK);/* 使能SPI 主机模式,设置时钟速率为fck/16 */SPCR = (1SPE)|(1MSTR)|(1SPR0);void SPI_MasterTransmit(char cData)/* 启动数据传输 */SPDR = cData;/* 等待传输结束 */while(!(SPSR & (1SPIF);下面的例子说明如何将SPI 初始化为从机,以及如何进行简单的数据接收。汇编语言:SPI_SlaveInit:; 设置MISO 为输出,其他为输入ldi r17,(1DD_MISO)out DDR_SPI,r17; 使能 SPIldi r17,(1SPE)out SPCR,r17retSPI_SlaveReceive:; 等待接收结束sbis SPSR,SPIFrjmp SPI_SlaveReceive; 读取接收到的数据,然后返回in r16,SPDRretC语言:void SPI_SlaveInit(void)/* 设置MISO 为输出,其他为输入 */DDR_SPI = (1DD_MISO);/* 使能 SPI */SPCR = (1SPE);char SPI_SlaveReceive(void)/* 等待接收结束 */while(!(SPSR & (1SPIF);/* 返回数据 */return SPDR; 1.3.3串行外设SS引脚详解当SPI 配置为主机时,从机选择引脚SS 总是为输入。SS 为低将激活SPI 接口, MISO成为输出( 用户必须进行相应的端口配置) 引脚,其他引脚成为输入引脚。当SS 为高时所有的引脚成为输入, SPI 逻辑复位,不再接收数据。SS引脚对于数据包/字节的同步非常有用,可以使从机的位计数器与主机的时钟发生器同步。当SS 拉高时SPI从机立即复位接收和发送逻辑,并丢弃移位寄存器里不完整的数据。当SPI 配置为主机时(MSTR 的SPCR 置位),用户可以决定SS 引脚的方向。若SS 配置为输出,则此引脚可以用作普通的I/O 口而不影响SPI 系统。典型应用是用来驱动从机的SS 引脚。如果SS 配置为输入,必须保持为高以保证SPI 的正常工作。若系统配置为主机, SS 为输入,但被外设拉低,则SPI 系统会将此低电平解释为有一个外部主机将自己选择为从机。为了防止总线冲突, SPI 系统将实现如下动作:n 清零SPCR 的MSTR 位,使SPI 成为从机,从而MOSI 和SCK 变为输入。n SPSR 的SPIF 置位。若SPI 中断和全局中断开放,则中断服务程序将得到执行。因此,使用中断方式处理SPI 主机的数据传输,并且存在SS 被拉低的可能性时,中断服务程序应该检查MSTR 是否为1。若被清零,用户必须将其置位,以重新使能SPI 主机模式。1.3.4串行外设接口寄存器SPCR寄存器SPIESPEDORDMSTRCPOLCPHASPR1SPR0R/W-0R/W-0R/W-0R/W-0R/W-0R/W-0R/W-0R/W-0Bit 7 SPIE: 使能SPI 中断 置位后,只要SPSR 寄存器的SPIF 和SREG 寄存器的全局中断使能位置位,就会引发 SPI 中断。Bit 6 SPE: 使能SPI SPE 置位将使能SPI。进行任何SPI 操作之前必须置位SPE。Bit 5 DORD: 数据次序 DORD 置位时数据的LSB 首先发送;否则数据的MSB 首先发送。Bit 4 MSTR: 主 / 从选择 MSTR置位时选择主机模式,否则为从机。如果MSTR为1”,SS配置为输入,但被拉低,则MSTR 被清零,寄存器SPSR 的SPIF 置位。用户必须重新设置MSTR 进入主机模式。Bit 3 CPOL: 时钟极性 CPOL 置位表示空闲时SCK 为高电平;否则空闲时SCK 为低电平。CPOL配置结果如下表:CPOL起始沿结束沿0上升沿下降沿1下降沿上升沿Bit 2 CPHA: 时钟相位CPHA 决定数据是在SCK 的起始沿采样还是在SCK 的结束沿采样。CPHA配置结果如下表:CPHA起始沿结束沿0采样采样1设置设置Bits 1, 0 SPR1, SPR0: SPI 时钟速率选择 1 与 0 确定主机的SCK 速率。SPR1 和SPR0 对从机没有影响。SPRx配置结果如下表:SPI2XSPR1SPR0SCK000fosc/4001fosc/16010fosc/64011fosc/128100fosc/2101fosc/8110fosc/32111fosc/64SPSR寄存器SPIFWCOLSPI2XR-0R-0R-0R-0R-0R-0R-0R/W-0Bit 7 SPIF: SPI 中断标志串行发送结束后,SPIF 置位。若此时寄存器SPCR 的SPIE 和全局中断使能位置位,SPI中断即产生。如果SPI 为主机, SS 配置为输入,且被拉低, SPIF 也将置位。进入中断服务程序后SPIF自动清零。或者可以通过先读SPSR,紧接着访问SPDR来对SPIF清零。Bit 6 WCOL: 写碰撞标志在发送当中对SPI 数据寄存器SPDR写数据将置位WCOL。WCOL可以通过先读SPSR,紧接着访问SPDR 来清零。Bit 0 SPI2X: SPI 倍速置位后SPI 的速度加倍。若为主机,则SCK 频率可达CPU 频率的一半。若为从机,只能保证fosc /4。SPDR寄存器DDDDDDDDR/WR/WR/WR/WR/WR/WR/WR/WSPI 数据寄存器为读/写寄存器,用来在寄存器文件和SPI移位寄存器之间传输数据。写寄存器将启动数据传输,读寄存器将读取寄存器的接收缓冲器。1.3.5串行外设接口数据模式相对于串行数据,SCK 的相位和极性有4 种组合。CPHA 和CPOL 控制组合的方式。每一位数据的移出和移入发生于SCK不同的信号跳变沿,以保证有足够的时间使数据稳定。其中图1-2-3-3中CPHA = 0(左)/CPHA = 1(右)。图1-3-1-31.4电气设计1.4.1焊接测试刚开始也先不打板了,万一失败了成本很高。所以,先做简单的焊接。 图1-4-1-1然后还要各种电路连接,所以,电路图是必须要画好的。简单连接图:图1-4-1-2图1-4-1-3当然,现在只是测试,所以,剪线什么的,在面包板上测试,还有很多测试线,都是按照电路图连接的,就不展示了。最后会给大家看看成品,成品笔者会使用热转印做PCB,效果应该会不错的,因为以前笔者做很多作品也是用热转印,笔者喜欢使用热转印是因为便宜,而且笔者有迷你激光打印机,条件不错嘛,对吧。都是笔者自己做项目赚回来的。1.4.2引脚参考不会无缘无故地有连接电路图,但是不先解释连接电路图,又很难往下解释,先从引脚参考下手说明一下吧。ENC28J60由7个模块组成。n SPI接口n 控制寄存器和状态机n 双端口RAM缓冲器n 判优器DMA对RAM缓冲器的写入权限进行仲裁n 总线解释接口SPI指令解释n MAC模块n PHY对双绞线上的模拟数据进行处理图1-4-2-1那几个SPI引脚接法就不用考虑了,接MCU的。图1-4-2-2振荡器引脚按照经典的接法,当然,另一种方法是OSC2悬空,OSC1使用外部时钟源输出,RJ45使用官方推荐接法,但是使用的铁氧体磁环额定电流至少100 mA。引脚一览表:引脚名引脚号引脚 类型缓冲器 类型说明SSOPQFNVCAP125P来自内部稳压器的 2.5V 输出。必须将此引脚通过一个 10 F 的电容连接 到 VSSTX。VSS226P参考接地端。CLKOUT327O可编程时钟输出引脚。 INT428OINT 中断输出引脚。 WOL51OLAN 中断唤醒输出引脚。 SO62OSPI 接口的数据输出引脚。 SI73ISTSPI 接口的数据输入引脚。 SCK84ISTSPI 接口的时钟输入引脚。 CS95ISTSPI 接口的片选输入引脚。 RESET106IST低电平有效器件复位输入。 VSSRX117PPHY RX 的参考接地端。TPIN-128IANA差分信号输入。TPIN+139IANA差分信号输入。RBIAS1410IANAPHY 的偏置电流引脚。必须将此引脚通过 2 k (1%)的电阻连接到VSSRX。VDDTX1511PPHY TX 的正电源端。TPOUT-1612O差分信号输出。TPOUT+1713O差分信号输出。VSSTX1814PPHY TX 的参考接地端。VDDRX1915PPHY RX 的正 3.3V 电源端。VDDPLL2016PPHY PLL 的正 3.3V 电源端。VSSPLL2117PPHY PLL 的参考接地端。VSSOSC2218P振荡器的参考接地端。OSC12319IDIG振荡器输入。OSC22420O振荡器输出。VDDOSC2521P振荡器的正 3.3V 电源端。LEDB2622OLEDB 驱动引脚。 LEDA2723OLEDA 驱动引脚。 VDD2824P正 3.3V 电源端。I = 输入, O = 输出, P = 电源, DIG = 数字输入, ANA = 模拟信号输入, ST = 施密特触发器1.4.3路由配置以后实验DHCP各种的,都需要这些的哈。不过笔者采用Linux系统的路由,以后会一次又一次地展示界面,各种配置先放默认。图1-4-2-3如果使用Windows不配置DHCP,则可以调整物理网卡到ENC28J60为同一网段,即可测试。比如ENC28J60的IP是静态配置为192.168.56.5的话,配置计算机时候只需要设置成同一网段就行。图1-4-2-4第二章 硬件内核开发2.1实现基本初始化通信2.1.1SPI调试使用SPI进行发送测试,测试稳定性。先根据MCU的硬件电路改变接口,为了以后方便,还是声明一下哈。/ ENC28J60 SPI port#define ENC28J60_SPI_PORTPORTB#define ENC28J60_SPI_DDRDDRB#define ENC28J60_SPI_SCK7#define ENC28J60_SPI_MOSI5#define ENC28J60_SPI_MISO6#define ENC28J60_SPI_SS4/ ENC28J60 Control Port#define ENC28J60_CONTROL_PORTPORTB#define ENC28J60_CONTROL_DDRDDRB#define ENC28J60_CONTROL_CS4数据发送到自己开发的一个FSM从机,如果这个也要写,这篇论文,得变长一倍。图2-1-1-1现在数据测试证明是可以的。一点差错都没有,好,笔者们开始下一步的开发。这里用到的代码很简单,只是用于测试硬件,以后的代码中也会体现到,所以,不公开了哈。当然,这个ENC28J60的SPI比较高级,不是发送一个字节什么的。笔者们看看发送格式。指令名称和助记符字节0字节1操作码参数数据RCR000控制寄存器地址-RBM00111010-WCR010控制寄存器地址数据负载WBM01111010数据负载BFS100控制寄存器地址数据负载BFC101控制寄存器地址数据负载SC11111111-其中RCR,RBM这些都是助记符,RCR是读控制寄存器,RBM是读缓冲器,WCR是写控制寄存器,WBM是写缓冲器,BFS是位域置位,BFC是位域清零,SC是软件复位。这里有一个规律,后五位是与前三位不同的,所以,采用掩码法处理数据。笔者定义了ADDR_MASK作为掩码,ADDR_MASK = 0x1F,生成一个读操作的函数。unsigned char enc28j60ReadOp(unsigned char op, unsigned char address)unsigned char data;ENC28J60_CONTROL_PORT &= (1ENC28J60_CONTROL_CS);SPDR = op | (address & ADDR_MASK);while(!(SPSR & (1SPIF);SPDR = 0x00;while(!(SPSR & (1SPIF);if(address & 0x80)SPDR = 0x00;while(!(SPSR) & (1SPIF);data = SPDR;ENC28J60_CONTROL_PORT |= (1ENC28J60_CONTROL_CS);return data;同理,能做一个写操作的函数。void enc28j60WriteOp(unsigned char op, unsigned char address, unsigned char data)ENC28J60_CONTROL_PORT &= (1ENC28J60_CONTROL_CS);SPDR = op | (address & ADDR_MASK);while(!(SPSR & (1SPIF);SPDR = data;while(!(SPSR & (1SPIF);ENC28J60_CONTROL_PORT |= (1ENC28J60_CONTROL_CS);读缓冲存储器(Read Buffer Memory,RBM)命令允许 主控制器从 8 KB 发送和接收缓冲存储器中读取字节。如果 ECON2 寄存器中的 AUTOINC 位置 1,那么在读 完每个字节的最后一位之后, ERDPT 指针将会自动地 递增指向下一个地址。正常情况下下一个地址为当前地 址加 1。 然而,如果读取了接收缓冲器中的最后一个字 节 (ERDPT = ERXND),则 ERDPT 指针将转而指向 接收缓冲器的起始单元。这样主控制器可以从接收缓冲 器中连续读取数据包,而无须跟踪何时需要折回。当读 取地址 1FFFh 时,如果 AUTOINC 被置 1,且 ERXND 没有指向该地址时,则读指针将递增并折回到 0000h。将 CS 引脚拉为低电平启动 RBM 命令。然后将 RBM 操 作码及随后的 5 位常量 1Ah 发送给 ENC28J60。在发送 RBM 命令和常量后,由 ERDPT 指向的存储器中的数据 将从 SO 引脚移出,首先移出最高位。如果主控制器继 续在 SCK 引脚提供时钟信号,而没有拉高 CS 的电平, ERDPT 指向的字节将再次从 SO 引脚移出,同样首先 移出最高位。当 AUTOINC 被使能时,使用该方式就可 以连续地从缓冲存储器中顺序读取字节而无需多余的 SPI 命令。拉高 CS 引脚电平可以结束 RBM 命令。void enc28j60ReadBuffer(unsigned short len, unsigned char* data)ENC28J60_CONTROL_PORT &= (1ENC28J60_CONTROL_CS);SPDR = ENC28J60_READ_BUF_MEM;while(!(SPSR & (1SPIF);while(len-)SPDR = 0x00;while(!(SPSR & (1SPIF);*data+ = SPDR;ENC28J60_CONTROL_PORT |= (1ENC28J60_CONTROL_CS);发送数据包之前要先写入数据到缓冲区,使用WBM指令,写缓冲存储器 (Write Buffer Memory, WBM)命令允 许主控制器将字节写入 8KB 发送和接收缓冲存储器。如果 ECON2 寄存器中的 AUTOINC 位置 1,那么在写 完每个字节的最后一位之后, EWRPT 指针将会自动地 递增指向下一个地址 (当前地址加 1)。 如果写入地址 1FFF 且 AUTOINC 置 1,则写指针加 1 指向 0000h。将 CS 引脚拉为低电平启动 WBM 命令。然后将 WBM 操作码及随后的 5 位常量 1Ah 送入 ENC28J60。在发送 WBM 命令和常量之后,由 EWRPT 指向的存储器中的 数据将移入 ENC28J60,首先移入最高位。 在接收到 8 个数据位后,如果 AUTOINC 置 1,写指针将自动递增。主控制器可以继续在 SCK 引脚提供时种信号、在 SI 引 脚发送数据同时保持 CS 为低电平,从而可以连续写入 存储器。当 AUTOINC 被使能时,以该方式就可以连续 地向缓冲存储器写入字节而无需多余的 SPI 命令。拉高 CS 引脚电平可结束 WBM 命令。所以,WBM指令也是会有点复杂。void enc28j60WriteBuffer(unsigned short len, unsigned char* data)ENC28J60_CONTROL_PORT &= (1ENC28J60_CONTROL_CS);SPDR = ENC28J60_WRITE_BUF_MEM;while(!(SPSR & (1SPIF);while(len-)SPDR = *data+;while(!(SPSR & (1SPIF);ENC28J60_CONTROL_PORT |= (15);Enc28j60Bank = (address & BANK_MASK);理所当然地设置寄存器了,这个才是真正的寄存器读写函数。读控制寄存器(Read Control Register,RCR)命令允 许主控制器随意读取 ETH、 MAC 和 MII 寄存器。将 CS 引脚拉为低电平启动 RCR 命令。然后将 RCR 操 作码和随后的 5 位寄存器地址 (A4 到 A0)发送给 ENC28J60。5 位地址决定将使用当前存储区中 32 个控制寄存器中的哪一个。如果 5 位地址指向的是一个 ETH 寄存器,那么选定寄存器中的数据会立即开始从 SO 引 脚移出,最高位在前。图 4-3 显示了这些寄存器的读取 序列。如果地址指向了一个 MAC 或 MII 寄存器,则首先从 SO 引脚移出一个无效数据字节,随后从SO引脚移出数据, 最高位在前。通过拉高 CS 引脚的电平可结束 RCR 操 作。unsigned char enc28j60Read(unsigned char address)enc28j60SetBank(address);return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address);写控制寄存器(Write Control Register,WCR)命令允 许主控制器以任何次序写入 ETH、 MAC 和 MII 控制寄 存器。将 CS 引脚拉为低电平启动 WCR 命令。然后将 WCR 操作码及随后的 5 位地址 (A4 到 A0)发送给 ENC28J60。5 位地址决定要使用当前存储区中 32 个控 制寄存器中的哪一个。在发送 WCR 命令和地址后,发 送要实际写入的数据,首先发送最高位。 在 SCK 的上 升沿,数据被写入目标寄存器。拉高 CS 引脚的电平可结束 WCR 操作。 如果在装载 8 个位前, CS 线变为高电平,则将中止这个数据字节的 写操作。void enc28j60Write(unsigned char address, unsigned char data)enc28j60SetBank(address);enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, data);还有PHY寄存器呢,他是很特别的,读取顺序很特别。n 把PHY寄存器地址写入MIREGADRn 置位MICMD的MIIRD寄存器n 等待MISTAT的MIIRD寄存器完成n 将MICMD清零n 读取MIRDL寄存器n 读取MIRDH寄存器虽然看起来很麻烦,程序也不过是几行的事情。unsigned short enc28j60PhyRead(unsigned char address)unsigned short data;enc28j60Write(MIREGADR, address);enc28j60Write(MICMD, MICMD_MIIRD);while(enc28j60Read(MISTAT) & MISTAT_BUSY);enc28j60Write(MICMD, 0x00);data = enc28j60Read(MIRDL);data |= enc28j60Read(MIRDH);return data;写PHY寄存器时,将一次写入全部的 16位数据,不能对位进行写操作。 如果只需要重新编程寄存器中的某几位,控制器必须首先读PHY寄存器,修改读到的数据,然后将数据写回PHY寄存器。n 将要写入的PHY寄存器的地址写入MIREGADR寄存器。n 将数据的低8 位写入MIWRL寄存器。n 将数据的高8 位写入MIWRH寄存器。 对MIWRH寄存器的写操作会自动启动MII事务,所以必须在写入 MIWRL 后才能写入该寄存器。MISTAT.BUSY位置1。n 在MII操作完成后写PHY寄存器,用时10.24 s。当写操作完成后,BUSY 位将自动清零。 在忙时主控制器不应开始MIISCAN或MIIRD 操作。void enc28j60PhyWrite(unsigned char address, unsigned short data)enc28j60Write(MIREGADR, address);enc28j60Write(MIWRL, data);enc28j60Write(MIWRH, data8);while(enc28j60Read(MISTAT) & MISTAT_BUSY);2.1.2ENC28J60的寄存器的详细配置莫名奇妙的多了很多寄存器的名字,当然,他们不是凭空产生的。所以,笔者整理了一下,做了个头文件。/ All-bank registers#define EIE0x1B#define EIR0x1C#define
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年中医护理专业就业能力测试试题及答案
- 2025年网络空间安全与防御能力考试试卷及答案
- 2025年土木工程与建筑材料考试试题及答案
- 2025年人工智能伦理与法律考试试卷及答案
- 2025年老年护理与健康管理专业能力测评考试卷及答案
- 2025年历史与文化遗产知识测试卷及答案
- 2025年国际经济与贸易专业知识测试卷及答案
- 2025年公共艺术创作与策展课程考试试题及答案
- 2025年城市生态规划师考试试题及答案
- 2024年度浙江省二级造价工程师之建设工程造价管理基础知识自我提分评估(附答案)
- 2023年济南历下控股集团有限公司招聘笔试题库及答案解析
- 2022年医学专题-感染性休克指南解读
- 流行病学传染病流行病学幻灯片
- 冬虫夏草PPT幻灯片
- 保险课堂-儿童教育金保险课件
- 药物配伍禁忌查询表
- 水 泵 安 装 记 录
- 大健康产业商业计划书
- GB∕T 7528-2019 橡胶和塑料软管及软管组合件 术语
- 常州市机械行业安管考试题库
- FANUC机器人R-2000iA机械单元维护手册
评论
0/150
提交评论