色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于STM32的WEB服務器設計

DS小龍哥-嵌入式技術 ? 來源:DS小龍哥-嵌入式技術 ? 作者:DS小龍哥-嵌入式技 ? 2022-02-28 14:03 ? 次閱讀

?一、環境介紹

MCU:STM32F103ZET6

網卡:ENC28J60

協議棧: UIP

開發軟件:Keil5

二、功能介紹

STM32控制ENC28J60+UIP協議棧創建TCP服務器(WEB服務器),支持瀏覽器訪問完成數據傳輸。 瀏覽器可以實時顯示溫度、時間、可以控制STM32開發板上的LED燈、蜂鳴器。

基于STM32的WEB服務器設計

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png基于STM32的WEB服務器設計

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png基于STM32的WEB服務器設計

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

基于STM32的WEB服務器設計

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

基于STM32的WEB服務器設計poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

基于STM32的WEB服務器設計poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

?

三、ENC28J60芯片介紹

ENC28J60 是帶有行業標準串行外設接口(Serial Peripheral Interface,SPI)的獨立以太網 控制器。它可作為任何配備有 SPI 的控制器的以太網接口。ENC28J60 符合 IEEE 802.3 的全部規范,采用了一系列包過濾機制以對傳入數據包進行限制。 它還提供了一個內部 DMA 模塊, 以實現快速數據吞吐和硬件支持的 IP 校驗和計算。 與主控制器的通信通過兩個中斷引腳和 SPI 實現,數據傳輸速率高達 10 Mb/s。兩個專用的引腳用于連接 LED,進行網絡活動狀態指示。ENC28J60 總共只有 28 腳,提供 QFN/TF

ENC28J60 的主要特點如下:

兼容 IEEE802.3 協議的以太網控制器

集成 MAC 和 10 BASE-T 物理層

支持全雙工和半雙工模式

數據沖突時可編程自動重發

SPI 接口速度可達 10Mbps

8K 數據接收和發送雙端口 RAM

提供快速數據移動的內部 DMA 控制器

可配置的接收和發送緩沖區大小

兩個可編程 LED 輸出

帶7個中斷源的兩個中斷引腳

TTL 電平輸入

提供多種封裝:SOIC/SSOP/SPDIP/QFN 等。

ENC28J60 由七個主要功能模塊組成:

1) SPI 接口,充當主控制器和 ENC28J60 之間通信通道。

2) 控制寄存器,用于控制和監視 ENC28J60。

3) 雙端口 RAM 緩沖器,用于接收和發送數據包。

4) 判優器,當 DMA、發送和接收模塊發出請求時對 RAM 緩沖器的訪問進行控制。

5) 總線接口,對通過 SPI 接收的數據和命令進行解析。

6) MAC(Medium Access Control)模塊,實現符合 IEEE 802.3 標準的 MAC 邏輯。

7) PHY(物理層)模塊,對雙絞線上的模擬數據進行編碼和譯碼。

ENC28J60 還包括其他支持模塊,諸如振蕩器、片內穩壓器、電平變換器(提供可以接受 5V 電壓的 I/O 引腳)和系統控制邏輯。

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

四、UIP 簡介

uIP 由瑞典計算機科學學院(網絡嵌入式系統小組)的Adam Dunkels 開發。其源代碼由C 語 言編寫,并完全公開,uIP 的最新版本是 1.0 版本。 uIP 協議棧去掉了完整的 TCP/IP 中不常用的功能,簡化了通訊流程,但保留了網絡通信 必須使用的協議,設計重點放在了 IP/TCP/ICMP/UDP/ARP 這些網絡層和傳輸層協議上,保證 了其代碼的通用性和結構的穩定性。

由于 uIP 協議棧專門為嵌入式系統而設計,因此還具有如下優越功能:

1) 代碼非常少,其協議棧代碼不到 6K,很方便閱讀和移植。

2) 占用的內存數非常少,RAM 占用僅幾百字節。

3) 其硬件處理層、協議棧層和應用層共用一個全局緩存區,不存在數據的拷貝,且發送 和接收都是依靠這個緩存區,極大的節省空間和時間。

4) 支持多個主動連接和被動連接并發。

5) 其源代碼中提供一套實例程序:web 服務器,web 客戶端,電子郵件發送程序(SMTP 客 戶端),Telnet 服務器, DNS 主機名解析程序等。通用性強,移植起來基本不用修改就可以通過。

6) 對數據的處理采用輪循機制,不需要操作系統的支持。 由于 uIP 對資源的需求少和移植容易,大部分的 8 位微控制器都使用過uIP 協議棧, 而且很多的著名的嵌入式產品和項目(如衛星,Cisco 路由器,無線傳感器網絡)中都在使用 uIP 協議棧。 uIP 相當于一個代碼庫,通過一系列的函數實現與底層硬件和高層應用程序的通訊,對于 整個系統來說它內部的協議組是透明的,從而增加了協議的通用性。

uIP 提供的接口函數有:

1.初始化 uIP 協議棧:uip_init()

2.處理輸入包:uip_input()

3.處理周期計時事件:uip_periodic()

4.開始監聽端口:uip_listen()

5.連接到遠程主機:uip_connect()

6.接收到連接請求:uip_connected()

7.主動關閉連接:uip_close()

8.連接被關閉:uip_closed()

9.發出去的數據被應答:uip_acked()

10.在當前連接發送數據:uip_send()

11.在當前連接上收到新的數據:uip_newdata()

12.告訴對方要停止連接:uip_stop()

13.連接被意外終止:uip_aborted()

基于STM32的WEB服務器設計

?

poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

五、核心代碼

5.1 main.c

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include 
#include 
#include "enc28j60.h"
#include "time.h"

#include "uip.h"
#include "uip_arp.h"
#include "tapdev.h"
#include "timer.h"
#include "uip-conf.h"
#include "httpd.h"
#include "ds18b20.h"
#include "rtc.h"

void uip_EventPoll(void); //事件處理函數
#define UIP_BUF ((struct uip_eth_hdr *)&uip_buf[0])

/*
當Uip接收到Uip接收到底層傳遞的數據,將接收到的數據通過調用http_appcall(),傳遞給Webserver處理,
再通過handle_connection()先后調用handle_input()函數和handle_output()函數
handle_input()主要作用是分析http數據流:得到請求的路徑、解析出請求的文件名稱。
然后調用函數handle_output進行查找對應文件,進行發送到瀏覽器,完成交互。
注意:瀏覽器最好使用谷歌瀏覽器,否則會導致訪問失敗!
*/

int main()
{
    u8 key;
    u32 tcnt=0;
    uip_ipaddr_t ipaddr;	//保存IP地址信息

    BeepInit();		  //蜂鳴器初始化
    LedInit();      //LED燈初始化
    UsartInit(USART1,72,115200);
    KeyInit();      //按鍵初始化
    TimerInit(TIM6,72,10000);  //定時器初始化,
		DS18B20_Init();
		RTC_Init();
	  SET_RTC_TIME(2019,5,24,10,58,20);
    printf("串口工作正常!rn");

    while(tapdev_init())	//初始化ENC28J60錯誤
    {
        printf("ENC28J60 Init Error!rn");
        Delay72M_Ms(500);
    }
    printf("ENC28J60 初始化成功!rn");

    uip_init();				                  //uIP初始化
    uip_ipaddr(ipaddr, 192,168,1,89);	  //填充開發板IP地址
    uip_sethostaddr(ipaddr);		        //設置開發板IP地址

    uip_ipaddr(ipaddr, 192,168,1,1); 	  //填充開發板網關地址
    uip_setdraddr(ipaddr);	            //設置開發板網關IP地址(其實就是你路由器的IP地址)

    uip_ipaddr(ipaddr, 255,255,255,0);  //填充開發板網絡掩碼
    uip_setnetmask(ipaddr);             //填充開發板網絡掩碼
    httpd_init();                       //創建WEB服務器,設置監聽端口

    while(1)
    {			
        uip_EventPoll(); 		 //輪詢方式處理處理網絡數據
    }
}

/*
函數功能:uip事件處理函數,需要將該函數插入用戶主循環,循環調用
*/
void uip_EventPoll(void)
{
    u8 i;
    static struct timer  arp_timer; //定義定時器
    static u8 timer_ok=0;

    if(timer_ok==0)//僅初始化一次
    {
        timer_ok = 1;
        timer_set(&arp_timer,CLOCK_SECOND*10);	   	//創建1個10秒的定時器
    }

    uip_len=tapdev_read();	//從網絡設備讀取一個IP包,得到數據長度.uip_len在uip.c中定義
    if(uip_len>0) 			    //有數據
    {
        //處理IP數據包(只有校驗通過的IP包才會被接收)
        if(UIP_BUF->type == htons(UIP_ETHTYPE_IP))//是否是IP包?
        {
            uip_arp_ipin();	//去除以太網頭結構,更新ARP表
            uip_input();   	//IP包處理
            //當上面的函數執行后,如果需要發送數據,則全局變量 uip_len > 0
            //需要發送的數據在uip_buf, 長度是uip_len  (這是2個全局變量)
            if(uip_len>0)//需要回應數據
            {
                uip_arp_out();//加以太網頭結構,在主動連接時可能要構造ARP請求
                tapdev_send();//發送數據到以太網
            }
        } else if (UIP_BUF->type==htons(UIP_ETHTYPE_ARP))//處理arp報文,是否是ARP請求包?
        {
            uip_arp_arpin();
            //當上面的函數執行后,如果需要發送數據,則全局變量uip_len>0
            //需要發送的數據在uip_buf, 長度是uip_len(這是2個全局變量)
            if(uip_len>0)tapdev_send();//需要發送數據,則通過tapdev_send發送
        }
    }
    //輪流處理每個TCP連接, UIP_CONNS缺省是40個
    for(i=0; i0
        //需要發送的數據在uip_buf, 長度是uip_len (這是2個全局變量)
        if(uip_len>0)
        {
            uip_arp_out();//加以太網頭結構,在主動連接時可能要構造ARP請求
            tapdev_send();//發送數據到以太網
        }
    }

    //每隔10秒調用1次ARP定時器函數 用于定期ARP處理,ARP表10秒更新一次,舊的條目會被拋棄
    if(timer_expired(&arp_timer))
    {
        timer_reset(&arp_timer);
        uip_arp_timer();
    }
}

;>
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

5.2 enc28j60.c

#include "delay.h"
#include 
#include "enc28j60.h"	

/*
以下是ENC28J60驅動移植接口:
MISO--->PA6----主機輸入
MOSI--->PA7----主機輸出
SCLK--->PA5----時鐘信號
CS----->PA4----片選
RESET-->PG15---復位
*/
#define ENC28J60_CS		PAout(4) 	//ENC28J60片選信號
#define ENC28J60_RST	PGout(15)	//ENC28J60復位信號
#define ENC28J60_MOSI PAout(7)  //輸出
#define ENC28J60_MISO PAin(6)   //輸入
#define ENC28J60_SCLK PAout(5)  //時鐘線

static u8 ENC28J60BANK;
static u32 NextPacketPtr;


/*
函數功能:底層SPI接口收發一個字節
說    明:模擬SPI時序,ENC28J60時鐘線空閑電平為低電平,在第一個下降沿采集數據
*/
u8 ENC28J60_SPI_ReadWriteOneByte(u8 tx_data)
{
	u16 cnt=0;				 
	while((SPI1->SR&1<<1)==0)		 //等待發送區空--等待發送緩沖為空	
	{
		cnt++;
		if(cnt>=65530)return 0; 	  //超時退出  u16=2個字節
	}	
	SPI1->DR=tx_data;	 	  		      //發送一個byte 
	cnt=0;
	while((SPI1->SR&1<<0)==0) 		//等待接收完一個byte   
	{
		cnt++;
		if(cnt>=65530)return 0;	   //超時退出
	}	  						    
	return SPI1->DR;          		//返回收到的數據				
}


/*
函數功能:復位ENC28J60,包括SPI初始化/IO初始化等
MISO--->PA6----主機輸入
MOSI--->PA7----主機輸出
SCLK--->PA5----時鐘信號
CS----->PA4----片選
RESET-->PG15---復位
*/
void ENC28J60_Reset(void)
{
/*開啟時鐘*/
	RCC->APB2ENR|=1<<12;   //開啟SPI1時鐘
	RCC->APB2ENR|=1<<2;    //PA
	GPIOA->CRL&=0X0000FFFF; //清除寄存器
	GPIOA->CRL|=0XB8B30000;
	GPIOA->ODR|=0XF<<4; //   	上拉--輸出高電平
	GPIOA->ODR&=~(1<<5);
	
	 RCC->APB2ENR|=1<<8; //2 3 4 5 6 7 8
	 GPIOG->CRH&=0x0FFFFFFF;
	 GPIOG->CRH|=0x30000000;

	/*SPI2基本配置*/
	SPI1->CR1=0X0; 		//清空寄存器
	SPI1->CR1|=0<<15; //選擇“雙線雙向”模式
	SPI1->CR1|=0<<11; //使用8位數據幀格式進行發送/接收;
	SPI1->CR1|=0<<10; //全雙工(發送和接收);
	SPI1->CR1|=1<<9;  //啟用軟件從設備管理
	SPI1->CR1|=1<<8;  //NSS
	SPI1->CR1|=0<<7;  //幀格式,先發送高位
	SPI1->CR1|=0x1<<3;//當總線頻率為36MHZ時,SPI速度為18MHZ,高速。
	SPI1->CR1|=1<<2;  //配置為主設備
	SPI1->CR1|=1<<1;  //空閑狀態時, SCK保持高電平。
	SPI1->CR1|=1<<0;  //數據采樣從第二個時鐘邊沿開始。
	SPI1->CR1|=1<<6;  //開啟SPI設備。
	
	//針對ENC28J60的特點(SCK空閑為低電平)修改SPI的設置
 	SPI1->CR1&=~(1<<6); 	//SPI設備失能
	SPI1->CR1&=~(1<<1); 	//空閑模式下SCK為0 CPOL=0
	SPI1->CR1&=~(1<<0); 	//數據采樣從第1個時間邊沿開始,CPHA=0  
	SPI1->CR1|=1<<6; 	  	//SPI設備使能
	
	ENC28J60_RST=0;			//復位ENC28J60
	DelayMs(10);	 
	ENC28J60_RST=1;			//復位結束				    
	DelayMs(10);	  
}


/*
函數功能:讀取ENC28J60寄存器(帶操作碼) 
參	  數:op:操作碼
					addr:寄存器地址/參數
返 回 值:讀到的數據
*/
u8 ENC28J60_Read_Op(u8 op,u8 addr)
{
	u8 dat=0;	 
	ENC28J60_CS=0;	 
	dat=op|(addr&ADDR_MASK);
	ENC28J60_SPI_ReadWriteOneByte(dat);
	dat=ENC28J60_SPI_ReadWriteOneByte(0xFF);
	//如果是讀取MAC/MII寄存器,則第二次讀到的數據才是正確的,見手冊29頁
 	if(addr&0x80)dat=ENC28J60_SPI_ReadWriteOneByte(0xFF);
	ENC28J60_CS=1;
	return dat;
}



/*
函數功能:讀取ENC28J60寄存器(帶操作碼) 
參    數:
				op:操作碼
				addr:寄存器地址
				data:參數
*/
void ENC28J60_Write_Op(u8 op,u8 addr,u8 data)
{
	u8 dat = 0;	    
	ENC28J60_CS=0;			   
	dat=op|(addr&ADDR_MASK);
	ENC28J60_SPI_ReadWriteOneByte(dat);	  
	ENC28J60_SPI_ReadWriteOneByte(data);
	ENC28J60_CS=1;
}



/*
函數功能:讀取ENC28J60接收緩存數據
參    數:
				len:要讀取的數據長度
				data:輸出數據緩存區(末尾自動添加結束符)
*/
void ENC28J60_Read_Buf(u32 len,u8* data)
{
	ENC28J60_CS=0;			 
	ENC28J60_SPI_ReadWriteOneByte(ENC28J60_READ_BUF_MEM);
	while(len)
	{
		len--;			  
		*data=(u8)ENC28J60_SPI_ReadWriteOneByte(0);
		data++;
	}
	*data='?';
	ENC28J60_CS=1;
}


/*
函數功能:向ENC28J60寫發送緩存數據
參    數:
				len:要寫入的數據長度
				data:數據緩存區
*/
void ENC28J60_Write_Buf(u32 len,u8* data)
{
	ENC28J60_CS=0;			   
	ENC28J60_SPI_ReadWriteOneByte(ENC28J60_WRITE_BUF_MEM);		 
	while(len)
	{
		len--;
		ENC28J60_SPI_ReadWriteOneByte(*data);
		data++;
	}
	ENC28J60_CS=1;
}

/*
函數功能:設置ENC28J60寄存器Bank
參    數:
				ban:要設置的bank
*/
void ENC28J60_Set_Bank(u8 bank)
{								    
	if((bank&BANK_MASK)!=ENC28J60BANK)//和當前bank不一致的時候,才設置
	{				  
		ENC28J60_Write_Op(ENC28J60_BIT_FIELD_CLR,ECON1,(ECON1_BSEL1|ECON1_BSEL0));
		ENC28J60_Write_Op(ENC28J60_BIT_FIELD_SET,ECON1,(bank&BANK_MASK)>>5);
		ENC28J60BANK=(bank&BANK_MASK);
	}
}


/*
函數功能:讀取ENC28J60指定寄存器
參    數:addr:寄存器地址
返 回 值:讀到的數據
*/
u8 ENC28J60_Read(u8 addr)
{						  
	ENC28J60_Set_Bank(addr);//設置BANK		 
	return ENC28J60_Read_Op(ENC28J60_READ_CTRL_REG,addr);
}


/*
函數功能:向ENC28J60指定寄存器寫數據
參    數:
					addr:寄存器地址
					data:要寫入的數據		
*/
void ENC28J60_Write(u8 addr,u8 data)
{					  
	ENC28J60_Set_Bank(addr);		 
	ENC28J60_Write_Op(ENC28J60_WRITE_CTRL_REG,addr,data);
}


/*
函數功能:向ENC28J60的PHY寄存器寫入數據
參    數:
				addr:寄存器地址
				data:要寫入的數據	
*/
void ENC28J60_PHY_Write(u8 addr,u32 data)
{
	u16 retry=0;
	ENC28J60_Write(MIREGADR,addr);	//設置PHY寄存器地址
	ENC28J60_Write(MIWRL,data);		//寫入數據
	ENC28J60_Write(MIWRH,data>>8);		   
	while((ENC28J60_Read(MISTAT)&MISTAT_BUSY)&&retry<0XFFF)retry++;//等待寫入PHY結束		  
}


/*
函數功能:初始化ENC28J60
參    數:macaddr:MAC地址
返 回 值:
				  0,初始化成功;
          1,初始化失敗;
*/
u8 ENC28J60_Init(u8* macaddr)
{		
	u16 retry=0;		  
	ENC28J60_Reset(); //復位底層引腳接口
	ENC28J60_Write_Op(ENC28J60_SOFT_RESET,0,ENC28J60_SOFT_RESET);//軟件復位
	while(!(ENC28J60_Read(ESTAT)&ESTAT_CLKRDY)&&retry<500)//等待時鐘穩定
	{
		retry++;
		DelayMs(1);
	};
	if(retry>=500)return 1;//ENC28J60初始化失敗
	// do bank 0 stuff
	// initialize receive buffer
	// 16-bit transfers,must write low byte first
	// set receive buffer start address	   設置接收緩沖區地址  8K字節容量
	NextPacketPtr=RXSTART_INIT;
	// Rx start
	//接收緩沖器由一個硬件管理的循環FIFO 緩沖器構成。
	//寄存器對ERXSTH:ERXSTL 和ERXNDH:ERXNDL 作
	//為指針,定義緩沖器的容量和其在存儲器中的位置。
	//ERXST和ERXND指向的字節均包含在FIFO緩沖器內。
	//當從以太網接口接收數據字節時,這些字節被順序寫入
	//接收緩沖器。 但是當寫入由ERXND 指向的存儲單元
	//后,硬件會自動將接收的下一字節寫入由ERXST 指向
	//的存儲單元。 因此接收硬件將不會寫入FIFO 以外的單
	//元。
	//設置接收起始字節
	ENC28J60_Write(ERXSTL,RXSTART_INIT&0xFF);	
	ENC28J60_Write(ERXSTH,RXSTART_INIT>>8);	  
	//ERXWRPTH:ERXWRPTL 寄存器定義硬件向FIFO 中
	//的哪個位置寫入其接收到的字節。 指針是只讀的,在成
	//功接收到一個數據包后,硬件會自動更新指針。 指針可
	//用于判斷FIFO 內剩余空間的大小  8K-1500。 
	//設置接收讀指針字節
	ENC28J60_Write(ERXRDPTL,RXSTART_INIT&0xFF);
	ENC28J60_Write(ERXRDPTH,RXSTART_INIT>>8);
	//設置接收結束字節
	ENC28J60_Write(ERXNDL,RXSTOP_INIT&0xFF);
	ENC28J60_Write(ERXNDH,RXSTOP_INIT>>8);
	//設置發送起始字節
	ENC28J60_Write(ETXSTL,TXSTART_INIT&0xFF);
	ENC28J60_Write(ETXSTH,TXSTART_INIT>>8);
	//設置發送結束字節
	ENC28J60_Write(ETXNDL,TXSTOP_INIT&0xFF);
	ENC28J60_Write(ETXNDH,TXSTOP_INIT>>8);
	// do bank 1 stuff,packet filter:
	// For broadcast packets we allow only ARP packtets
	// All other packets should be unicast only for our mac (MAADR)
	//
	// The pattern to match on is therefore
	// Type     ETH.DST
	// ARP      BROADCAST
	// 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
	// in binary these poitions are:11 0000 0011 1111
	// This is hex 303F->EPMM0=0x3f,EPMM1=0x30
	//接收過濾器
	//UCEN:單播過濾器使能位
	//當ANDOR = 1 時:
	//1 = 目標地址與本地MAC 地址不匹配的數據包將被丟棄
	//0 = 禁止過濾器
	//當ANDOR = 0 時:
	//1 = 目標地址與本地MAC 地址匹配的數據包會被接受
	//0 = 禁止過濾器
	//CRCEN:后過濾器CRC 校驗使能位
	//1 = 所有CRC 無效的數據包都將被丟棄
	//0 = 不考慮CRC 是否有效
	//PMEN:格式匹配過濾器使能位
	//當ANDOR = 1 時:
	//1 = 數據包必須符合格式匹配條件,否則將被丟棄
	//0 = 禁止過濾器
	//當ANDOR = 0 時:
	//1 = 符合格式匹配條件的數據包將被接受
	//0 = 禁止過濾器
	ENC28J60_Write(ERXFCON,ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);
	ENC28J60_Write(EPMM0,0x3f);
	ENC28J60_Write(EPMM1,0x30);
	ENC28J60_Write(EPMCSL,0xf9);
	ENC28J60_Write(EPMCSH,0xf7);
	// do bank 2 stuff
	// enable MAC receive
	//bit 0 MARXEN:MAC 接收使能位
	//1 = 允許MAC 接收數據包
	//0 = 禁止數據包接收
	//bit 3 TXPAUS:暫停控制幀發送使能位
	//1 = 允許MAC 發送暫停控制幀(用于全雙工模式下的流量控制)
	//0 = 禁止暫停幀發送
	//bit 2 RXPAUS:暫停控制幀接收使能位
	//1 = 當接收到暫停控制幀時,禁止發送(正常操作)
	//0 = 忽略接收到的暫停控制幀
	ENC28J60_Write(MACON1,MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);
	// bring MAC out of reset
	//將MACON2 中的MARST 位清零,使MAC 退出復位狀態。
	ENC28J60_Write(MACON2,0x00);
	// enable automatic padding to 60bytes and CRC operations
	//bit 7-5 PADCFG2:PACDFG0:自動填充和CRC 配置位
	//111 = 用0 填充所有短幀至64 字節長,并追加一個有效的CRC
	//110 = 不自動填充短幀
	//101 = MAC 自動檢測具有8100h 類型字段的VLAN 協議幀,并自動填充到64 字節長。如果不
	//是VLAN 幀,則填充至60 字節長。填充后還要追加一個有效的CRC
	//100 = 不自動填充短幀
	//011 = 用0 填充所有短幀至64 字節長,并追加一個有效的CRC
	//010 = 不自動填充短幀
	//001 = 用0 填充所有短幀至60 字節長,并追加一個有效的CRC
	//000 = 不自動填充短幀
	//bit 4 TXCRCEN:發送CRC 使能位
	//1 = 不管PADCFG如何,MAC都會在發送幀的末尾追加一個有效的CRC。 如果PADCFG規定要
	//追加有效的CRC,則必須將TXCRCEN 置1。
	//0 = MAC不會追加CRC。 檢查最后4 個字節,如果不是有效的CRC 則報告給發送狀態向量。
	//bit 0 FULDPX:MAC 全雙工使能位
	//1 = MAC工作在全雙工模式下。 PHCON1.PDPXMD 位必須置1。
	//0 = MAC工作在半雙工模式下。 PHCON1.PDPXMD 位必須清零。
	ENC28J60_Write_Op(ENC28J60_BIT_FIELD_SET,MACON3,MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN|MACON3_FULDPX);
	// set inter-frame gap (non-back-to-back)
	//配置非背對背包間間隔寄存器的低字節
	//MAIPGL。 大多數應用使用12h 編程該寄存器。
	//如果使用半雙工模式,應編程非背對背包間間隔
	//寄存器的高字節MAIPGH。 大多數應用使用0Ch
	//編程該寄存器。
	ENC28J60_Write(MAIPGL,0x12);
	ENC28J60_Write(MAIPGH,0x0C);
	// set inter-frame gap (back-to-back)
	//配置背對背包間間隔寄存器MABBIPG。當使用
	//全雙工模式時,大多數應用使用15h 編程該寄存
	//器,而使用半雙工模式時則使用12h 進行編程。
	ENC28J60_Write(MABBIPG,0x15);
	// Set the maximum packet size which the controller will accept
	// Do not send packets longer than MAX_FRAMELEN:
	// 最大幀長度  1500
	ENC28J60_Write(MAMXFLL,MAX_FRAMELEN&0xFF);	
	ENC28J60_Write(MAMXFLH,MAX_FRAMELEN>>8);
	// do bank 3 stuff
	// write MAC address
	// NOTE: MAC address in ENC28J60 is byte-backward
	//設置MAC地址
	ENC28J60_Write(MAADR5,macaddr[0]);	
	ENC28J60_Write(MAADR4,macaddr[1]);
	ENC28J60_Write(MAADR3,macaddr[2]);
	ENC28J60_Write(MAADR2,macaddr[3]);
	ENC28J60_Write(MAADR1,macaddr[4]);
	ENC28J60_Write(MAADR0,macaddr[5]);
	//配置PHY為全雙工  LEDB為拉電流
	ENC28J60_PHY_Write(PHCON1,PHCON1_PDPXMD);	 
	// no loopback of transmitted frames	 禁止環回
	//HDLDIS:PHY 半雙工環回禁止位
	//當PHCON1.PDPXMD = 1 或PHCON1.PLOOPBK = 1 時:
	//此位可被忽略。
	//當PHCON1.PDPXMD = 0 且PHCON1.PLOOPBK = 0 時:
	//1 = 要發送的數據僅通過雙絞線接口發出
	//0 = 要發送的數據會環回到MAC 并通過雙絞線接口發出
	ENC28J60_PHY_Write(PHCON2,PHCON2_HDLDIS);
	// switch to bank 0
	//ECON1 寄存器
	//寄存器3-1 所示為ECON1 寄存器,它用于控制
	//ENC28J60 的主要功能。 ECON1 中包含接收使能、發
	//送請求、DMA 控制和存儲區選擇位。	   
	ENC28J60_Set_Bank(ECON1);
	// enable interrutps
	//EIE: 以太網中斷允許寄存器
	//bit 7 INTIE: 全局INT 中斷允許位
	//1 = 允許中斷事件驅動INT 引腳
	//0 = 禁止所有INT 引腳的活動(引腳始終被驅動為高電平)
	//bit 6 PKTIE: 接收數據包待處理中斷允許位
	//1 = 允許接收數據包待處理中斷
	//0 = 禁止接收數據包待處理中斷
	ENC28J60_Write_Op(ENC28J60_BIT_FIELD_SET,EIE,EIE_INTIE|EIE_PKTIE);
	// enable packet reception
	//bit 2 RXEN:接收使能位
	//1 = 通過當前過濾器的數據包將被寫入接收緩沖器
	//0 = 忽略所有接收的數據包
	ENC28J60_Write_Op(ENC28J60_BIT_FIELD_SET,ECON1,ECON1_RXEN);
	if(ENC28J60_Read(MAADR5)== macaddr[0])return 0;//初始化成功
	else return 1; 	  

}

/*
函數功能:讀取EREVID
參    數:
*/
u8 ENC28J60_Get_EREVID(void)
{
	//在EREVID 內也存儲了版本信息。 EREVID 是一個只讀控
	//制寄存器,包含一個5 位標識符,用來標識器件特定硅片
	//的版本號
	return ENC28J60_Read(EREVID);
}



/*
函數功能:通過ENC28J60發送數據包到網絡
參    數:
					len   :數據包大小
          packet:數據包
*/
void ENC28J60_Packet_Send(u32 len,u8* packet)
{
	//設置發送緩沖區地址寫指針入口
	ENC28J60_Write(EWRPTL,TXSTART_INIT&0xFF);
	ENC28J60_Write(EWRPTH,TXSTART_INIT>>8);
	//設置TXND指針,以對應給定的數據包大小	   
	ENC28J60_Write(ETXNDL,(TXSTART_INIT+len)&0xFF);
	ENC28J60_Write(ETXNDH,(TXSTART_INIT+len)>>8);
	//寫每包控制字節(0x00表示使用macon3的設置) 
	ENC28J60_Write_Op(ENC28J60_WRITE_BUF_MEM,0,0x00);
	//復制數據包到發送緩沖區
	//printf("len:%drn",len);	//監視發送數據長度
 	ENC28J60_Write_Buf(len,packet);
 	//發送數據到網絡
	ENC28J60_Write_Op(ENC28J60_BIT_FIELD_SET,ECON1,ECON1_TXRTS);
	//復位發送邏輯的問題。參見Rev. B4 Silicon Errata point 12.
	if((ENC28J60_Read(EIR)&EIR_TXERIF))ENC28J60_Write_Op(ENC28J60_BIT_FIELD_CLR,ECON1,ECON1_TXRTS);
}


/*
函數功能:從網絡獲取一個數據包內容
函數參數:
				maxlen:數據包最大允許接收長度
				packet:數據包緩存區
返 回 值:收到的數據包長度(字節)	
*/
u32 ENC28J60_Packet_Receive(u32 maxlen,u8* packet)
{
	u32 rxstat;
	u32 len;    													 
	if(ENC28J60_Read(EPKTCNT)==0)return 0;  //是否收到數據包?	   
	//設置接收緩沖器讀指針
	ENC28J60_Write(ERDPTL,(NextPacketPtr));
	ENC28J60_Write(ERDPTH,(NextPacketPtr)>>8);	   
	// 讀下一個包的指針
	NextPacketPtr=ENC28J60_Read_Op(ENC28J60_READ_BUF_MEM,0);
	NextPacketPtr|=ENC28J60_Read_Op(ENC28J60_READ_BUF_MEM,0)<<8;
	//讀包的長度
	len=ENC28J60_Read_Op(ENC28J60_READ_BUF_MEM,0);
	len|=ENC28J60_Read_Op(ENC28J60_READ_BUF_MEM,0)<<8;
 	len-=4; //去掉CRC計數
	//讀取接收狀態
	rxstat=ENC28J60_Read_Op(ENC28J60_READ_BUF_MEM,0);
	rxstat|=ENC28J60_Read_Op(ENC28J60_READ_BUF_MEM,0)<<8;
	//限制接收長度	
	if (len>maxlen-1)len=maxlen-1;	
	//檢查CRC和符號錯誤
	// ERXFCON.CRCEN為默認設置,一般我們不需要檢查.
	if((rxstat&0x80)==0)len=0;//無效
	else ENC28J60_Read_Buf(len,packet);//從接收緩沖器中復制數據包	    
	//RX讀指針移動到下一個接收到的數據包的開始位置 
	//并釋放我們剛才讀出過的內存
	ENC28J60_Write(ERXRDPTL,(NextPacketPtr));
	ENC28J60_Write(ERXRDPTH,(NextPacketPtr)>>8);
	//遞減數據包計數器標志我們已經得到了這個包 
 	ENC28J60_Write_Op(ENC28J60_BIT_FIELD_SET,ECON2,ECON2_PKTDEC);
	return(len);
}



poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

5.3 enc28j60.h

#include "sys.h"    
#ifndef __ENC28J60_H
#define __ENC28J60_H	  
#include "stm32f10x.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ENC28J60 Control Registers
// Control register definitions are a combination of address,
// bank number, and Ethernet/MAC/PHY indicator bits.
// - Register address         (bits 0-4)
// - Bank number              (bits 5-6)
// - MAC/PHY indicator        (bit 7)
#define ADDR_MASK        0x1F
#define BANK_MASK        0x60
#define SPRD_MASK        0x80
// All-bank registers
#define EIE              0x1B
#define EIR              0x1C
#define ESTAT            0x1D
#define ECON2            0x1E
#define ECON1            0x1F
// Bank 0 registers
#define ERDPTL           (0x00|0x00)
#define ERDPTH           (0x01|0x00)
#define EWRPTL           (0x02|0x00)
#define EWRPTH           (0x03|0x00)
#define ETXSTL           (0x04|0x00)
#define ETXSTH           (0x05|0x00)
#define ETXNDL           (0x06|0x00)
#define ETXNDH           (0x07|0x00)
#define ERXSTL           (0x08|0x00)
#define ERXSTH           (0x09|0x00)
#define ERXNDL           (0x0A|0x00)
#define ERXNDH           (0x0B|0x00)
//ERXWRPTH:ERXWRPTL 寄存器定義硬件向FIFO 中
//的哪個位置寫入其接收到的字節。 指針是只讀的,在成
//功接收到一個數據包后,硬件會自動更新指針。 指針可
//用于判斷FIFO 內剩余空間的大小。
#define ERXRDPTL         (0x0C|0x00)
#define ERXRDPTH         (0x0D|0x00)
#define ERXWRPTL         (0x0E|0x00)
#define ERXWRPTH         (0x0F|0x00)
#define EDMASTL          (0x10|0x00)
#define EDMASTH          (0x11|0x00)
#define EDMANDL          (0x12|0x00)
#define EDMANDH          (0x13|0x00)
#define EDMADSTL         (0x14|0x00)
#define EDMADSTH         (0x15|0x00)
#define EDMACSL          (0x16|0x00)
#define EDMACSH          (0x17|0x00)
// Bank 1 registers
#define EHT0             (0x00|0x20)
#define EHT1             (0x01|0x20)
#define EHT2             (0x02|0x20)
#define EHT3             (0x03|0x20)
#define EHT4             (0x04|0x20)
#define EHT5             (0x05|0x20)
#define EHT6             (0x06|0x20)
#define EHT7             (0x07|0x20)
#define EPMM0            (0x08|0x20)
#define EPMM1            (0x09|0x20)
#define EPMM2            (0x0A|0x20)
#define EPMM3            (0x0B|0x20)
#define EPMM4            (0x0C|0x20)
#define EPMM5            (0x0D|0x20)
#define EPMM6            (0x0E|0x20)
#define EPMM7            (0x0F|0x20)
#define EPMCSL           (0x10|0x20)
#define EPMCSH           (0x11|0x20)
#define EPMOL            (0x14|0x20)
#define EPMOH            (0x15|0x20)
#define EWOLIE           (0x16|0x20)
#define EWOLIR           (0x17|0x20)
#define ERXFCON          (0x18|0x20)
#define EPKTCNT          (0x19|0x20)
// Bank 2 registers
#define MACON1           (0x00|0x40|0x80)
#define MACON2           (0x01|0x40|0x80)
#define MACON3           (0x02|0x40|0x80)
#define MACON4           (0x03|0x40|0x80)
#define MABBIPG          (0x04|0x40|0x80)
#define MAIPGL           (0x06|0x40|0x80)
#define MAIPGH           (0x07|0x40|0x80)
#define MACLCON1         (0x08|0x40|0x80)
#define MACLCON2         (0x09|0x40|0x80)
#define MAMXFLL          (0x0A|0x40|0x80)
#define MAMXFLH          (0x0B|0x40|0x80)
#define MAPHSUP          (0x0D|0x40|0x80)
#define MICON            (0x11|0x40|0x80)
#define MICMD            (0x12|0x40|0x80)
#define MIREGADR         (0x14|0x40|0x80)
#define MIWRL            (0x16|0x40|0x80)
#define MIWRH            (0x17|0x40|0x80)
#define MIRDL            (0x18|0x40|0x80)
#define MIRDH            (0x19|0x40|0x80)
// Bank 3 registers
#define MAADR1           (0x00|0x60|0x80)
#define MAADR0           (0x01|0x60|0x80)
#define MAADR3           (0x02|0x60|0x80)
#define MAADR2           (0x03|0x60|0x80)
#define MAADR5           (0x04|0x60|0x80)
#define MAADR4           (0x05|0x60|0x80)
#define EBSTSD           (0x06|0x60)
#define EBSTCON          (0x07|0x60)
#define EBSTCSL          (0x08|0x60)
#define EBSTCSH          (0x09|0x60)
#define MISTAT           (0x0A|0x60|0x80)
#define EREVID           (0x12|0x60)
#define ECOCON           (0x15|0x60)
#define EFLOCON          (0x17|0x60)
#define EPAUSL           (0x18|0x60)
#define EPAUSH           (0x19|0x60)
// PHY registers
#define PHCON1           0x00
#define PHSTAT1          0x01
#define PHHID1           0x02
#define PHHID2           0x03
#define PHCON2           0x10
#define PHSTAT2          0x11
#define PHIE             0x12
#define PHIR             0x13
#define PHLCON           0x14	   
// ENC28J60 ERXFCON Register Bit Definitions
#define ERXFCON_UCEN     0x80
#define ERXFCON_ANDOR    0x40
#define ERXFCON_CRCEN    0x20
#define ERXFCON_PMEN     0x10
#define ERXFCON_MPEN     0x08
#define ERXFCON_HTEN     0x04
#define ERXFCON_MCEN     0x02
#define ERXFCON_BCEN     0x01
// ENC28J60 EIE Register Bit Definitions
#define EIE_INTIE        0x80
#define EIE_PKTIE        0x40
#define EIE_DMAIE        0x20
#define EIE_LINKIE       0x10
#define EIE_TXIE         0x08
#define EIE_WOLIE        0x04
#define EIE_TXERIE       0x02
#define EIE_RXERIE       0x01
// ENC28J60 EIR Register Bit Definitions
#define EIR_PKTIF        0x40
#define EIR_DMAIF        0x20
#define EIR_LINKIF       0x10
#define EIR_TXIF         0x08
#define EIR_WOLIF        0x04
#define EIR_TXERIF       0x02
#define EIR_RXERIF       0x01
// ENC28J60 ESTAT Register Bit Definitions
#define ESTAT_INT        0x80
#define ESTAT_LATECOL    0x10
#define ESTAT_RXBUSY     0x04
#define ESTAT_TXABRT     0x02
#define ESTAT_CLKRDY     0x01
// ENC28J60 ECON2 Register Bit Definitions
#define ECON2_AUTOINC    0x80
#define ECON2_PKTDEC     0x40
#define ECON2_PWRSV      0x20
#define ECON2_VRPS       0x08
// ENC28J60 ECON1 Register Bit Definitions
#define ECON1_TXRST      0x80
#define ECON1_RXRST      0x40
#define ECON1_DMAST      0x20
#define ECON1_CSUMEN     0x10
#define ECON1_TXRTS      0x08
#define ECON1_RXEN       0x04
#define ECON1_BSEL1      0x02
#define ECON1_BSEL0      0x01
// ENC28J60 MACON1 Register Bit Definitions
#define MACON1_LOOPBK    0x10
#define MACON1_TXPAUS    0x08
#define MACON1_RXPAUS    0x04
#define MACON1_PASSALL   0x02
#define MACON1_MARXEN    0x01
// ENC28J60 MACON2 Register Bit Definitions
#define MACON2_MARST     0x80
#define MACON2_RNDRST    0x40
#define MACON2_MARXRST   0x08
#define MACON2_RFUNRST   0x04
#define MACON2_MATXRST   0x02
#define MACON2_TFUNRST   0x01
// ENC28J60 MACON3 Register Bit Definitions
#define MACON3_PADCFG2   0x80
#define MACON3_PADCFG1   0x40
#define MACON3_PADCFG0   0x20
#define MACON3_TXCRCEN   0x10
#define MACON3_PHDRLEN   0x08
#define MACON3_HFRMLEN   0x04
#define MACON3_FRMLNEN   0x02
#define MACON3_FULDPX    0x01
// ENC28J60 MICMD Register Bit Definitions
#define MICMD_MIISCAN    0x02
#define MICMD_MIIRD      0x01
// ENC28J60 MISTAT Register Bit Definitions
#define MISTAT_NVALID    0x04
#define MISTAT_SCAN      0x02
#define MISTAT_BUSY      0x01
// ENC28J60 PHY PHCON1 Register Bit Definitions
#define PHCON1_PRST      0x8000
#define PHCON1_PLOOPBK   0x4000
#define PHCON1_PPWRSV    0x0800
#define PHCON1_PDPXMD    0x0100
// ENC28J60 PHY PHSTAT1 Register Bit Definitions
#define PHSTAT1_PFDPX    0x1000
#define PHSTAT1_PHDPX    0x0800
#define PHSTAT1_LLSTAT   0x0004
#define PHSTAT1_JBSTAT   0x0002
// ENC28J60 PHY PHCON2 Register Bit Definitions
#define PHCON2_FRCLINK   0x4000
#define PHCON2_TXDIS     0x2000
#define PHCON2_JABBER    0x0400
#define PHCON2_HDLDIS    0x0100

// ENC28J60 Packet Control Byte Bit Definitions
#define PKTCTRL_PHUGEEN  0x08
#define PKTCTRL_PPADEN   0x04
#define PKTCTRL_PCRCEN   0x02
#define PKTCTRL_POVERRIDE 0x01

// SPI operation codes
#define ENC28J60_READ_CTRL_REG       0x00
#define ENC28J60_READ_BUF_MEM        0x3A
#define ENC28J60_WRITE_CTRL_REG      0x40
#define ENC28J60_WRITE_BUF_MEM       0x7A
#define ENC28J60_BIT_FIELD_SET       0x80
#define ENC28J60_BIT_FIELD_CLR       0xA0
#define ENC28J60_SOFT_RESET          0xFF

// The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata
// buffer boundaries applied to internal 8K ram
// the entire available packet buffer space is allocated
//
// start with recbuf at 0/
#define RXSTART_INIT     0x0
// receive buffer end
#define RXSTOP_INIT      (0x1FFF-1518-1)
// start TX buffer at 0x1FFF-0x0600, pace for one full ethernet frame (0~1518 bytes)
#define TXSTART_INIT     (0x1FFF-1518)
// stp TX buffer at end of mem
#define TXSTOP_INIT      0x1FFF
// max frame length which the conroller will accept:
#define   MAX_FRAMELEN    1518        // (note: maximum ethernet frame length would be 1518)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////


void ENC28J60_Reset(void);
u8 ENC28J60_Read_Op(u8 op,u8 addr);
void ENC28J60_Write_Op(u8 op,u8 addr,u8 data);
void ENC28J60_Read_Buf(u32 len,u8* data);
void ENC28J60_Write_Buf(u32 len,u8* data);
void ENC28J60_Set_Bank(u8 bank);
u8 ENC28J60_Read(u8 addr);
void ENC28J60_Write(u8 addr,u8 data);
void ENC28J60_PHY_Write(u8 addr,u32 data);
u8 ENC28J60_Init(u8* macaddr);
u8 ENC28J60_Get_EREVID(void);
void ENC28J60_Packet_Send(u32 len,u8* packet);
u32 ENC28J60_Packet_Receive(u32 maxlen,u8* packet);  
#endif
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

5.4 httpd-fs.c

/*
 * Copyright (c) 2001, Swedish Institute of Computer Science.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Institute nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * This file is part of the lwIP TCP/IP stack.
 *
 * Author: Adam Dunkels 
 *
 * $Id: httpd-fs.c,v 1.1 2006/06/07 09:13:08 adam Exp $
 */

#include "httpd.h"
#include "httpd-fs.h"
#include "httpd-fsdata.h"

#ifndef NULL
#define NULL 0
#endif /* NULL */

#include "httpd-fsdata.c"

#if HTTPD_FS_STATISTICS
static u16_t count[HTTPD_FS_NUMFILES];
#endif /* HTTPD_FS_STATISTICS */

/*-----------------------------------------------------------------------------------*/
static u8_t
httpd_fs_strcmp(const char *str1, const char *str2)
{
    u8_t i;
    i = 0;
loop:

    if(str2[i] == 0 ||
            str1[i] == 'r' ||
            str1[i] == 'n') {
        return 0;
    }

    if(str1[i] != str2[i]) {
        return 1;
    }


    ++i;
    goto loop;
}
#include 
#include 
#include "led.h"
#include "ds18b20.h"
#include "stm32f10x.h"
#include "rtc.h"

extern const unsigned char web_data[];
extern const  char led1_on[];
extern const  char led1_off[];

char ds18b20_temp[100]; //存放DS18B20溫度信息
u16 ds18b20_T;
u16 ds18b20_intT,ds18b20_decT; 	  //溫度值的整數和小數部分

/*-----------------------------------------------------------------------------------*/
int
httpd_fs_open(const char *name, struct httpd_fs_file *file)
{
 	 //第一次的默認頁面
	 if(strstr(name,"/index.html"))
	 {
		  file->data=(char*)web_data;
      file->len = sizeof(web_data);
		 	 return 1;
	 }
	 else if(strstr(name,"/404.html"))
	 {
			file->data=(char*)data_404_html;
      file->len = sizeof(data_404_html);
		 	return 0; 
	 }
	 else if(strstr(name,"/test?data=off1"))
	 {
			file->data=(char*)led1_on;
      file->len = strlen(led1_on);
		  LED1=1;
		 	return 1; 
	 }
	 else if(strstr(name,"/test?data=on1"))
	 {
			file->data=(char*)led1_off;
      file->len = strlen(led1_off);
		  LED1=0;
		 	return 1; 
	 }
	 else if(strstr(name,"/test?data=off2"))
	 {
			file->data=(char*)led1_on;
      file->len = strlen(led1_on);
		  LED2=1;
		 	return 1; 
	 }
	 else if(strstr(name,"/test?data=on2"))
	 {
			file->data=(char*)led1_off;
      file->len = strlen(led1_off);
		  LED2=0;
		 	return 1; 
	 }
	 else if(strstr(name,"/test?data=off3"))
	 {
			file->data=(char*)led1_on;
      file->len = strlen(led1_on);
		  LED3=1;
		 	return 1; 
	 }
	 else if(strstr(name,"/test?data=on3"))
	 {
			file->data=(char*)led1_off;
      file->len = strlen(led1_off);
		  LED3=0;
		 	return 1; 
	 }
	 else if(strstr(name,"/test?data=off4"))
	 {
			file->data=(char*)led1_on;
      file->len = strlen(led1_on);
		  LED4=1;
		 	return 1; 
	 }
	 else if(strstr(name,"/test?data=on4"))
	 {
			file->data=(char*)led1_off;
      file->len = strlen(led1_off);
		  LED4=0;
		 	return 1; 
	 }
	 else if(strstr(name,"/test?data=off5"))
	 {
			file->data=(char*)led1_on;
      file->len = strlen(led1_on);
		  BEEP=0;
		 	return 1; 
	 }
	 else if(strstr(name,"/test?data=on5"))
	 {
			file->data=(char*)led1_off;
      file->len = strlen(led1_off);
		  BEEP=1;
		 	return 1; 
	 }
	 else if(strstr(name,"/test?data=temp"))
	 {
		 	/*讀取溫度信息*/
			ds18b20_T=DS18B20_Get_Temp();
			ds18b20_intT = ds18b20_T >> 4;             //分離出溫度值整數部分
			ds18b20_decT = ds18b20_T & 0xF;            //分離出溫度值小數部分
		  //printf("%d-%d-%d %d:%d:%drn",rtc_time.year,rtc_time.mon,rtc_time.day,rtc_time.hour,rtc_time.min,rtc_time.sec);
		
		  sprintf(ds18b20_temp,"%d.%d&%d-%d-%d %d:%d:%d",ds18b20_intT,ds18b20_decT,rtc_time.year,rtc_time.mon,rtc_time.day,rtc_time.hour,rtc_time.min,rtc_time.sec);
			file->data=(char*)ds18b20_temp;
      file->len = strlen(ds18b20_temp);
		 	return 1; 
	 }
   return 0;
}

/*-----------------------------------------------------------------------------------*/
void
httpd_fs_init(void)
{
#if HTTPD_FS_STATISTICS
    u16_t i;
    for(i = 0; i < HTTPD_FS_NUMFILES; i++) {
        count[i] = 0;
    }
#endif /* HTTPD_FS_STATISTICS */
}
/*-----------------------------------------------------------------------------------*/
#if HTTPD_FS_STATISTICS
u16_t httpd_fs_count
(char *name)
{
    struct httpd_fsdata_file_noconst *f;
    u16_t i;

    i = 0;
    for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT;
            f != NULL;
            f = (struct httpd_fsdata_file_noconst *)f->next) {

        if(httpd_fs_strcmp(name, f->name) == 0) {
            return count[i];
        }
        ++i;
    }
    return 0;
}
#endif /* HTTPD_FS_STATISTICS */
/*-----------------------------------------------------------------------------------*/
@sics.se>
poYBAGDYdXCAWkKMAAAAK8RNs4s030.png

審核編輯:湯梓紅

?

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 服務器
    +關注

    關注

    12

    文章

    9225

    瀏覽量

    85616
  • STM32
    +關注

    關注

    2270

    文章

    10906

    瀏覽量

    356530
  • TCP
    TCP
    +關注

    關注

    8

    文章

    1370

    瀏覽量

    79135
收藏 人收藏

    評論

    相關推薦

    服務器如何處理 HTTP 請求

    請求。這是服務器等待接收HTTP請求的第一步。 接受連接 :當客戶端(如Web瀏覽)發起連接請求時,服務器接受該連接,并創建一個新的套接字來處理該連接。這個套接字將用于后續的通信。
    的頭像 發表于 12-30 09:37 ?97次閱讀

    Tomcat開放源代碼的Web應用服務器

    Tomcat 簡介 Tomcat 服務器是一個免費的開放源代碼的Web 應用服務器,屬于輕量級應用服務器,在中小型系統和并發訪問用戶不是很多的場合下被普遍使用,是開發和調試JSP 程序
    的頭像 發表于 12-23 11:24 ?213次閱讀
    Tomcat開放源代碼的<b class='flag-5'>Web</b>應用<b class='flag-5'>服務器</b>

    nginx隱藏版本號與WEB服務器信息

    nginx不僅可以隱藏版本信息,還支持自定義web服務器信息 先看看最終的隱藏結果吧 具體怎么實現呢,其實也很簡單,請往下看 1 官網下載最新穩定版 wget http://nginx.org
    的頭像 發表于 11-22 10:25 ?185次閱讀
    nginx隱藏版本號與<b class='flag-5'>WEB</b><b class='flag-5'>服務器</b>信息

    使用zabbix監控云服務器的方法

    Zabbix環境 在開始監控云服務器之前,你需要準備Zabbix環境。這包括安裝Zabbix服務器、Zabbix代理和配置Web界面。 2.1 安裝Zabbix服務器 Zabbix
    的頭像 發表于 11-08 10:47 ?277次閱讀

    獨立服務器與云服務器的區別

    隨著互聯網技術的飛速發展,企業對于服務器的需求日益增加,而服務器市場也隨之出現了多種類型的產品,其中最常見的是獨立服務器和云服務器。這兩種服務器
    的頭像 發表于 10-12 14:34 ?286次閱讀

    使用NS1串口服務器HTTP模式上傳服務器數據

    HTTP協議工作于客戶端-服務端架構之上。瀏覽作為HTTP客戶端通過URL向HTTP服務端即Web服務器發送所有請求。
    的頭像 發表于 08-30 12:36 ?390次閱讀
    使用NS1串口<b class='flag-5'>服務器</b>HTTP模式上傳<b class='flag-5'>服務器</b>數據

    如何使用espconn api實現一個Web服務器

    我正在嘗試使用 espconn api 實現一個 Web 服務器。 在一些請求之后,我收到將此錯誤(err1,超過最大時間值)寫入 uart,下一個espconn_send導致致命異常 (28)。 沒有關于此的文檔... 我該如何解決這個問題?
    發表于 07-18 07:46

    將ESP8266配置為帶有AT命令的Web服務器,AT命令回復HTTP GET出現錯誤怎么解決?

    我已將ESP8266配置為帶有 AT 命令的 Web 服務器。當瀏覽連接時,它會向我發送一個請求[i]GET /favicon.ico我想用一個[i]錯誤 404 未找到. 如何在響應 IPD 時發送的數據包中執行此操作?
    發表于 07-16 08:29

    服務器和虛擬服務器的區別是什么

    服務器和虛擬服務器是兩種常見的服務器類型,它們在很多方面有相似之處,但也有一些關鍵的區別。本文將詳細介紹云服務器和虛擬服務器的區別,包括它
    的頭像 發表于 07-02 09:48 ?847次閱讀

    通過STM32+ESP8266 Wifi模塊 +云服務器,做一個數據收發控制的板子云服務器方面該如何選擇?

    通過STM32+ESP8266 Wifi模塊 +云服務器 做一個數據收發控制的板子 云服務器方面該如何選擇?
    發表于 04-25 08:16

    服務器操作系統有幾種?

    web版適用2G運行內存,都是添加4G運 行內存也只有鑒別2G,中小型企業大多數應用標準版,要是想布署集群服務器必須使用商業版。 2、Windows 2008 Windows server 2008
    發表于 03-29 16:59

    linux服務器和windows服務器

    Linux服務器和Windows服務器是目前應用最廣泛的兩種服務器操作系統。兩者各有優劣,也適用于不同的應用場景。本文將 對Linux服務器和Windows
    發表于 02-22 15:46

    服務器連接應用解決方案

    、ATM等終端,甚至包括火車系統等大型設備)提供計算或應用服務。根據服務器所提供的服務類型,可以分為多種形式,如文件服務器、數據庫服務器應用
    的頭像 發表于 02-19 12:38 ?288次閱讀
    <b class='flag-5'>服務器</b>連接應用解決方案

    Apache服務器和Nginx服務器

    Apache和Nginx都是常見的開源Web服務器軟件,它們用于處理HTTP請求并提供網站和應用程序的服務。下面是對Apache和Nginx的一些基本特點的比較: 一、Apache HTTP
    的頭像 發表于 01-22 16:48 ?577次閱讀

    獨立服務器和云服務器的區別

    獨立服務器和云服務器的區別是很多用戶在選擇服務器時要做的課程,那么獨立服務器和云服務器的區別有哪些呢?
    的頭像 發表于 01-17 10:58 ?880次閱讀
    主站蜘蛛池模板: 中文字幕在线观看亚洲| 国产毛片视频网站| 毛片亚洲毛片亚洲毛片| JIZJIZJIZ 日本老师水多| 日韩精品在线观看免费| 国产精品国产三级国AV在线观看| 亚洲精品第五页中文字幕| 久久中文字幕无线观看| xxxx免费观看| 亚洲免费每日在线观看| 年轻漂亮的妺妺中文字幕版| 国产成人高清亚洲一区app| 亚洲免费中文| 欧美无码专区| 国产性夜夜性夜夜爽91| ass女人下部欣赏| 亚洲AV噜噜狠狠网址蜜桃尤物| 美女岔开腿露出粉嫩花苞| 国产99视频在线观看| 伊人电院网| 天堂精品国产自在自线| 一个人日本的视频免费完整版 | 麻豆精品传媒2021网站入口| 儿子好妈妈的HD3中字抢劫| 一个人免费播放高清在线观看| 青青草原在线新免费| 久久AV喷吹AV高潮欧美| 国产高清美女一级毛片久久 | 高hbl双性浪荡古代| 中文字幕乱码一区AV久久| 婷婷四房播客五月天| 免费毛片网站在线观看| 韩国伦理片2018在线播放免费观看| 99手机在线视频| 伊伊人成亚洲综合人网| 四虎精品久久久久影院| 欧美黑人经典片免费观看| 久久精品AV无码亚洲色欲| 国产免费午夜高清| 俄罗斯6一12呦女精品| 99热这里只有精品88|