網絡時鐘同步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);
}
}
浙公網安備 33010602011771號