W7500P以太网模块串口与udp透传

本例主要使用W7500P以太网模块实现串口udp透传。W7500P开发板来自某宝,可自行搜索。

官网链接:w7500p

开发软件:keil5,官网下载外设demo和以太网有关demo。
W7500P以太网模块串口与udp透传_第1张图片
W7500P以太网模块串口与udp透传_第2张图片

调试方式:使用j-link进行调试swd模式。
isp烧录:使用串口2进行烧录,烧录前将boot拉高,按一下reset。进入boot成功后,会提示打开串口成功。

功能:
1. 串口透传
2. 串口和socket配置本地IP地址和远程地址
3. 将ip参数等存储在flash中

主函数中,循环调用:

SystemInit();                                                       
delay_init();                                                           
UART_Configuration();                                               
S_UART_Init(115200);                                                
phy_init(); 
read_w7500_ip(); //从flash中读取本地和远程参数
set_w7500_ip((__network_info_common*)(&g_network_info_common)); //设置本地ip参数等

while(1)
{   
 udps(0,test_buf,g_network_info_common.local_port);    //客户端0接收平台的数据,透传至串口0
 udps(1,test_buf_485,g_network_info_common.local_port+1);  //客户端1接收平台的数据,透传至串口1
 uart_rcv_parse();      //串口0的数据通过本地端口0上传至远程平台,串口1的数据通过本地端口1上传至远程平台 
}  

模块重要的本地ip参数主要有:同一个工作现场,模块需要配置不同的mac地址

uint8_t mac[6] = {0x74, 0xe6, 0xe2, 0x2b, 0xb1, 0xb2}; //mac地址
uint8_t lip[4] = {192, 168,0,114};                  //本地ip  
uint8_t gw[4]  = {192, 168,0,1};                    //网关            
uint8_t sub[4] = {255, 255, 255,  0};               //子网掩码          
uint8_t dns_server[4] = {114,114,114,114};          //dns

uint16_t fac_local_port = 5000; 

串口和flash部分,和其他的mcu差不多,此处不再赘述。
UDP部分:

int32_t udps(uint8_t sn, uint8_t* buf, uint16_t port)
{
    int32_t  ret;
    uint16_t size, sentsize;
    uint8_t  destip[4];
    uint16_t destport;

    switch(getSn_SR(sn))    //获取socket的状态                                                                                           
    {
        case SOCK_UDP :                                                                                                 
            if((size = getSn_RX_RSR(sn)) > 0)
            {
                if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
                ret = recvfrom(sn, buf, size, resip, (uint16_t*)&resport);/*W7500P接收数据,可能来自服务端,或者本地的pc客户端*/
                if(ret <= 0)
                {                       
                    printf("%d: recvfrom error. %ld\r\n",sn,ret);                       
                }

                size = (uint16_t) ret;
                sentsize = 0;
                while(sentsize != size)
                {
                    u8 source_port = 0;                 
                    if(sn == 0)//根据sn号码,区分服务端发送的数据是下发给哪个客户端的,一个sn号对应一个本地端口
                    {
                         source_port = SOURCE_PORT_SCK;
                    }
                    else if(sn == 1)
                    {
                        source_port = SOURCE_PORT_SCK1;
                    }   
                    sck_rcv_parse(sn,source_port,buf,size);  //协议处理后透传至串口
                    sentsize += ret; 
                }
            }
        break;
        case SOCK_CLOSED:           //socket处于关闭状态,首次上电时调用,创建socket                                                                                             
                if((ret = socket(sn, Sn_MR_UDP, port, 0x00)) != sn)                     //此处上电后首次将sn号码和本地端口绑定
                return ret;
                #ifdef _LOOPBACK_DEBUG_
                printf("%d:Opened, UDP loopback, port [%d]\r\n", sn, port);
                #endif
        break;
        default :
        break;
    }
    return 1;
    }

上述部分为socket接收到的数据处理过程,发送如下:

u8 ret = sendto(sn, buffer, buffer_size, remoteip, remoteport);/*sn为唯一识别号,发送数据至服务端*/
if(ret < 0)
{
    #ifdef _LOOPBACK_DEBUG_
    printf("%d: sendto error. %ld\r\n",sn,ret);
    #endif
    return ret;
}

此处,本地端口号和sn号很重要!!

测试时,可将远程端口绑定至字节电脑,用工具建立一个udp服务端。用串口0发送数据时,发现服务端收数据时的端口号为5000,串口2的为5001.

同时,可在本地电脑创建udp客户端,端口设置为5000/5001(需与程序中的本地端口一致),测试以太网模块是否正常运行。

嵌入式开发,初次接触硬件以太网,学到很多,加油。

你可能感兴趣的:(以太网模块,arm)