欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
STM32溫濕度傳感器檢測,W5500以太網發送程序
[打印本頁]
作者:
QEQWE123
時間:
2021-7-25 14:49
標題:
STM32溫濕度傳感器檢測,W5500以太網發送程序
/**********************************************************************************
* 文件名 :W5500.c
* 描述 :W5500 驅動函數庫
* 庫版本 :ST_v3.5
**********************************************************************************/
#include "stm32f10x.h"
#include "stm32f10x_spi.h"
#include "W5500.h"
#include "delay.h"
/***************----- 網絡參數變量定義 -----***************/
unsigned char Gateway_IP[4];//網關IP地址
unsigned char Sub_Mask[4]; //子網掩碼
unsigned char Phy_Addr[6]; //物理地址(MAC)
unsigned char IP_Addr[4]; //本機IP地址
unsigned char S0_Port[2]; //端口0的端口號(5000)
unsigned char S0_DIP[4]; //端口0目的IP地址
unsigned char S0_DPort[2]; //端口0目的端口號(6000)
unsigned char UDP_DIPR[4]; //UDP(廣播)模式,目的主機IP地址
unsigned char UDP_DPORT[2]; //UDP(廣播)模式,目的主機端口號
/***************----- 端口的運行模式 -----***************/
unsigned char S0_Mode =3; //端口0的運行模式,0:TCP服務器模式,1:TCP客戶端模式,2:UDP(廣播)模式
#define TCP_SERVER 0x00 //TCP服務器模式
#define TCP_CLIENT 0x01 //TCP客戶端模式
#define UDP_MODE 0x02 //UDP(廣播)模式
/***************----- 端口的運行狀態 -----***************/
unsigned char S0_State =0; //端口0狀態記錄,1:端口完成初始化,2端口完成連接(可以正常傳輸數據)
#define S_INIT 0x01 //端口完成初始化
#define S_CONN 0x02 //端口完成連接,可以正常傳輸數據
/***************----- 端口收發數據的狀態 -----***************/
unsigned char S0_Data; //端口0接收和發送數據的狀態,1:端口接收到數據,2:端口發送數據完成
#define S_RECEIVE 0x01 //端口接收到一個數據包
#define S_TRANSMITOK 0x02 //端口發送一個數據包完成
/***************----- 端口數據緩沖區 -----***************/
unsigned char Rx_Buffer[2048]; //端口接收數據緩沖區
unsigned char Tx_Buffer[2048]; //端口發送數據緩沖區
unsigned char W5500_Interrupt; //W5500中斷標志(0:無中斷,1:有中斷)
/*******************************************************************************
* 函數名 : W5500_GPIO_Configuration
* 描述 : W5500 GPIO初始化配置
* 輸入 : 無
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void W5500_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
/* W5500_RST引腳初始化配置(PC5) */
GPIO_InitStructure.GPIO_Pin = W5500_RST; //pin 5
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz; //速率10MHZ
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
GPIO_Init(W5500_RST_PORT, &GPIO_InitStructure); //PC
GPIO_ResetBits(W5500_RST_PORT, W5500_RST); //默認PC5置低
/* W5500_INT引腳初始化配置(PC4) */
GPIO_InitStructure.GPIO_Pin = W5500_INT;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(W5500_INT_PORT, &GPIO_InitStructure);
/* Connect EXTI Line4 to PC4 */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource4);
/* PC4 as W5500 interrupt input */
EXTI_InitStructure.EXTI_Line = EXTI_Line4;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
/*******************************************************************************
* 函數名 : W5500_NVIC_Configuration
* 描述 : W5500 接收引腳中斷優先級設置
* 輸入 : 無
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void W5500_NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the EXTI4 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*******************************************************************************
* 函數名 : EXTI4_IRQHandler
* 描述 : 中斷線4中斷服務函數(W5500 INT引腳中斷服務函數)
* 輸入 : 無
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void EXTI4_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line4) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line4);
W5500_Interrupt=1;
}
}
/*******************************************************************************
* 函數名 : SPI_Configuration
* 描述 : W5500 SPI初始化配置(STM32 SPI1)
* 輸入 : 無
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void SPI_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO, ENABLE);
/* 初始化SCK、MISO、MOSI引腳 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽 PA5,6,7
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);
/* 初始化CS引腳 */
GPIO_InitStructure.GPIO_Pin = W5500_SCS;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(W5500_SCS_PORT, &GPIO_InitStructure);
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS);
/* 初始化配置STM32 SPI1 */
SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex; //SPI設置為雙線雙向全雙工
SPI_InitStructure.SPI_Mode=SPI_Mode_Master; //設置為主SPI
SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b; //SPI發送接收8位幀結構
SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low; //時鐘懸空低
SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge; //數據捕獲于第1個時鐘沿
SPI_InitStructure.SPI_NSS=SPI_NSS_Soft; //NSS由外部管腳管理
SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_2; //波特率預分頻值為2
SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB; //數據傳輸從MSB位開始
SPI_InitStructure.SPI_CRCPolynomial=7; //CRC多項式為7
SPI_Init(SPI1,&SPI_InitStructure); //根據SPI_InitStruct中指定的參數初始化外設SPI1寄存器
SPI_Cmd(SPI1,ENABLE); //STM32使能SPI1
}
/*******************************************************************************
* 函數名 : SPI1_Send_Byte
* 描述 : SPI1發送1個字節數據
* 輸入 : dat:待發送的數據
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void SPI1_Send_Byte(unsigned char dat)
{
SPI_I2S_SendData(SPI1,dat);//寫1個字節數據
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);//等待數據寄存器空
}
/*******************************************************************************
* 函數名 : SPI1_Send_Short
* 描述 : SPI1發送2個字節數據(16位)
* 輸入 : dat:待發送的16位數據
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void SPI1_Send_Short(unsigned short dat)
{
SPI1_Send_Byte(dat/256);//寫數據高位
SPI1_Send_Byte(dat); //寫數據低位
}
/*******************************************************************************
* 函數名 : Write_W5500_1Byte
* 描述 : 通過SPI1向指定地址寄存器寫1個字節數據
* 輸入 : reg:16位寄存器地址,dat:待寫入的數據
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void Write_W5500_1Byte(unsigned short reg, unsigned char dat)
{
GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為低電平 PA4
SPI1_Send_Short(reg);//通過SPI1寫16位寄存器地址
SPI1_Send_Byte(FDM1|RWB_WRITE|COMMON_R);//通過SPI1寫控制字節,1個字節數據長度,寫數據,選擇通用寄存器
SPI1_Send_Byte(dat);//寫1個字節數據
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS為高電平
}
/*******************************************************************************
* 函數名 : Write_W5500_2Byte
* 描述 : 通過SPI1向指定地址寄存器寫2個字節數據
* 輸入 : reg:16位寄存器地址,dat:16位待寫入的數據(2個字節)
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void Write_W5500_2Byte(unsigned short reg, unsigned short dat)
{
GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為低電平
SPI1_Send_Short(reg);//通過SPI1寫16位寄存器地址
SPI1_Send_Byte(FDM2|RWB_WRITE|COMMON_R);//通過SPI1寫控制字節,2個字節數據長度,寫數據,選擇通用寄存器
SPI1_Send_Short(dat);//寫16位數據
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS為高電平
}
/*******************************************************************************
* 函數名 : Write_W5500_nByte
* 描述 : 通過SPI1向指定地址寄存器寫n個字節數據
* 輸入 : reg:16位寄存器地址,*dat_ptr:待寫入數據緩沖區指針,size:待寫入的數據長度
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void Write_W5500_nByte(unsigned short reg, unsigned char *dat_ptr, unsigned short size)
{
unsigned short i;
GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為低電平
SPI1_Send_Short(reg);//通過SPI1寫16位寄存器地址
SPI1_Send_Byte(VDM|RWB_WRITE|COMMON_R);//通過SPI1寫控制字節,N個字節數據長度,寫數據,選擇通用寄存器
for(i=0;i<size;i++)//循環將緩沖區的size個字節數據寫入W5500
{
SPI1_Send_Byte(*dat_ptr++);//寫一個字節數據
}
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS為高電平
}
/*******************************************************************************
* 函數名 : Write_W5500_SOCK_1Byte
* 描述 : 通過SPI1向指定端口寄存器寫1個字節數據
* 輸入 : s:端口號,reg:16位寄存器地址,dat:待寫入的數據
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void Write_W5500_SOCK_1Byte(SOCKET s, unsigned short reg, unsigned char dat)
{
GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為低電平
SPI1_Send_Short(reg);//通過SPI1寫16位寄存器地址
SPI1_Send_Byte(FDM1|RWB_WRITE|(s*0x20+0x08));//通過SPI1寫控制字節,1個字節數據長度,寫數據,選擇端口s的寄存器
SPI1_Send_Byte(dat);//寫1個字節數據
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS為高電平
}
/*******************************************************************************
* 函數名 : Write_W5500_SOCK_2Byte
* 描述 : 通過SPI1向指定端口寄存器寫2個字節數據
* 輸入 : s:端口號,reg:16位寄存器地址,dat:16位待寫入的數據(2個字節)
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void Write_W5500_SOCK_2Byte(SOCKET s, unsigned short reg, unsigned short dat)
{
GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為低電平
SPI1_Send_Short(reg);//通過SPI1寫16位寄存器地址
SPI1_Send_Byte(FDM2|RWB_WRITE|(s*0x20+0x08));//通過SPI1寫控制字節,2個字節數據長度,寫數據,選擇端口s的寄存器
SPI1_Send_Short(dat);//寫16位數據
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS為高電平
}
/*******************************************************************************
* 函數名 : Write_W5500_SOCK_4Byte
* 描述 : 通過SPI1向指定端口寄存器寫4個字節數據
* 輸入 : s:端口號,reg:16位寄存器地址,*dat_ptr:待寫入的4個字節緩沖區指針
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void Write_W5500_SOCK_4Byte(SOCKET s, unsigned short reg, unsigned char *dat_ptr)
{
GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為低電平
SPI1_Send_Short(reg);//通過SPI1寫16位寄存器地址
SPI1_Send_Byte(FDM4|RWB_WRITE|(s*0x20+0x08));//通過SPI1寫控制字節,4個字節數據長度,寫數據,選擇端口s的寄存器
SPI1_Send_Byte(*dat_ptr++);//寫第1個字節數據
SPI1_Send_Byte(*dat_ptr++);//寫第2個字節數據
SPI1_Send_Byte(*dat_ptr++);//寫第3個字節數據
SPI1_Send_Byte(*dat_ptr++);//寫第4個字節數據
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS為高電平
}
/*******************************************************************************
* 函數名 : Read_W5500_1Byte
* 描述 : 讀W5500指定地址寄存器的1個字節數據
* 輸入 : reg:16位寄存器地址
* 輸出 : 無
* 返回值 : 讀取到寄存器的1個字節數據
* 說明 : 無
*******************************************************************************/
unsigned char Read_W5500_1Byte(unsigned short reg)
{
unsigned char i;
GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為低電平
SPI1_Send_Short(reg);//通過SPI1寫16位寄存器地址
SPI1_Send_Byte(FDM1|RWB_READ|COMMON_R);//通過SPI1寫控制字節,1個字節數據長度,讀數據,選擇通用寄存器
i=SPI_I2S_ReceiveData(SPI1);
SPI1_Send_Byte(0x00);//發送一個啞數據
i=SPI_I2S_ReceiveData(SPI1);//讀取1個字節數據
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為高電平
return i;//返回讀取到的寄存器數據
}
/*******************************************************************************
* 函數名 : Read_W5500_SOCK_1Byte
* 描述 : 讀W5500指定端口寄存器的1個字節數據
* 輸入 : s:端口號,reg:16位寄存器地址
* 輸出 : 無
* 返回值 : 讀取到寄存器的1個字節數據
* 說明 : 無
*******************************************************************************/
unsigned char Read_W5500_SOCK_1Byte(SOCKET s, unsigned short reg)
{
unsigned char i;
GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為低電平
SPI1_Send_Short(reg);//通過SPI1寫16位寄存器地址
SPI1_Send_Byte(FDM1|RWB_READ|(s*0x20+0x08));//通過SPI1寫控制字節,1個字節數據長度,讀數據,選擇端口s的寄存器
i=SPI_I2S_ReceiveData(SPI1);
SPI1_Send_Byte(0x00);//發送一個啞數據
i=SPI_I2S_ReceiveData(SPI1);//讀取1個字節數據
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為高電平
return i;//返回讀取到的寄存器數據
}
/*******************************************************************************
* 函數名 : Read_W5500_SOCK_2Byte
* 描述 : 讀W5500指定端口寄存器的2個字節數據
* 輸入 : s:端口號,reg:16位寄存器地址
* 輸出 : 無
* 返回值 : 讀取到寄存器的2個字節數據(16位)
* 說明 : 無
*******************************************************************************/
unsigned short Read_W5500_SOCK_2Byte(SOCKET s, unsigned short reg)
{
unsigned short i;
GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為低電平
SPI1_Send_Short(reg);//通過SPI1寫16位寄存器地址
SPI1_Send_Byte(FDM2|RWB_READ|(s*0x20+0x08));//通過SPI1寫控制字節,2個字節數據長度,讀數據,選擇端口s的寄存器
i=SPI_I2S_ReceiveData(SPI1);
SPI1_Send_Byte(0x00);//發送一個啞數據
i=SPI_I2S_ReceiveData(SPI1);//讀取高位數據
SPI1_Send_Byte(0x00);//發送一個啞數據
i*=256;
i+=SPI_I2S_ReceiveData(SPI1);//讀取低位數據
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為高電平
return i;//返回讀取到的寄存器數據
}
/*******************************************************************************
* 函數名 : Read_SOCK_Data_Buffer
* 描述 : 從W5500接收數據緩沖區中讀取數據
* 輸入 : s:端口號,*dat_ptr:數據保存緩沖區指針
* 輸出 : 無
* 返回值 : 讀取到的數據長度,rx_size個字節
* 說明 : 無
*******************************************************************************/
unsigned short Read_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr)
{
unsigned short rx_size;
unsigned short offset, offset1;
unsigned short i;
unsigned char j;
rx_size=Read_W5500_SOCK_2Byte(s,Sn_RX_RSR);
if(rx_size==0) return 0;//沒接收到數據則返回
if(rx_size>1460) rx_size=1460;
offset=Read_W5500_SOCK_2Byte(s,Sn_RX_RD);
offset1=offset;
offset&=(S_RX_SIZE-1);//計算實際的物理地址
GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為低電平
SPI1_Send_Short(offset);//寫16位地址
SPI1_Send_Byte(VDM|RWB_READ|(s*0x20+0x18));//寫控制字節,N個字節數據長度,讀數據,選擇端口s的寄存器
j=SPI_I2S_ReceiveData(SPI1);
if((offset+rx_size)<S_RX_SIZE)//如果最大地址未超過W5500接收緩沖區寄存器的最大地址
{
for(i=0;i<rx_size;i++)//循環讀取rx_size個字節數據
{
SPI1_Send_Byte(0x00);//發送一個啞數據
j=SPI_I2S_ReceiveData(SPI1);//讀取1個字節數據
*dat_ptr=j;//將讀取到的數據保存到數據保存緩沖區
dat_ptr++;//數據保存緩沖區指針地址自增1
}
}
else//如果最大地址超過W5500接收緩沖區寄存器的最大地址
{
offset=S_RX_SIZE-offset;
for(i=0;i<offset;i++)//循環讀取出前offset個字節數據
{
SPI1_Send_Byte(0x00);//發送一個啞數據
j=SPI_I2S_ReceiveData(SPI1);//讀取1個字節數據
*dat_ptr=j;//將讀取到的數據保存到數據保存緩沖區
dat_ptr++;//數據保存緩沖區指針地址自增1
}
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS為高電平
GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為低電平
SPI1_Send_Short(0x00);//寫16位地址
SPI1_Send_Byte(VDM|RWB_READ|(s*0x20+0x18));//寫控制字節,N個字節數據長度,讀數據,選擇端口s的寄存器
j=SPI_I2S_ReceiveData(SPI1);
for(;i<rx_size;i++)//循環讀取后rx_size-offset個字節數據
{
SPI1_Send_Byte(0x00);//發送一個啞數據
j=SPI_I2S_ReceiveData(SPI1);//讀取1個字節數據
*dat_ptr=j;//將讀取到的數據保存到數據保存緩沖區
dat_ptr++;//數據保存緩沖區指針地址自增1
}
}
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS為高電平
offset1+=rx_size;//更新實際物理地址,即下次讀取接收到的數據的起始地址
Write_W5500_SOCK_2Byte(s, Sn_RX_RD, offset1);
Write_W5500_SOCK_1Byte(s, Sn_CR, RECV);//發送啟動接收命令
return rx_size;//返回接收到數據的長度
}
/*******************************************************************************
* 函數名 : Write_SOCK_Data_Buffer
* 描述 : 將數據寫入W5500的數據發送緩沖區
* 輸入 : s:端口號,*dat_ptr:數據保存緩沖區指針,size:待寫入數據的長度
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void Write_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr, unsigned short size)
{
unsigned short offset,offset1;
unsigned short i;
//如果是UDP模式,可以在此設置目的主機的IP和端口號
if((Read_W5500_SOCK_1Byte(s,Sn_MR)&0x0f) != SOCK_UDP)//如果Socket打開失敗
{
Write_W5500_SOCK_4Byte(s, Sn_DIPR, UDP_DIPR);//設置目的主機IP
Write_W5500_SOCK_2Byte(s, Sn_DPORTR, UDP_DPORT[0]*256+UDP_DPORT[1]);//設置目的主機端口號
}
offset=Read_W5500_SOCK_2Byte(s,Sn_TX_WR);
offset1=offset;
offset&=(S_TX_SIZE-1);//計算實際的物理地址
GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為低電平
SPI1_Send_Short(offset);//寫16位地址
SPI1_Send_Byte(VDM|RWB_WRITE|(s*0x20+0x10));//寫控制字節,N個字節數據長度,寫數據,選擇端口s的寄存器
if((offset+size)<S_TX_SIZE)//如果最大地址未超過W5500發送緩沖區寄存器的最大地址
{
for(i=0;i<size;i++)//循環寫入size個字節數據
{
SPI1_Send_Byte(*dat_ptr++);//寫入一個字節的數據
}
}
else//如果最大地址超過W5500發送緩沖區寄存器的最大地址
{
offset=S_TX_SIZE-offset;
for(i=0;i<offset;i++)//循環寫入前offset個字節數據
{
SPI1_Send_Byte(*dat_ptr++);//寫入一個字節的數據
}
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS為高電平
GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS為低電平
SPI1_Send_Short(0x00);//寫16位地址
SPI1_Send_Byte(VDM|RWB_WRITE|(s*0x20+0x10));//寫控制字節,N個字節數據長度,寫數據,選擇端口s的寄存器
for(;i<size;i++)//循環寫入size-offset個字節數據
{
SPI1_Send_Byte(*dat_ptr++);//寫入一個字節的數據
}
}
GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS為高電平
offset1+=size;//更新實際物理地址,即下次寫待發送數據到發送數據緩沖區的起始地址
Write_W5500_SOCK_2Byte(s, Sn_TX_WR, offset1);
Write_W5500_SOCK_1Byte(s, Sn_CR, SEND);//發送啟動發送命令
}
/*******************************************************************************
* 函數名 : W5500_Hardware_Reset
* 描述 : 硬件復位W5500
* 輸入 : 無
* 輸出 : 無
* 返回值 : 無
* 說明 : W5500的復位引腳保持低電平至少500us以上,才能重圍W5500
*******************************************************************************/
void W5500_Hardware_Reset(void)
{
GPIO_ResetBits(W5500_RST_PORT, W5500_RST);//復位引腳拉低
delay_ms(100);
GPIO_SetBits(W5500_RST_PORT, W5500_RST);//復位引腳拉高
delay_ms(200);
while((Read_W5500_1Byte(PHYCFGR)&LINK)==0);//等待以太網連接完成
}
/*******************************************************************************
* 函數名 : W5500_Init
* 描述 : 初始化W5500寄存器函數
* 輸入 : 無
* 輸出 : 無
* 返回值 : 無
* 說明 : 在使用W5500之前,先對W5500初始化
*******************************************************************************/
void W5500_Init(void)
{
u8 i=0;
Write_W5500_1Byte(MR, RST);//軟件復位W5500,置1有效,復位后自動清0
delay_ms(20);//延時10ms,自己定義該函數
//設置網關(Gateway)的IP地址,Gateway_IP為4字節unsigned char數組,自己定義
//使用網關可以使通信突破子網的局限,通過網關可以訪問到其它子網或進入Internet
Write_W5500_nByte(GAR, Gateway_IP, 4);
//設置子網掩碼(MASK)值,SUB_MASK為4字節unsigned char數組,自己定義
//子網掩碼用于子網運算
Write_W5500_nByte(SUBR,Sub_Mask,4);
//設置物理地址,PHY_ADDR為6字節unsigned char數組,自己定義,用于唯一標識網絡設備的物理地址值
//該地址值需要到IEEE申請,按照OUI的規定,前3個字節為廠商代碼,后三個字節為產品序號
//如果自己定義物理地址,注意第一個字節必須為偶數
Write_W5500_nByte(SHAR,Phy_Addr,6);
//設置本機的IP地址,IP_ADDR為4字節unsigned char數組,自己定義
//注意,網關IP必須與本機IP屬于同一個子網,否則本機將無法找到網關
Write_W5500_nByte(SIPR,IP_Addr,4);
//設置發送緩沖區和接收緩沖區的大小,參考W5500數據手冊
for(i=0;i<8;i++)
{
Write_W5500_SOCK_1Byte(i,Sn_RXBUF_SIZE, 0x02);//Socket Rx memory size=2k
Write_W5500_SOCK_1Byte(i,Sn_TXBUF_SIZE, 0x02);//Socket Tx mempry size=2k
}
//設置重試時間,默認為2000(200ms)
//每一單位數值為100微秒,初始化時值設為2000(0x07D0),等于200毫秒
Write_W5500_2Byte(RTR, 0x07d0);
//設置重試次數,默認為8次
//如果重發的次數超過設定值,則產生超時中斷(相關的端口中斷寄存器中的Sn_IR 超時位(TIMEOUT)置“1”)
Write_W5500_1Byte(RCR,8);
//啟動中斷,參考W5500數據手冊確定自己需要的中斷類型
//IMR_CONFLICT是IP地址沖突異常中斷,IMR_UNREACH是UDP通信時,地址無法到達的異常中斷
//其它是Socket事件中斷,根據需要添加
Write_W5500_1Byte(IMR,IM_IR7 | IM_IR6);
Write_W5500_1Byte(SIMR,S0_IMR);
Write_W5500_SOCK_1Byte(0, Sn_IMR, IMR_SENDOK | IMR_TIMEOUT | IMR_RECV | IMR_DISCON | IMR_CON);
}
/*******************************************************************************
* 函數名 : Detect_Gateway
* 描述 : 檢查網關服務器
* 輸入 : 無
* 輸出 : 無
* 返回值 : 成功返回TRUE(0xFF),失敗返回FALSE(0x00)
* 說明 : 無
*******************************************************************************/
unsigned char Detect_Gateway(void)
{
unsigned char ip_adde[4];
ip_adde[0]=IP_Addr[0]+1;
ip_adde[1]=IP_Addr[1]+1;
ip_adde[2]=IP_Addr[2]+1;
ip_adde[3]=IP_Addr[3]+1;
//檢查網關及獲取網關的物理地址
Write_W5500_SOCK_4Byte(0,Sn_DIPR,ip_adde);//向目的地址寄存器寫入與本機IP不同的IP值
Write_W5500_SOCK_1Byte(0,Sn_MR,MR_TCP);//設置socket為TCP模式
Write_W5500_SOCK_1Byte(0,Sn_CR,OPEN);//打開Socket
delay_ms(5);//延時5ms
if(Read_W5500_SOCK_1Byte(0,Sn_SR) != SOCK_INIT)//如果socket打開失敗
{
Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//打開不成功,關閉Socket
return FALSE;//返回FALSE(0x00)
}
Write_W5500_SOCK_1Byte(0,Sn_CR,CONNECT);//設置Socket為Connect模式
do
{
u8 j=0;
j=Read_W5500_SOCK_1Byte(0,Sn_IR);//讀取Socket0中斷標志寄存器
if(j!=0)
Write_W5500_SOCK_1Byte(0,Sn_IR,j);
delay_ms(5);//延時5ms
if((j&IR_TIMEOUT) == IR_TIMEOUT)
{
return FALSE;
}
else if(Read_W5500_SOCK_1Byte(0,Sn_DHAR) != 0xff)
{
Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//關閉Socket
return TRUE;
}
}while(1);
}
/*******************************************************************************
* 函數名 : Socket_Init
* 描述 : 指定Socket(0~7)初始化
* 輸入 : s:待初始化的端口
* 輸出 : 無
* 返回值 : 無
* 說明 : 無
*******************************************************************************/
void Socket_Init(SOCKET s)
{
//設置分片長度,參考W5500數據手冊,該值可以不修改
Write_W5500_SOCK_2Byte(0, Sn_MSSR, 1460);//最大分片字節數=1460(0x5b4)
//設置指定端口
switch(s)
{
case 0:
//設置端口0的端口號
Write_W5500_SOCK_2Byte(0, Sn_PORT, S0_Port[0]*256+S0_Port[1]);
//設置端口0目的(遠程)端口號
Write_W5500_SOCK_2Byte(0, Sn_DPORTR, S0_DPort[0]*256+S0_DPort[1]);
//設置端口0目的(遠程)IP地址
Write_W5500_SOCK_4Byte(0, Sn_DIPR, S0_DIP);
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
default:
break;
}
}
/*******************************************************************************
* 函數名 : Socket_Connect
* 描述 : 設置指定Socket(0~7)為客戶端與遠程服務器連接
* 輸入 : s:待設定的端口
* 輸出 : 無
* 返回值 : 成功返回TRUE(0xFF),失敗返回FALSE(0x00)
* 說明 : 當本機Socket工作在客戶端模式時,引用該程序,與遠程服務器建立連接
* 如果啟動連接后出現超時中斷,則與服務器連接失敗,需要重新調用該程序連接
* 該程序每調用一次,就與服務器產生一次連接
*******************************************************************************/
unsigned char Socket_Connect(SOCKET s)
{
Write_W5500_SOCK_1Byte(s,Sn_MR,MR_TCP);//設置socket為TCP模式
Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打開Socket
delay_ms(5);//延時5ms
if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_INIT)//如果socket打開失敗
{
Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打開不成功,關閉Socket
return FALSE;//返回FALSE(0x00)
}
Write_W5500_SOCK_1Byte(s,Sn_CR,CONNECT);//設置Socket為Connect模式
return TRUE;//返回TRUE,設置成功
}
/*******************************************************************************
* 函數名 : Socket_Listen
* 描述 : 設置指定Socket(0~7)作為服務器等待遠程主機的連接
* 輸入 : s:待設定的端口
* 輸出 : 無
* 返回值 : 成功返回TRUE(0xFF),失敗返回FALSE(0x00)
* 說明 : 當本機Socket工作在服務器模式時,引用該程序,等等遠程主機的連接
* 該程序只調用一次,就使W5500設置為服務器模式
*******************************************************************************/
unsigned char Socket_Listen(SOCKET s)
{
Write_W5500_SOCK_1Byte(s,Sn_MR,MR_TCP);//設置socket為TCP模式
Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打開Socket
delay_ms(5);//延時5ms
if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_INIT)//如果socket打開失敗
{
Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打開不成功,關閉Socket
return FALSE;//返回FALSE(0x00)
}
Write_W5500_SOCK_1Byte(s,Sn_CR,LISTEN);//設置Socket為偵聽模式
delay_ms(5);//延時5ms
if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_LISTEN)//如果socket設置失敗
{
Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//設置不成功,關閉Socket
return FALSE;//返回FALSE(0x00)
}
return TRUE;
//至此完成了Socket的打開和設置偵聽工作,至于遠程客戶端是否與它建立連接,則需要等待Socket中斷,
//以判斷Socket的連接是否成功。參考W5500數據手冊的Socket中斷狀態
//在服務器偵聽模式不需要設置目的IP和目的端口號
}
……………………
…………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
代碼工程51hei附件下載:
(溫濕度監測+W5500 AD采集)服務器端 單AD 多通道.7z
(211.5 KB, 下載次數: 63)
2021-7-25 17:04 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
2279652997
時間:
2024-7-1 16:52
good 收藏了
作者:
2279652997
時間:
2024-7-1 16:52
good 收下了
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1