我们使用的以太网协议栈管理芯片是CH395L,芯片是通过SPI串口与DSP连接的。
void CH395_PORT_INIT(void)
{SpiaRegs.SPIBRR=0x0005;SpiaRegs.SPISTS.all=0x0000; // Baud rate 3.75MSpiaRegs.SPIPRI.all=0x0001; // stop immediately //--DA7614工作时SPI的设置: 无延迟的下降沿方式(时钟的初始态为高),16 bit dataSpiaRegs.SPICCR.all=0x0047; // initialize spi,output at falling edge, 16 bit dataSpiaRegs.SPICTL.all=0x0006; // Master,normal phase, enable transmissionSpiaRegs.SPICCR.all=0x00c7;
}
/*==============================================================================
* Function Name : CH395CMDReset
* Description : 复位CH395芯片
* Input : None
* Output : None
* Return : None
==============================================================================*/
void CH395CMDReset(void)
{xWriteCH395Cmd(CMD00_RESET_ALL);xEndCH395Cmd();DELAY_US(60000L);
}/*==============================================================================
/*==============================================================================
* Function Name : xWriteCH395Cmd
* Description : 向CH395写命令
* Input : cmd 8位的命令码
* Output : None
* Return : None
==============================================================================*/
void xWriteCH395Cmd(UINT8 cmd)
{ xEndCH395Cmd(); /* 防止CS原来为低,先将CD置高 */xCH395CmdStart( ); /* 命令开始,CS拉低 */Spi395Exchange(cmd); /* SPI发送命令码 */DELAY_US(2L); /* 必要延时,延时1.5uS确保读写周期不小于1.5uS */
}
/*******************************************************************************
* Function Name : Spi395Exchange
* Description : 硬件SPI输出且输入8个位数据(SPI读写数据函数)
* Input : d---将要送入到CH395的数据
* Output : None
* Return : None
*******************************************************************************/
UINT8 Spi395Exchange( UINT8 d )
{ UINT8 RES1;SpiaRegs.SPITXBUF&#61;d<<8; /* 先将数据写入SPI数据寄存器,然后查询SPI状态寄存器以等待*/ while(SpiaRegs.SPISTS.bit.INT_FLAG&#61;&#61;0){} /* 查询SPI状态寄存器的标志位以等待SPI字节传输完成数据,发送完成标志位置1*/RES1&#61;(UINT8)SpiaRegs.SPIRXBUF;return(RES1); /*从SPI数据寄存器读出数据*/
}/*&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
/*&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
* Function Name : InitCH395InfParam
* Description : 初始化CH395Inf参数
* Input : None
* Output : None
* Return : None
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;*/
void InitCH395InfParam(void)
{memset(&CH395Inf,0,sizeof(CH395Inf)); /* 将CH395Inf全部清零*/memcpy(CH395Inf.IPAddr,CH395IPAddr,sizeof(CH395IPAddr)); /* 将IP地址写入CH395Inf中 */memcpy(CH395Inf.GWIPAddr,CH395GWIPAddr,sizeof(CH395GWIPAddr)); /* 将网关IP地址写入CH395Inf中 */memcpy(CH395Inf.MASKAddr,CH395IPMask,sizeof(CH395IPMask)); /* 将子网掩码写入CH395Inf中 */
}
struct _CH395_SYS//CH395Inf变量的数据结构
{UINT8 IPAddr[4]; /* CH395IP地址 32bit*/UINT8 GWIPAddr[4]; /* CH395网关地址 32bit*/UINT8 MASKAddr[4]; /* CH395子网掩码 32bit*/UINT8 MacAddr[6]; /* CH395MAC地址 48bit*/UINT8 PHYStat; /* CH395 PHY状态码 8bit*/UINT8 MackFilt; /* CH395 MAC过滤&#xff0c;默认为接收广播&#xff0c;接收本机MAC 8bit*/UINT32 RetranCount; /* 重试次数 默认为10次*/UINT32 RetranPeriod; /* 重试周期,单位MS,默认200MS */UINT8 IntfMode; /* 接口模式 */UINT8 UnreachIPAddr[4]; /* 不可到达IP */UINT16 UnreachPort; /* 不可到达端口 */
};
/*&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
* Function Name : CH395Init
* Description : 配置CH395的IP,GWIP,MAC等参数&#xff0c;并初始化
* Input : None
* Output : None
* Return : 函数执行结果
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;*/
UINT8 CH395Init(void)
{UINT8 i;i &#61; CH395CMDCheckExist(0x65); if(i !&#61; 0x9a)return CH395_ERR_UNKNOW; /* 测试命令&#xff0c;如果无法通过返回0XFA *//* 返回0XFA一般为硬件错误或者读写时序不对 */CH395CMDSetIPAddr(CH395Inf.IPAddr); /* 设置CH395的IP地址 */
// CH395CMDSetMACAddr(CH395Inf.MacAddr); /* 设置CH395的MAC地址 */CH395CMDSetGWIPAddr(CH395Inf.GWIPAddr); /* 设置网关地址 */CH395CMDSetMASKAddr(CH395Inf.MASKAddr); /* 设置子网掩码&#xff0c;默认为255.255.255.0*/ i &#61; CH395CMDInitCH395(); /* 初始化CH395芯片 */return i;
}
/*&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
* Function Name : CH395CMDCheckExist
* Description : 测试命令&#xff0c;用于测试硬件以及接口通讯
* Input : testdata 1字节测试数据
* Output : None
* Return : 硬件OK&#xff0c;返回 testdata按位取
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;*/
UINT8 CH395CMDCheckExist(UINT8 testdata)
{UINT8 i;xWriteCH395Cmd(CMD11_CHECK_EXIST);xWriteCH395Data(testdata);i &#61; xReadCH395Data();xEndCH395Cmd();return i;
}
/*&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
* Function Name : CH395CMDInitCH395
* Description : 初始化CH395芯片。
* Input : None
* Output : None
* Return : 返回执行结果
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;*/
UINT8 CH395CMDInitCH395(void)
{UINT8 i &#61; 0;UINT8 s &#61; 0;xWriteCH395Cmd(CMD0W_INIT_CH395);xEndCH395Cmd();while(1){DELAY_US(5000L); /* 延时查询&#xff0c;建议2MS以上*/s &#61; CH395GetCmdStatus(); /* 不能过于频繁查询*/if(s !&#61;CH395_ERR_BUSY)break; /* 如果CH395芯片返回忙状态*/if(i&#43;&#43; > 200)return CH395_ERR_UNKNOW; /* 超时退出,本函数需要500MS以上执行完毕 */}return s;
}
/*&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
* Function Name : InitSocketParam
* Description : 初始化socket
* Input : None
* Output : None
* Return : None
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;*/
void InitSocketParam(void)
{memset(&ScokInf,0,sizeof(ScokInf)); /* 将ScokInf[0]全部清零*/memcpy(ScokInf.IPAddr,Socket0DesIP,sizeof(Socket0DesIP)); /* 将目的IP地址写入 */ScokInf.DesPort &#61; Socket0DesPort; /* 目的端口 */ScokInf.SourPort &#61; Socket0SourPort; /* 源端口 */ScokInf.ProtoType &#61; PROTO_TYPE_UDP; /* TCP模式(TCP改为UDP) */
// ScokInf.TcpMode &#61; TCP_CLIENT_MODE;
}
struct _SCOK_INF
{UINT8 IPAddr[4]; /* socket目标IP地址 32bit*/UINT8 MacAddr[6]; /* socket目标地址 48bit*/UINT8 ProtoType; /* 协议类型 */UINT8 ScokStatus; /* socket状态&#xff0c;参考scoket状态定义 */UINT8 TcpMode; /* TCP模式 */UINT32 IPRAWProtoType; /* IPRAW 协议类型 */UINT16 DesPort; /* 目的端口 */UINT16 SourPort; /* 目的端口 */UINT16 SendLen; /* 发送数据长度 */UINT16 RemLen; /* 剩余长度 */UINT8 *pSend; /* 发送指针 */
};
/*&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
* Function Name : CH395SocketInitOpen
* Description : 配置CH395 socket 参数&#xff0c;初始化并打开socket
* Input : None
* Output : None
* Return : None
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;*/
void CH395SocketInitOpen(void)
{UINT8 i;/* socket 0为TCP 客户端模式 */CH395SetSocketDesIP(0,ScokInf.IPAddr); /* 设置socket 0目标IP地址 */CH395SetSocketProtType(0,ScokInf.ProtoType); /* 设置socket 0协议类型 */CH395SetSocketDesPort(0,ScokInf.DesPort); /* 设置socket 0目的端口 */CH395SetSocketSourPort(0,ScokInf.SourPort); /* 设置socket 0源端口 */i &#61; CH395OpenSocket(0); /* 打开socket 0 */mStopIfError(i); /* 检查是否成功 */
}
实际上&#xff0c;我们设置了一个标志量flag_send&#xff0c;当进入CAN中断服务子程序后&#xff0c;即证明单片机收到了来自传感器的数据信息&#xff0c;我们就将flag_send置1&#xff0c;然后调用CH395发送和接收函数&#xff0c;将数据送到上位机或者从上位机接收指令。即我们实际上是采用的轮询方式实现的以太网通信。
/*&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
* Function Name : CH395GetReceLength
* Description : 读取接收缓冲区数据
* Input : sockindex Socket索引len 长度pbuf 缓冲区
* Output : None
* Return : None
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;*/
void CH395GetReceData(UINT8 sockindex,UINT16 len,UINT8 *pbuf)
{UINT16 i;if(!len)return;xWriteCH395Cmd(CMD30_READ_RECV_BUF_SN);xWriteCH395Data(sockindex);xWriteCH395Data((UINT8)len);xWriteCH395Data((UINT8)(len>>8));for(i &#61; 0; i < len; i&#43;&#43;){*pbuf &#61; xReadCH395Data();pbuf&#43;&#43;;}xEndCH395Cmd();
}
/*&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;
* Function Name : CH395SendData
* Description : 向发送缓冲区写数据
* Input : sockindex Socket索引databuf 数据缓冲区len 长度
* Output : None
* Return : None
&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;&#61;*/
void CH395SendData(UINT8 sockindex,UINT8 *databuf,UINT16 len)
{UINT16 i;xWriteCH395Cmd(CMD30_WRITE_SEND_BUF_SN);xWriteCH395Data((UINT8)sockindex);xWriteCH395Data((UINT8)len);xWriteCH395Data((UINT8)(len>>8));for(i &#61; 0; i < len; i&#43;&#43;){xWriteCH395Data(*databuf&#43;&#43;);}xEndCH395Cmd();
}