1. 以太网模块初始化netinit
1.1 SPI串口初始化
????我们使用的以太网协议栈管理芯片是CH395L,芯片是通过SPI串口与DSP连接的。
void CH395_PORT_INIT(void)
{
SpiaRegs.SPIBRR=0x0005;
SpiaRegs.SPISTS.all=0x0000;
SpiaRegs.SPIPRI.all=0x0001;
SpiaRegs.SPICCR.all=0x0047;
SpiaRegs.SPICTL.all=0x0006;
SpiaRegs.SPICCR.all=0x00c7;
}
1.2 复位CH395芯片
void CH395CMDReset(void)
{
xWriteCH395Cmd(CMD00_RESET_ALL);
xEndCH395Cmd();
DELAY_US(60000L);
}
void xWriteCH395Cmd(UINT8 cmd)
{
xEndCH395Cmd();
xCH395CmdStart( );
Spi395Exchange(cmd);
DELAY_US(2L);
}
UINT8 Spi395Exchange( UINT8 d )
{
UINT8 RES1;
SpiaRegs.SPITXBUF=d<<8;
while(SpiaRegs.SPISTS.bit.INT_FLAG==0){}
RES1=(UINT8)SpiaRegs.SPIRXBUF;
return(RES1);
}
1.3 初始化CH395相关变量
void InitCH395InfParam(void)
{
memset(&CH395Inf,0,sizeof(CH395Inf));
memcpy(CH395Inf.IPAddr,CH395IPAddr,sizeof(CH395IPAddr));
memcpy(CH395Inf.GWIPAddr,CH395GWIPAddr,sizeof(CH395GWIPAddr));
memcpy(CH395Inf.MASKAddr,CH395IPMask,sizeof(CH395IPMask));
}
struct _CH395_SYS
{
UINT8 IPAddr[4];
UINT8 GWIPAddr[4];
UINT8 MASKAddr[4];
UINT8 MacAddr[6];
UINT8 PHYStat;
UINT8 MackFilt;
UINT32 RetranCount;
UINT32 RetranPeriod;
UINT8 IntfMode;
UINT8 UnreachIPAddr[4];
UINT16 UnreachPort;
};
1.4 CH395芯片初始化
UINT8 CH395Init(void)
{
UINT8 i;
i = CH395CMDCheckExist(0x65);
if(i != 0x9a)return CH395_ERR_UNKNOW;
CH395CMDSetIPAddr(CH395Inf.IPAddr);
CH395CMDSetGWIPAddr(CH395Inf.GWIPAddr);
CH395CMDSetMASKAddr(CH395Inf.MASKAddr);
i = CH395CMDInitCH395();
return i;
}
UINT8 CH395CMDCheckExist(UINT8 testdata)
{
UINT8 i;
xWriteCH395Cmd(CMD11_CHECK_EXIST);
xWriteCH395Data(testdata);
i = xReadCH395Data();
xEndCH395Cmd();
return i;
}
UINT8 CH395CMDInitCH395(void)
{
UINT8 i = 0;
UINT8 s = 0;
xWriteCH395Cmd(CMD0W_INIT_CH395);
xEndCH395Cmd();
while(1)
{
DELAY_US(5000L);
s = CH395GetCmdStatus();
if(s !=CH395_ERR_BUSY)break;
if(i++ > 200)return CH395_ERR_UNKNOW;
}
return s;
}
1.5 初始化socket
void InitSocketParam(void)
{
memset(&ScokInf,0,sizeof(ScokInf));
memcpy(ScokInf.IPAddr,Socket0DesIP,sizeof(Socket0DesIP));
ScokInf.DesPort = Socket0DesPort;
ScokInf.SourPort = Socket0SourPort;
ScokInf.ProtoType = PROTO_TYPE_UDP;
}
struct _SCOK_INF
{
UINT8 IPAddr[4];
UINT8 MacAddr[6];
UINT8 ProtoType;
UINT8 ScokStatus;
UINT8 TcpMode;
UINT32 IPRAWProtoType;
UINT16 DesPort;
UINT16 SourPort;
UINT16 SendLen;
UINT16 RemLen;
UINT8 *pSend;
};
1.6 初始化并打开socket
void CH395SocketInitOpen(void)
{
UINT8 i;
CH395SetSocketDesIP(0,ScokInf.IPAddr);
CH395SetSocketProtType(0,ScokInf.ProtoType);
CH395SetSocketDesPort(0,ScokInf.DesPort);
CH395SetSocketSourPort(0,ScokInf.SourPort);
i = CH395OpenSocket(0);
mStopIfError(i);
}
2. 以太网通信的具体实现
????实际上,我们设置了一个标志量flag_send,当进入CAN中断服务子程序后,即证明单片机收到了来自传感器的数据信息,我们就将flag_send置1,然后调用CH395发送和接收函数,将数据送到上位机或者从上位机接收指令。即我们实际上是采用的轮询方式实现的以太网通信。
2.1 接收缓冲区数据
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 = 0; i < len; i++)
{
*pbuf = xReadCH395Data();
pbuf++;
}
xEndCH395Cmd();
}
2.2 写数据到缓存区
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 = 0; i < len; i++)
{
xWriteCH395Data(*databuf++);
}
xEndCH395Cmd();
}
|