📄 89c52ctr.c
字号:
#include "GloblDef.h"
//#include "RTL8019.h"
#include "AT89X52.h"
#include "math.h"
extern byte MemAllocation(word size);
extern void FreePage(byte page);
extern byte xdata *MemPageToPoint(byte page);
extern byte WriteQueue(byte page,stuct queue xdata *pQueue);
byte xdata LocalMACAddr[6]={0x52,0x68,0x3a,0x1c,0x2b,0x56};
struct Queue xdata QueueNetPacketIn;
byte StartPageOfPacket;
/*接收头文件信息*/
struct RTLReceiveHeader
{
byte ReceiveStatus;
byte NextPacketStartPage;
byte PacketSizeLow;
byte PacketSizeHigh;
}Head;
byte xdata Head[4];
byte LastSendStartPage;
sbit RTLResetPin = RTL_RESET_PIN;
//读rtl寄存器端口
byte ReadReg(word port)
{
byte xdata *p;
p=(byte xdata *)port; //强制类型转换,为什么不是p=byte xdata port;
return *p;
}
void WriteReg(word port,byte value)
{
byte xdata *p;
p=(byte xdata *)port;
*p=value;
}
//chose page
void RTLPage(byte Index)
{
//set cr,cr_txp 7--6bit0 (1,resend)
byte temp;
temp=ReadReg(CR);
temp=temp&0x3b; //set 7-6 and 2 bit(TXP) to 0
Index=Index<<6; //把页码左移到ps1,ps0 实现选择 ^^;
temp =temp | Index;
WriteReg(CR,temp);
}
//PRA为物理地址//
void RTLInitial()
{
byte temp;
int i;
/*硬件重启*/
RTLResetPin=1;
for(i=0;i<255;i++); //延迟时间让高电平持续1us以上
RTLResetPin=0; //再给个低电平,从而复位RTL
/*若硬件重启延迟很大,rtl自我初始化*/
for(i=0;i<DELAY_AFTER_HARDWARE_RESET;i++); //复位过程需要一些时间推荐100ms
/*写重启口*/
temp=ReadReg(RESET_PORT);
WriteReg(RESET_PORT,temp);//软件复位通过写ResetPort达到复位,也就是给18~1F之间的任意一个寄存器写入任意一个数,就使得以太网口复位
/*初始化rtl寄存器*/
WriteReg(CR,(CR_PAGE0 | CR_ABORT_COMPLETE_DMA | CR_STOP_COMMAND));
//选择page0,stop command
WriteReg(PSTART_WPAGE0,RECEIVE_START_PAGE);
WriteReg(PSTOP_WPAGE0, RECEIVE_STOP_PAGE);
WriteReg(BNRY_WPAGE0, RECEIVE_START_PAGE);
WriteReg(TPSR_WPAGE0, SEND_START_PAGE0);//Pstart,Pstop,bnry,tpsr
WriteReg(RCR_WPAGE0, 0XCE);
WriteReg(TCR_WPAGE0, 0XE0);
WriteReg(DCR_WPAGE0, 0XC8); //RCR,TCR,DCR在头文件里定义
WriteReg(IMR_WPAGE0,0); //RTL接收中断使能
WriteReg(ISR_WPAGE0, 0XFF); //写ff清除所有中断标志
RTLPage(1);
WriteReg(CURR_WPAGE,RECEIVE_START_PAGE+1);
//MAR0
WriteReg(0x08,0x00);
WriteReg(0x09,0x41);
WriteReg(0x0a,0x00);
WriteReg(0x0b,0x80);
WriteReg(0x0c,0x00);
WriteReg(0x0d,0x00);
WriteReg(0x0e,0x00);
WriteReg(0x0f,0x00);
//设置物理地址
WriteReg(PRA0_WPAGE1,LocalMACAddr[0]);
WriteReg(PRA1_WPAGE1,LocalMACAddr[1]);
WriteReg(PRA2_WPAGE1,LocalMACAddr[2]);
WriteReg(PRA3_WPAGE1,LocalMACAddr[3]);
WriteReg(PRA4_WPAGE1,LocalMACAddr[4]);
WriteReg(PRA5_WPAGE1,LocalMACAddr[5]);
//传输起始页
LastSendStartPage=SEND_START_PAGE0;
StartPageOfPacket=RECEIVE_START_PAGE+1;
//初始化结束
WriteReg(CR,(CR_PAGE0|CR_ABORT_COMPLETE_DMA|CR_STOP_COMMAND));
}
//写buffer到rtl ram
void RTLWriteRam(word address,word size,byte xdata *buff)
{
word i;
byte PrePage; //store page
Prepage=ReadReg(CR);
RTLPage(0);
WriteReg(RSARH_WPAGE0,(byte)((address>>8)&0x00ff));
WriteReg(RSARL_WPAGE0,(byte)address);
WriteReg(RBCRH_WPAGE0,(byte)((size>>8)&0x00ff));
WriteReg(RBCRL_WPAGE0,(byte)size);
WriteReg(CR,(0x00|CR_REMOTE_WRITE|CR_START_COMMAND));
for(i=0;i<size;i++)
{
WriteReg(REMOTE_DMA_PORT,buff[i]);
}
//完成DMA
WriteReg(RBCRH_WPAGE0,0);
WriteReg(RBCRL_WPAGE0,0);
WriteReg(CR,((PrePage&0xc0)|CR_ABORT_COMPLETE|CR_STARAT_COMMAND));
}
//读rtl ram 数据到 buffer
void RTLReadRam(word address,word size,byte xdata *buff)
{
word i;
byte PrePage;
PrePage=ReadReg(CR);
RTLPage(0);
WriteReg(RSARH_WPAGE0,(byte)((address>>8)&0x00ff));
WriteReg(RSARL_WPAGE0,(byte)address);
WriteReg(RBCRH_WPAGE0,(byte)((size>>8)&0x00ff));
WriteReg(RBCRL_WPAGE0,(byte)size);
WriteReg(CR,(0x00|CR_REMOTE_READ|CR_START_COMMAND));
for (i=0;i<size;i++)
{
buff[i]=ReadReg(REMOTE_DMA_PORT);
}
//完成dma
WriteReg(RBCRH_WPAGE0,0);
WriteReg(RBCRL_WPAGE0,0);
WriteReg(CR,((PrePage&0xc0)|CR_ABORT_COMPLETE|CR_STARAT_COMMAND));
}
byte RTLSendPacket(byte xdata *buffer,word size)
{
byte StartPage;
byte PrePage;
PrePage=ReadReg(CR);
//检测包大小
if(size<MIN_PACKET_SIZE||size>MAX_PACKET_SIZE)
return FALSE;
//写包到ram
if(LastSendStartPage==SEND_START_PAGE0)
{
StartPage=SEND_START_PAGE1;
LastSendStartPage==SEND_START_PAGE1;
}
else
{
StartPage==SEND_START_PAGE0;
LastSendStartPage==SEND_START_PAGE0;
}
RTLWriteRam(((word)StartPage)<<8,size,buffer);
//等待上一次传输结束
while ((ReadReg(CR)&CR_TXP)==CR_TXP);
//写传输起始页和大小
RTLPage(0);
WriteReg(TPSR_WPAGE0,StartPage); //TPSR
WriteReg(TBCRL_WPAGE0,(byte)size); //LOW
WriteReg(TBCRH_WPAGE0,(byte)((size>>8)&0XFF)); //HIGH
WriteReg(CR,((PrePage&0xc0)|CR_ABORT_COMPLETE|CR_TXP|CR_START_COMMAND);
return TRUE;
}
void RTLReceivePacket()
{
byte curr,bnry;
word adrress;
word PacketSize;
byte MemPage;
struct MemHeader xdata *pMemHead;
RTLPage(1);
curr=ReadReg(CURR_RPAGE1);
RTLPage(0);
//在接收缓存中读所有包
while(TRUE)
{ //检测起始页是否未知吃错误
if(StartPageOfPacket>=RECEIVE_STOP_PAGE||StartPageOfPacket<RECEIVE_START_PAGE)
{ //用curr作为startpageofpacket
StartPageOfPacket=curr;
break;
}
//检测是否有包读到
if(StartPageOfPacket==curr)
break;
//读一个包
//读包头信息
address=((wodr)StartPageOfPacket)<<8;
RTLReadRam(address,4,Head);
//校验rsr
if(Head[0]&RSR_RECEIVE_NO_ERRO)
{
//好包
//得到mac校验和
PacketSize=((word)Head[3])*256+Head[2]-4;
//分配buffer,读包到buffer
MemPage=MemAllocation(PacketSize);
if(MemPage!=PAGE_NOT_FOUND)
{
pMemHead=(struct MemHeader xdata*)MemPageToPoint(MemPage);
pMemHead->StartPos=(byte xdata *)pMemHead+sizeof(struct MemHeader);
pMemHead->StopPos=pMemhead->StopPos+PacketSize;
//停止pos
address+=4;
if(StartPageOfPacket>Head[1]&&Head[1]!=RECEIVE_START_PAGE)
{
RTLReadRam(address,(((word)RECEIVE_STOP_PAGE)<<8)-address,pMemHead->StartPos);
//read rtl
RTLReadRam(((word)RECEIVVE_START_PAGE)<<8,PacketSize-((((word)RECEIVE_STOP_PAGE)
<<8)-address),pMemHead->StartPos+((((word)RECEIVE_STOP_PAGE)<<8)-address));
}
else
{
RTLReadRam(address,PacketSize,pMemHead->StartPos);//read rtl
}
if(WriteQueue(MemPage,&QueueNetPacketIn)==PAGE_NOT_FOUND)//写到队列
{ //队列满
#ifdef DEBUG
printf("\n----queue full----");
#endif
FreePage(MemPage);
break;
}
}
else
{ //mem over
#ifdef DEBUG
printf("\n----queue over----");
#endif
break;
}
}
//得到下一包的起始页
StartPageOfPacket=Head[1];
}
//重置bnry
bnry=StartPageOfPacket-1;
if(bnry<RECEIVE_START_PAGE)
bnry=RECEIVE_STOP_PAGE-1;
WriteReg(BNRY_WPAGE0,bnry);
}
void Start8019()
{
WriteReg(CR,CR_ABORT_COMPLETE_DMA|CR_START_COMMAND);
}
void Stop8019()
{
WriteReg(CR,CR_ABORT_COMPLETE_DMA|CR_STOP_COMMAND);
}
void main(void)
{
byte temp;
word port=1001;
LocalMACAddr[0]=0x52;
LocalMACAddr[1]=0x68;
LocalMACAddr[2]=0x3a;
LocalMACAddr[3]=0x1c;
LocalMACAddr[4]=0x2b;
LocalMACAddr[5]=0x56;
LocalIPAddress=0x0a8020d; //本地ip192.168.2.14
ServerIPAddress=0x0a8020e;//目的ip192.168.2.13
//初始化
SerialInitial();
MemInitial();
NetInInitial();
RTLInitial();
Start8019();
InterruptInitial();
//建立一个arp包
p[0]=0xff;
p[1]=0xff;
p[2]=0xff;
p[3]=0xff;
p[4]=0xff;
p[5]=0xff;
p[6]=0x52;
p[7]=0x54;
p[8]=0x4c;
p[9]=0x30;
p[10]=0x2e;
p[11]=0x2f;
p[12]=0x08;
p[13]=0x06;
p[14]=0x00;
p[15]=0x01;
p[16]=0x08;
p[17]=0x00;
p[18]=0x06;
p[19]=0x04;
p[20]=0x00;
p[21]=0x01;
//发送arp包
RTLSendPacket(p,60);
while(1);
#ifdef DEBUG
printf("\n----bigine-----");
#endif
//处理
TCPBind(port);
if(TCPConnect(ServerIPAddress,1001)==TRUE)
{
while(UserFunc());
}
//延迟
for(temp;temp<255;temp++);
#ifdef DEBUG
printf("\n run over!");
#endif
//存储
Stop8019();
while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -