本帖最后由 湛只为无双 于 2015-2-23 11:29 编辑
三、W5500的相关配置: W5500的配置主要包括了对SOCKET中FIFO的SIZE设置,在这里采用了EmbedNet论坛中所给出的默认配置,即八个SOCKET的收发缓冲全为2KB。具体设置如下:
- uint8_t memsize[2][8] = {{2,2,2,2,2,2,2,2},{2,2,2,2,2,2,2,2}};
- /* SOCKET缓冲的初始化——使用了memsize中的数据进行发送接收缓冲的初始化 */
- if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1)
- {
- printf("WIZCHIP Initialized fail.\r\n");
- while(1);
- }
第二步是对PHY连接状态的初始化,等待PHY连接成功:
- /* PHY的链接状态初始化 */
- do
- {
- if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1)
- {
- printf("Unknown PHY Link stauts.\r\n");
- }
- }
- while(tmp == PHY_LINK_OFF);
第三步是对本机的设置,包括了本机的MAC,本机的IP、网关、子网掩码、DNS服务器和DHCP状态:
- wiz_NetInfo gNETINFO = { .mac = {0x01, 0x23, 0x45,0x67, 0x89, 0xab},
- .ip = {192, 168, 2, 123},
- .sn = {255,255,255,0},
- .gw = {192, 168, 2, 1},
- .dns = {0,0,0,0},
- .dhcp = NETINFO_STATIC
- };
- /* 网口的初始化 包括了MAC 本机IP 网关 子网掩码 DNS服务器 和 DHCP状态 */
- do
- {
- if(network_init() == 0)
- {
- printf("Net is OK\r\n");
- break;
- }
- else
- {
- printf("Net is Error\r\n");
- }
- delay_ms(500);
- }while(1);
- //当初始换这个后,如果没有错误,实际上就已经可以PING通了
在这个里面的network_init函数如下:
在此可以判断W5500是否已经连接上了:
- u8 network_init(void)
- {
- wiz_NetInfo lNETINFO={0};
- uint8_t *plNETINFO,*pgNETINFO,i;
-
- ctlnetwork(CN_SET_NETINFO, (void*)&gNETINFO);
- ctlnetwork(CN_GET_NETINFO, (void*)&lNETINFO);
-
- plNETINFO=(uint8_t*)&lNETINFO;
- pgNETINFO=(uint8_t*)&gNETINFO;
-
- for(i=0;i<sizeof(gNETINFO);i++)
- {
- if(*plNETINFO != *pgNETINFO)
- {
- return 1;
- }
- plNETINFO++;
- pgNETINFO++;
- }
- }
- //当有W5500正常将会返回0,否则返回1。
第四步是可选设置,设置溢出时间和最大重发次数:
- setRTR(2000);//设置溢出时间值
- setRCR(3);//设置最大重新发送的次数
到了这里W5500的相关配置已经配置完成了,可以通过PING来查看配置是否成功,如图一所示。
如果能够到了这里,说明网络的连接已经完成了,总体的任务完成了一半。
四、W5500的UDP设置:
UDP的设置如下,是使用了状态机的形式: - while(1)
- {
- if( (ret = udp_ds18b20(SOCK_UDPS, gDATABUF, 3000)) < 0)
- {
- printf("SOCKET ERROR : %ld\r\n", ret);
- }
- }
- int32_t udp_ds18b20(uint8_t sn, uint8_t* buf, uint16_t port)
- {
- int32_t ret;
- uint16_t size;
- uint8_t destip[4];
- uint16_t destport;
-
- switch(getSn_SR(sn))
- {
- case SOCK_UDP :
- if((size = getSn_RX_RSR(sn)) > 0)
- {
- if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
- ret = recvfrom(sn,buf,size,destip,(uint16_t*)&destport);
- if(ret <= 0)
- {
- printf("%d: recvfrom error. %ld\r\n",sn,ret);
- return ret;
- }
- size = (uint16_t) ret;
- sentsize = 0;
- //sprintf((char*)buf,"DS18B20:%.1f℃\r\n",DS18B20_Get_Temp());
- sprintf((char*)buf,"%.1f\r\n",DS18B20_Get_Temp());
- ret = sendto(sn,buf,strlen((char*)buf),destip,destport);
- if(ret < 0)
- {
- printf("%d: sendto error. %ld\r\n",sn,ret);
- return ret;
- }
- }
- break;
- case SOCK_CLOSED:
- printf("W5500 UDP%d:Start\r\n",sn);
- if((ret=socket(sn,Sn_MR_UDP,port,0x00)) != sn)
- return ret;
- printf("W5500 UDP%d:Opened, port [%d]\r\n",sn, port);
- break;
- default :
- break;
- }
- return 1;
- }
在这个里面,在最开始的时候是出于SOCK_CLOSED状态,进行了SOCKET模式的设置,和W5500的SOCKET端口号设置,通过串口会打印出相关的信息,包括了配置成功和失败的原因。 通过串口调试助手上电后可以看到如下信息,如图二所示。
通过图二可以看出对W5500所设置的MAC地址、本机IP地址SIP、网关GAR、子网掩码SUB和DNS;然后通过读取设置,并与原设置进行比较来判断出来网络是否配置成功。
接着就是开始了W5500的UDP,并显示使用的是端口1,如果UDP开启成功后会打印出相关信息和端口号,由图二可以得出端口号为3000。
五、实验现象和结论: 最后就是当通过电脑的UDP向端口发送了任何信息,就向相对应的IP端口返回当前的温度值,这是为了使任何电脑都能够与此相连,并获得温度值所设计的,具体的现象如图三所示。
通过图三可以看出循环发送数据后可以返回相对应的温度值,在此可以查看温度传感器DS18B20的灵敏度,通过将数据复制到MATLAB中进行绘图,得到了如下结果,如图四。 通过图四可以看出第一次用手稍微碰到DS18B20后温度迅速上升,当手指离开后温度缓慢下降,接着再次用手指一直捏着传感器,温度开始迅速的上升,一直到了顶峰22度后停止,中间手指稍微松了一下后温度稍有下降,手指离开后温度显示迅速下降一段时间后缓慢下降,这是与周围的环境温度有关的;在最后温度下降太慢了,向传感器吹气使其温度下降也是能够查看出这个细节。总之,通过本设计,可以实现温度的远程监测,并对外界微小的温度变化进行捕捉,并且具有成本控制较好,软件编程简单等特点。
六、附录——DS18B20程序:
在本次设计中,使用了ALIENTEK正点原子所出的探索者STM32F407开发板中的DS18B20程序源码,再次提出感谢。在使用过程中,处于接口的设计,更改了所使用的端口和端口的配置,以及获取温度的部分源码。
①:其中端口由原来的PG9更改为了PB9,端口的更改如下: 将ds18b20.h中的IO端口操作由原来的: - //IO方向设置
- #define DS18B20_IO_IN() {GPIOG->MODER&=~(3<<(9*2));GPIOG->MODER|=0<<9*2;} //PG9输入模式
- #define DS18B20_IO_OUT() {GPIOG->MODER&=~(3<<(9*2));GPIOG->MODER|=1<<9*2;} //PG9输出模式
-
- ////IO操作函数
- #define DS18B20_DQ_OUT PGout(9) //数据端口 PG9
- #define DS18B20_DQ_IN PGin(9) //数据端口 PG9
改为了:
|