用于ATmega设备的Wiznet W5100库
一开始,我从ermicroblog网站上下载并加载代码。这些代码都是由RWB开发的,他开创了一个很好的开端。我尤其是喜欢RWB一步一步演绎一个完整例子的过程,有一行行的代码作为理论基础,没有头文件会丢失,也不需要后台代码作支撑。
我重新编写了RWB的代码,并且创建一个W5100设备库。请注意这个库内的目标是相互独立的。这就意味着你可以链接任何ATmega项目的代码而不需要每次都对库进行重建,因为你的硬件和我的不兼容。这种独立性来自一个叫做W51_register()的成熟调用例程,它允许你通过函数指针设置到库内进行具体的目标测试,比如启用/禁用W5100芯片和通过设备进行数据交换。
W5100库代码
以下是W5100库模块的代码。不像RWB的代码,我的代码使用了一个头文件(源于RWB的代码和微知纳特数据手册的结合);你可以在页面最底部的的压缩包文件看到它。
/*
* w5100.c library of target-independent AVR support routines
* for the Wiznet W5100 Ethernet inte易做图ce device
*
* This file is derived from the excellent work found here:
* www.ermicro.com/blog/?p=1773
* by RWB. I am leaving the header from the original file intact below,
* but you need to remember the rest of the source here is fairly
* heavily modified. Go to the above site for the original.
*/
/*****************************************************************************
// File Name : wiznetping.c
// Version : 1.0
// Description : Wiznet W5100
// Author : RWB
// Target : AVRJazz Mega168 Board
// Compiler : AVR-GCC 4.3.2; avr-libc 1.6.6 (WinAVR 20090313)
// IDE : Atmel AVR Studio 4.17
// Programmer : AVRJazz Mega168 STK500 v2.0 Bootloader
// : AVR Visual Studio 4.17, STK500 programmer
// Last Updated : 01 July 2010
*****************************************************************************/
/*
* The following code turns the above wiznetping.c source code into a
* generic library of W5100 support routines that are target-independent.
* That is, you build this library for a generic AVR ATmega device, then
* write your application to use the W51_xxx routines below for accessing
* the W5100 chip. Because these routines are target-independent, you
* never have to rebuild them just because you are moving your code from,
* say, a ‘mega128 to an ‘xmega128a1 device.
*
* For this to work properly, your application must provide three target-
* specific functions and must register the addresses of those functions
* with the W5100 library at run-time. These functions are:
*
* select target-specific function for enabling the W5100 chip
* xchg target-specific function for exchanging a byte with the W5100 chip
* deselect target-specific function for disabling the W5100 chip
* reset target-specific function for hardware reset of the W5100 chip
*
* Your application registers these three functions with the W5100 library
* by invoking the W51_register() function. Your application must make this
* call one time and must make this call before calling any other W5100
* functions.
*/
#include <util/delay.h>
#include “w5100.h”
#ifndef FALSE
#define FALSE 0
#define TRUE !FALSE
#endif
/*
* Define the function pointers used to access the SPI port assigned to the
* W5100 device. These pointers will be filled in at run-time when the host
* calls W51_register().
*/
static void (*select)(void) = (void *)0;
static unsigned char (*xchg)(unsigned char val) = (void *)0;
static void (*deselect)(void) = (void *)0;
static void (*reset)(void) = (void *)0;
static unsigned char inited = FALSE;
void W51_register(W5100_CALLBACKS *pcallbacks)
{
select = pcallbacks->_select;
xchg = pcallbacks->_xchg;
deselect = pcallbacks->_deselect;
reset = pcallbacks->_reset;
inited = FALSE;
if ((select) && (xchg) && (deselect)) inited = TRUE; // these functions must be valid
}
void W51_write(unsigned int addr, unsigned char data)
{
if (!inited) return; // not set up, ignore request
select(); // enable the W5100 chip
xchg(W5100_WRITE_OPCODE); // need to write a byte
xchg((addr & 0xff00) >> 8); // send MSB of addr
xchg(addr & 0xff); // send LSB
xchg(data); // send the data
deselect(); // done with the chip
}
unsigned char W51_read(unsigned int addr)
{
unsigned char val;
if (!inited) return 0; // not set up, ignore request
select(); // enable the W5100 chip
xchg(W5100_READ_OPCODE); // need to read a byte
xchg((addr & 0xff00) >> 8); // send MSB of addr
xchg(addr & 0xff); // send LSB
val = xchg(0×00); // need to send a dummy char to get response
deselect(); // done with the chip
return val; // tell her what she’s won
}
void W51_init(void)
{
if (reset) reset(); // if host provided a reset function, use it
else W51_write(W5100_MR, W5100_MR_SOFTRST); // otherwise, force the w5100 to soft-reset
_delay_ms(1);
}
unsigned char W51_config(W5100_CFG *pcfg)
{
if (pcfg == 0) return W5100_FAIL;
W51_write(W5100_GAR + 0, pcfg->gtw_addr[0]); // set up the gateway address
W51_write(W5100_GAR + 1, pcfg->gtw_addr[1]);
W51_write(W5100_GAR + 2, pcfg->gtw_addr[2]);
W51_write(W5100_GAR + 3, pcfg->gtw_addr[3]);
_delay_ms(1);
W51_write(W5100_SHAR + 0, pcfg->mac_addr[0]); // set up the MAC address
W51_write(W5100_SHAR + 1, pcfg->mac_addr[1]);
W51_write(W5100_SHAR + 2, pcfg->mac_addr[2]);
W51_write(W5100_SHAR + 3, pcfg->mac_addr[3]);
W51_write(W5100_SHAR + 4, pcfg->mac_addr[4]);
W51_write(W5100_SHAR + 5, pcfg->mac_addr[5]);
_delay_ms(1);
W51_write(W5100_SUBR + 0, pcfg->sub_mask[0]); // set up the subnet mask
W51_write(W5100_SUBR + 1, pcfg->sub_mask[1]);
W51_write(W5100_SUBR + 2, pcfg->sub_mask[2]);
W51_write(W5100_SUBR + 3, pcfg->sub_mask[3]);
_delay_ms(1);
W51_write(W5100_SIPR + 0, pcfg->ip_addr[0]); // set up the source IP address
W51_write(W5100_SIPR + 1, pcfg->ip_addr[1]);
W51_write(W5100_SIPR + 2, pcfg->ip_addr[2]);
W51_write(W5100_SIPR + 3, pcfg->ip_addr[3]);
_delay_ms(1);
W51_write(W5100_RMSR, 0×55); // use default buffer sizes (2K bytes RX and TX for each socket
W51_write(W5100_TMSR, 0×55);
return W5100_OK; // everything worked, show success
}
使用库
下面来教你使用这个库。创建一个新的AVRStudio4项目,并且在你的项目(记得修改你的项目配置中文件夹的大小,以便能放得下W5100.h文件)里添加W5100.h头文件。同时修改你的项目配置来添加W5100库,以便你在建立项目时连接器能找到它。
在你的资源库中,你需要写下三个(也可以是4个)具体目标例程。这三个必需的例程可以实现通过总线访问电路板中的W5100芯片。select()例程用来选择端口线与W5100设备进行连接。deselect()例程的作用是取消对W5100设备的选择。xchg()例程的作用是,每当通过总线向W5100发送一个字节的数据,会同时向调用例程返回一个字节的数据。有时候,你可能还会用到reset()例程,它的作用是使端口线重置W5100设备。我真心建议你将来在硬件设置中使用它,因为有时在W5100启动时会遇到一些故障,到时候你对它重置,就省事多了。
项目案例(网络服务器)
以下代码是使用库建立的网络服务器案例。
#include <avr/io.h>
#include <string.h>
#include <stdio.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include “w5100.h”
unsigned char OpenSocket(unsigned char sock, unsigned char eth_protocol, unsigned int tcp_port);
void CloseSocket(unsigned char sock);
void DisconnectSocket(unsigned char sock);
unsigned char Listen(unsigned char sock);
unsigned
补充:综合编程 , 其他综合 ,