📄 main.c
字号:
unsigned char PHY_Init()
{
unsigned char temp_char;
unsigned char retval = 0;
//--------------------------------------------------------------------------
//以下部分为物理层自适应同步,详见CP2200数据手册
//--------------------------------------------------------------------------
PHYCN = 0x00; // 禁止物理层寄存器
TXPWR = 0x80;
PHYCF = ( SMSQ | JABBER | ADPAUSE | AUTOPOL );
// 使能物理层
PHYCN = PHYEN;
// 物理层上电
PHYCN = ( PHYEN | TXEN | RXEN ); // 使能传输与接收寄存器
// 唤醒中断
temp_char = INT1;
//--------------------------------------------------------------------------
//以下是物理层初始化
//--------------------------------------------------------------------------
PHYCN = 0x00; //禁止物理层寄存器
PHYCF = ( SMSQ | LINKINTG | JABBER | AUTONEG | ADPAUSE | AUTOPOL ); //进行连接完整性与自适应配置
PHYCN = PHYEN;//使能物理层
PHYCN = ( PHYEN | TXEN | RXEN ); // 使能传输与接收寄存器
temp_char = INT1;
while(1){
if(INT1RD & (ANCINT | ANFINT))break; // 判断初始化是成功
}
temp_char = INT1RD;
temp_char &= (ANCINT | ANFINT);
if(temp_char & ANFINT) // 检测自适应是否失败
{
retval = LINK_ERROR;
}
else
if(temp_char == ANCINT) // 检测自适应是否通过
{
retval = 0;
IOPWR = 0x0C; // 使能 Link LED and Activity LED
}
else
{
retval = LINK_ERROR;
}
return retval;
}
/***********************************************************************/
//数据链路层初始化
/***********************************************************************/
void MAC_Init(void)
{
//判断是否为全双工通讯,并进行相关设置 详见CP2200数据手册
if(PHYCN & 0x10)
{
MAC_Write(MACCF, 0x40B3);
MAC_Write(IPGT, 0x0015);
}
else
{
MAC_Write(MACCF, 0x4012);
MAC_Write(IPGT, 0x0012);
}
MAC_Write(IPGR, 0x0C12);
MAC_Write(MAXLEN, 0x05EE);
// 读出厂前设置的MAC地址
FLASHADDRH = 0x1F;
FLASHADDRL = 0xFA;
MYMAC.Char[0] = FLASHAUTORD;
MYMAC.Char[1] = FLASHAUTORD;
MYMAC.Char[2] = FLASHAUTORD;
MYMAC.Char[3] = FLASHAUTORD;
MYMAC.Char[4] = FLASHAUTORD;
MYMAC.Char[5] = FLASHAUTORD;
my_hwaddr[0]=MYMAC.Char[0];
my_hwaddr[1]=MYMAC.Char[1];
my_hwaddr[2]=MYMAC.Char[2];
my_hwaddr[3]=MYMAC.Char[3];
my_hwaddr[4]=MYMAC.Char[4];
my_hwaddr[5]=MYMAC.Char[5];
MAC_SetAddress(&MYMAC);
MAC_Write(MACCN, 0x0001); // 允许回环模式
}
/************************************************************************/
//访问MAC间接寄存器
/************************************************************************/
void MAC_Write(unsigned char mac_reg_offset, unsigned int mac_reg_data)
{
MACADDR = mac_reg_offset;
MACDATAH = (mac_reg_data >> 8); // Copy High Byte
MACDATAL = (mac_reg_data & 0xFF); // Copy Low Byte
MACRW = 0;
return;
}
/**************************************************************************/
//设置MAC地址
/**************************************************************************/
void MAC_SetAddress(MACADDRESS* pMAC)
{
UINT1 temp_int;
temp_int.Char[0] = pMAC->Char[5];
temp_int.Char[1] = pMAC->Char[4];
MAC_Write(MACAD0, temp_int.Int);
temp_int.Char[0] = pMAC->Char[3];
temp_int.Char[1] = pMAC->Char[2];
MAC_Write(MACAD1, temp_int.Int);
temp_int.Char[0] = pMAC->Char[1];
temp_int.Char[1] = pMAC->Char[0];
MAC_Write(MACAD2, temp_int.Int);
return;
}
/**************************************************************************/
// 以太网帧接收函数
/**************************************************************************/
void eth_rcve(UCHAR xdata * inbuf)
{
ETH_HEADER xdata * eth;
eth = (ETH_HEADER xdata *)inbuf;
if (eth->frame_type < 1520) // 帧长度不能超过IEEE 802标准归定
{
return;
}
switch (eth->frame_type) //根据接收到的数据包类型,选择不同的处理方式
{
case ARP_PACKET:
arp_rcve(inbuf);
break;
case IP_PACKET:
ip_rcve(inbuf);
break;
default:break;
}
}
/*************************************************************************/
//以太网帧传输函数--------传输层
/*************************************************************************/
void eth_send(UCHAR xdata * outbuf, UCHAR * hwaddr, UINT ptype, UINT len)
{
ETH_HEADER xdata * eth;
eth = (ETH_HEADER xdata *)outbuf;
//加入14位的以太网数据帧头标识
memcpy(eth->dest_hwaddr, hwaddr, 6);
memcpy(eth->source_hwaddr, my_hwaddr, 6);
eth->frame_type = ptype;
CP220x_Send(outbuf, len + 14); // 增加数据包长度
}
/*************************************************************************/
// CP2200发送函数
/*************************************************************************/
void CP220x_Send( UCHAR xdata * outbuf, UINT len)
{
int i;
unsigned int ramaddr;
// 定义宏来增加地址指针
#define INC_RAMADDR ramaddr++; \
RAMADDRH = (ramaddr >> 8);\
RAMADDRL = (ramaddr & 0x00FF);
while(TXBUSY); //等待传输结束
TXSTARTH = 0x00;
TXSTARTL = 0x00;
RAMADDRH = 0x00; //地址设为零
RAMADDRL = 0x00;
ramaddr = 0x0000;
for(i = 0; i < len; i++)
{
RAMTXDATA = outbuf[i];
INC_RAMADDR
}
while(ramaddr < 64) //将不足64字节长度的数据填充到64字节
{
RAMTXDATA = 0;
INC_RAMADDR
}
ramaddr--;
TXENDH = (ramaddr >> 8); //将RAM地址减一后赋给TXEND使其地址为)X0040
TXENDL = (ramaddr & 0x00FF);
TXSTARTH = 0x00;
TXSTARTL = 0x00; //将TXSTAR地址归零
TXCN = 0x01; //向TXGO写1开始传输
}
/****************************************************************/
//CP2200芯片接收数据函数
/****************************************************************/
UCHAR xdata * rcve_frame(void)
{
bit rx_ok;
bit skip = 0;
UINT1 cplen;
unsigned int i;
UCHAR xdata * buf;
unsigned char interrupt_read;
unsigned char valid_bits;
unsigned char num_packets;
interrupt_read = INT1;
interrupt_read = INT0; //清中断标志
if( interrupt_read & RXINT) //判断接收中断是否产生
{
valid_bits = TLBVALID; //对接收数据包进行统计
for(num_packets = 0; valid_bits; num_packets++)
{
valid_bits &= valid_bits - 1;
}
if( num_packets >= 7) //接收区超过7个数据包,停止接收
{
RXCN = RXINH;
}
}
//以下步骤参考CP2200数据手册的接收部分
rx_ok = (CPINFOL & RXOK) && (CPINFOH & RXVALID);
if(rx_ok)
{
cplen.Char[0] = CPLENH;
cplen.Char[1] = CPLENL;
buf=inbuf1;
}
else
{
cplen.Int = 0;
skip = 1;
buf = NULL;
}
if(1)
{
for(i = 0; i < cplen.Int; i++)
{
buf[i] = RXAUTORD;
}
rcve_buf_allocated = TRUE;
}
else
{
cplen.Int = 0;
skip = 1;
}
if(skip)
{
RXCN |= 0x02;
}
else
{
RXCN |= 0x04;
}
if(TLBVALID == 0x00)
{
RXCN = 0x00;
}
return(buf);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -