网络时钟同步SOCKET代码

深圳市立显电子有限公司,专业LED时钟生产厂家!--------【点击进入】   

/*
* w5100.c
*
* Created: 2013-10-6 8:40:38
* Author: Administrator
*/

#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/eeprom.h>
#include "../include/xufei.h"


/* 网络参数寄存器 */
unsigned char Gateway_IP[4]={192,168,0,1};// Gateway IP Address
unsigned char Sub_Mask[4]={255,255,255,0};//Subnet Mask
unsigned char Phy_Addr[6]={0x00,0x1f,0x81,0x00,0x055,LEDaddr};//Physical Address
unsigned char IP_Addr[4]={192,168,0,55};//Loacal IP Address
/*目标IP*/
unsigned char NTP_DIP[4]={192,168,0,103};//Socket0 Destination IP Address 40,118,103,7 192,168,1,100

//W5100Transmit PC4-RST PC5-SCK PD0-SS PD1-MOSI PD2-MISO
void Write_W5100(unsigned int Addr, unsigned char cData){
PORTC&=~(1<<PC2);//置W5100的CS为低电平
delay_ms(1);
SPI_SendByte(0xf0);//发送写命令
SPI_SendByte(Addr>>8);
SPI_SendByte(Addr);
SPI_SendByte(cData);
delay_ms(1);
PORTC|=(1<<PC2);//置W5100的CS为高电平
}

unsigned char Read_W5100(unsigned int Addr){
unsigned char cData=0;
PORTC&=~(1<<PC2);//置W5100的CS为低电平
delay_ms(1);
SPI_SendByte(0x0f);//
SPI_SendByte(Addr>>8);
SPI_SendByte(Addr);
cData=SPI_ReadByte();
delay_ms(1);
PORTC|=(1<<PC2);//置W5100的CS为高电平
return cData;
}

unsigned int getSn_RX_RSR(unsigned char s){
unsigned int val=0,val1=0;
do{
val1=Read_W5100(Sn_RX_RSR0(s));
val1=(val1<<8)+Read_W5100(Sn_RX_RSR0(s)+1);
if(val1!= 0){
val = Read_W5100(Sn_RX_RSR0(s));
val =(val<<8)+Read_W5100(Sn_RX_RSR0(s)+1);
}
} while (val != val1);
return val;
}

unsigned int getSn_TX_FSR(unsigned char s){
unsigned int val=0,val1=0;
do{
val1=Read_W5100(Sn_TX_FSR0(s));
val1=(val1<<8)+Read_W5100(Sn_TX_FSR0(s)+1);
if(val1!= 0){
val = Read_W5100(Sn_TX_FSR0(s));
val =(val<<8)+Read_W5100(Sn_TX_FSR0(s)+1);
}
} while (val != val1);
return val;
}

unsigned char getSn_SR(unsigned char s){
return Read_W5100(Sn_SR(s));
}
//W5100Transmit PC0-RST PC1-SCK PC2-SS PC3-MOSI PC4-MISO
void W5100_Init(void){
unsigned int i=0;
DDRC&=~(1<<PC4);//MISO
DDRC|=(1<<PC3)|(1<<PC2)|(1<<PC1)|(1<<PC0);//MOSI SS SCK RST
PORTC&=~(1<<PC0);//复位信号
delay_ms(500);
PORTC|=(1<<PC0);//复位信号
delay_ms(10);
Write_W5100(MR,MR_RST);//软件复位
while(Read_W5100(MR)&MR_RST){
wdt_reset();
}
for (i=0;i<4;i++){
Write_W5100(GAR0+i,Gateway_IP[i]);//网关
}
for (i=0;i<4;i++){
Write_W5100(SUBR0+i,Sub_Mask[i]);//子网掩码
}
for (i=0;i<6;i++){
Write_W5100(SHAR0+i,Phy_Addr[i]);//物理地址
}
for (i=0;i<4;i++){
Write_W5100(SIPR0+i,IP_Addr[i]);//本机IP
}
Write_W5100(RMSR,0x55);//接收缓冲2K
Write_W5100(TMSR,0x55);//发送缓冲2K
Write_W5100(RTR0,0x17);
Write_W5100(RTR0+1,0x10);//重试时间默认200MS
Write_W5100(RCR,0x04);//重试次数默认8次
}


void Socket_UDP(unsigned char s,unsigned int port){
Write_W5100(Sn_CR(s),Sn_CR_CLOSE);//关闭Socket
while(Read_W5100(Sn_CR(s)));
Write_W5100(Sn_IR(s),0xff);//回写清除中断标志
Write_W5100(Sn_PORT0(s),(port&0xff00)>>8);
Write_W5100(Sn_PORT0(s)+1,port&0x00ff);
start:
Write_W5100(Sn_MR(s),Sn_MR_UDP);//UDP模式
Write_W5100(Sn_CR(s),Sn_CR_OPEN);//打开Socket
if(Read_W5100(Sn_SR(s))!=SOCK_UDP){
Write_W5100(Sn_CR(s),Sn_CR_CLOSE); /*打开不成功,关闭Socket,然后返回*/
goto start;
}
}

void read_data(unsigned char s,unsigned int src,unsigned char *dst,unsigned int len){
unsigned int msrc=0,asrc=0,i=0;
msrc=src&0x07ff;//相对物理地址
asrc=0x6000+2048*s+msrc;//实际物理地址
if((msrc+len)>2048){
for(i=0;i<(2048-msrc);i++){
*(dst+i)=Read_W5100(asrc+i);
}
for (i=0;i<(len-2048+msrc);i++){
*(dst+i+2048-msrc)=Read_W5100(0x6000+s*2048+i);
}
}else{
for (i=0;i<len;i++){
*(dst+i)=Read_W5100(asrc+i);
}
}
}

void write_data(unsigned char s,unsigned char *src,unsigned int dst,unsigned int len){
unsigned int mdst=0,adst=0,i=0;
mdst=dst&0x07ff;
adst=0x4000+s*2048+mdst;
if ((mdst+len)>2048){
for (i=0;i<(2048-mdst);i++){
Write_W5100(adst+i,*(src+i));
}
for (i=0;i<(len-2048+mdst);i++){
Write_W5100(0x4000+s*2048+i,*(src+2048-mdst+i));
}
}else{
for (i=0;i<len;i++){
Write_W5100(adst+i,*(src+i));
}
}
}

void Recv_data_processing(unsigned char s,unsigned char *buf,unsigned int len){
unsigned int src=0;
src=(Read_W5100(Sn_RX_RD0(s))<<8)+Read_W5100(Sn_RX_RD0(s)+1);
read_data(s,src,buf,len);
src+=len;
Write_W5100(Sn_RX_RD0(s),(src&0xff00)>>8);
Write_W5100((Sn_RX_RD0(s)+1),(src&0x00ff));//更新接收指针
}

void Send_data_processing(unsigned char s,unsigned char *buf,unsigned int len){
unsigned int dst=0;
//开始数据发送
dst=(Read_W5100(Sn_TX_WR0(s))<<8)+Read_W5100(Sn_TX_WR0(s)+1);
write_data(s,buf,dst,len);
dst+=len;
Write_W5100(Sn_TX_WR0(s),(dst&0xff00)>>8);
Write_W5100((Sn_TX_WR0(s)+1),dst&0x00ff);
}

unsigned int UDP_Recv(unsigned char s,unsigned char *buf,unsigned int len,unsigned char *addr,unsigned int *port){
unsigned char head[8]={0};
unsigned int data_len=0,ptr=0;
ptr=(Read_W5100(Sn_RX_RD0(s))<<8)+Read_W5100(Sn_RX_RD0(s)+1);
read_data(s,ptr,head,0x08);
//读UDP数据段
ptr+=8;
*(addr+0)= head[0];
*(addr+1) = head[1];
*(addr+2) = head[2];
*(addr+3) = head[3];
*port =head[4];
*port =(*port<<8)+head[5];
data_len=(head[6]<<8)+head[7];
read_data(s,ptr,buf,data_len);
ptr+=data_len;
Write_W5100(Sn_RX_RD0(s),(ptr&0xff00)>>8);
Write_W5100((Sn_RX_RD0(s)+1),(ptr&0x00ff));//更新接收指针
Write_W5100(Sn_CR(s),Sn_CR_RECV);//准备接收
while(Read_W5100(Sn_CR(s)));
return data_len;
}
//len<2048
unsigned int UDP_Send(unsigned char s,unsigned char *buf,unsigned int len,unsigned char *addr,unsigned int port){
unsigned int i=0;
Write_W5100(Sn_DPORT0(s),(port&0xff00)>>8);
Write_W5100(Sn_DPORT0(s)+1,port&0x00ff);
for (i=0;i<4;i++){
Write_W5100(Sn_DIPR0(s)+i,*(addr+i));
}
//开始数据发送
Send_data_processing(s,buf,len);
Write_W5100(Sn_CR(s),Sn_CR_SEND);//准备发送
while(Read_W5100(Sn_CR(s)));
while((Read_W5100(Sn_IR(s))&Sn_IR_SEND_OK)!=Sn_IR_SEND_OK ){
if(Read_W5100(Sn_IR(s))&Sn_IR_TIMEOUT){
Write_W5100(Sn_IR(s),(Sn_IR_SEND_OK | Sn_IR_TIMEOUT)); /* clear SEND_OK & TIMEOUT */
return 0;
}
}
Write_W5100(Sn_IR(s),Sn_IR_SEND_OK);
return len;
}

void NTP_sending(unsigned char s){
unsigned int i=0;
Rx_Tx_Buffer[0]=0xdb;
Rx_Tx_Buffer[1]=0x00;
Rx_Tx_Buffer[2]=0x0a;
Rx_Tx_Buffer[3]=0xfa;
for(i=0;i<44;i++){
Rx_Tx_Buffer[4+i]=0;
}
UDP_Send(s,Rx_Tx_Buffer,48,NTP_DIP,123);
}

void NTP_processing(unsigned char s){
unsigned char SI=0,svr_addr[4];
unsigned int svr_port=0;
//接收对时信息
SI=Read_W5100(Sn_IR(s));
if (SI&Sn_IR_RECV){
Write_W5100(Sn_IR(s),Sn_IR_RECV);//回写清除中断标志
//接收数据
UDP_Recv(s,Rx_Tx_Buffer,48,svr_addr,&svr_port);
if(svr_port==123){
Time_update();
WEEK_Update();
}
//结束清除中断
Write_W5100(Sn_CR(s),Sn_CR_CLOSE);
while(Read_W5100(Sn_CR(s)));
Write_W5100(Sn_IR(s),0xff);
}
}

void Data_processing(unsigned char s){
unsigned char SI=0,svr_addr[4];
unsigned int svr_port=0;
SI=Read_W5100(Sn_IR(s));
if (SI&Sn_IR_RECV){
Write_W5100(Sn_IR(s),Sn_IR_RECV);//回写清除中断标志
//接收数据
UDP_Recv(s,Rx_Tx_Buffer,48,svr_addr,&svr_port);
//设置NTP服务器IP,回复cc 03---------------------------------------------------------
if (Rx_Tx_Buffer[0]==0x03&&Rx_Tx_Buffer[1]==0xcc){
Rx_Tx_Buffer[0]=0xcc;
Rx_Tx_Buffer[1]=0x03;
for(int i=0;i<16;i++){
net_para[1+i]=Rx_Tx_Buffer[2+i];
}
Rx_Tx_Buffer[2]=LEDaddr;
UDP_Send(s,Rx_Tx_Buffer,48,svr_addr,svr_port);
EEPROM_Save();
}
//置零,防止误操作
for(int i=0;i<48;i++){
Rx_Tx_Buffer[i]=0;
}
//结束清除中断
Write_W5100(Sn_CR(s),Sn_CR_CLOSE);
while(Read_W5100(Sn_CR(s)));
Write_W5100(Sn_IR(s),0xff);
}
}


posted on 2020-04-14 17:02  parserval  阅读(478)  评论(1编辑  收藏  举报