單片機聯網,UIP實現tcp/udp協議

UIP是單片機界聯網的一個很好地選擇,移植這個庫有點複雜,首先是第一步,網卡驅動要寫好,使用的網卡芯片爲ENC28J60,驅動能夠再工程包裏面找到數組

//配置網卡硬件,並設置MAC地址 
//返回值:0,正常;1,失敗;
u8 tapdev_init(u8* macaddr)
{        
    u8 i,res=0;                      
    res=ENC28J60_Init((u8*)macaddr);    //初始化ENC28J60                      
    //把IP地址和MAC地址寫入緩存區
     for (i = 0; i < 6; i++)uip_ethaddr.addr[i]=macaddr[i];  
    //指示燈狀態:0x476 is PHLCON LEDA(綠)=links status, LEDB(紅)=receive/transmit
     //PHLCON:PHY 模塊LED 控制寄存器        
    ENC28J60_PHY_Write(PHLCON,0x0476);
    return res;    
}


//讀取一包數據  
uint16_t tapdev_read(void)
{    
    return  ENC28J60_Packet_Receive(MAX_FRAMELEN,uip_buf);
}


//發送一包數據  
void tapdev_send(void)
{
    ENC28J60_Packet_Send(uip_len,uip_buf);
}

分別是初始化,讀,寫緩存

這些驅動會在一個叫作uip_call的函數中用到,其次,要設置uip的時鐘,這個時鐘適用於arp表的更新的服務器

#include "clock-arch.h"
#include "sys.h" 


//時鐘驅動文件,

//uip時鐘
extern u32 uip_timer;//uip 計時器,每10ms增長1.
/*---------------------------------------------------------------------------*/
clock_time_t
clock_time(void)
{
    return uip_timer; /* 10ms 單位 */     
}
u32 uip_timer=0;//uip 計時器,每10ms增長1.

//定時器6中斷服務程序     
void TIM6_IRQHandler(void)
{     if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) //檢查指定的TIM中斷髮生與否:TIM 中斷源 
    {
      uip_timer++;//uip計時器增長1    
    } 
        TIM_ClearITPendingBit(TIM6, TIM_IT_Update  );  //清除TIMx的中斷待處理位:TIM 中斷源 
                                                      
}
 
//基本定時器6中斷初始化
//這裏時鐘選擇爲APB1的2倍,而APB1爲36M
//arr:自動重裝值。
//psc:時鐘預分頻數
//這裏使用的是定時器3!
void TIM6_Int_Init(u16 arr,u16 psc)
{    
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //時鐘使能

    TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器週期的值     計數到5000爲500ms
    TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來做爲TIMx時鐘頻率除數的預分頻值  10Khz的計數頻率  
    TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計數模式
    TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位
 
    TIM_ITConfig( TIM6,TIM_IT_Update|TIM_IT_Trigger,ENABLE);//使能定時器6更新觸發中斷
 
    TIM_Cmd(TIM6, ENABLE);  //使能TIMx外設
     
      NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;  //TIM3中斷
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先佔優先級0級
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //從優先級3級
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    NVIC_Init(&NVIC_InitStructure);  //根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器                                  
}

定時器的定時長度取決於這個宏定義網絡

#ifndef __CLOCK_ARCH_H__
#define __CLOCK_ARCH_H__

typedef int clock_time_t;
#define CLOCK_CONF_SECOND 100

#endif /* __CLOCK_ARCH_H__ */

上面是100,也就是說定時器的長度應該是10MS架構

接下來是配置回調函數app

//uip事件處理函數
//必須將該函數插入用戶主循環,循環調用.
void uip_polling(void)
{
    u8 i;
    static struct timer periodic_timer, arp_timer;
    static u8 timer_ok=0;     
    if(timer_ok==0)//僅初始化一次
    {
        timer_ok = 1;
        timer_set(&periodic_timer,CLOCK_SECOND/2);  //建立1個0.5秒的定時器 
        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(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 (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發送     
        }
    }else if(timer_expired(&periodic_timer))    //0.5秒定時器超時
    {
        timer_reset(&periodic_timer);        //復位0.5秒定時器 
        //輪流處理每一個TCP鏈接, UIP_CONNS缺省是40個  
        for(i=0;i<UIP_CONNS;i++)
        {
            uip_periodic(i);    //處理TCP通訊事件  
             //當上面的函數執行後,若是須要發送數據,則全局變量uip_len>0
            //須要發送的數據在uip_buf, 長度是uip_len (這是2個全局變量)
             if(uip_len>0)
            {
                uip_arp_out();//加以太網頭結構,在主動鏈接時可能要構造ARP請求
                tapdev_send();//發送數據到以太網
            }
        }
#if UIP_UDP    //UIP_UDP 
        //輪流處理每一個UDP鏈接, UIP_UDP_CONNS缺省是10個
        for(i=0;i<UIP_UDP_CONNS;i++)
        {
            uip_udp_periodic(i);    //處理UDP通訊事件
             //當上面的函數執行後,若是須要發送數據,則全局變量uip_len>0
            //須要發送的數據在uip_buf, 長度是uip_len (這是2個全局變量)
            if(uip_len > 0)
            {
                uip_arp_out();//加以太網頭結構,在主動鏈接時可能要構造ARP請求
                tapdev_send();//發送數據到以太網
            }
        }
#endif 
        //每隔10秒調用1次ARP定時器函數 用於按期ARP處理,ARP表10秒更新一次,舊的條目會被拋棄
        if(timer_expired(&arp_timer))
        {
            timer_reset(&arp_timer);
            uip_arp_timer();
        }
    }
}

這個函數是uip的靈魂,能夠說所有的功能都是在這個函數裏面實現的,而後定義網卡數據回調函數框架

//通訊程序狀態字(用戶能夠本身定義)  
enum
{
    STATE_CMD        = 0,    //命令接收狀態 
    STATE_TX_TEST    = 1,    //連續發送數據包狀態(速度測試)  
    STATE_RX_TEST    = 2        //連續接收數據包狀態(速度測試)  
};    


//定義 uip_tcp_appstate_t 數據類型,用戶能夠添加應用程序須要用到
//成員變量。不要更改結構體類型的名字,由於這個類型名會被uip引用。
//uip.h 中定義的     struct uip_conn  結構體中引用了 uip_tcp_appstate_t          
struct tcp_appstate
{
    u8_t state;
    u8_t *textptr;
    int textlen;
};    

struct uip_appstate
{
    u8_t state;
    u8_t *textptr;
    int textlen;
};    

typedef struct tcp_appstate uip_tcp_appstate_t;
typedef struct uip_appstate uip_udp_appstate_t;

//TCP的回調
void tcp_appcall(void);
void tcp_client_appcall(void);    //tcp客戶端的回調,PC是服務器
void tcp_server_appcall(void);    //tcp服務器的回調,pc是客戶端


//UDP的回調
void udp_appcall(void);
void udp_send_appcall(void);
void udp_recv_appcall(void);

//定義應用程序回調函數 
#ifndef UIP_APPCALL
#define UIP_APPCALL tcp_appcall //定義回調函數爲 tcp_demo_appcall 
#endif

#ifndef UIP_UDP_APPCALL
#define UIP_UDP_APPCALL udp_appcall //定義回調函數爲 udp_demo_appcall 
#endif

UIP_UDP_APPCALL和UIP_APPCALL分別是TCP通信和udp通信的回調函數,實現的架構以下tcp

//TCP應用接口函數(UIP_APPCALL)
//完成TCP服務(包括server和client)和HTTP服務
void tcp_appcall(void)
{    
      
    switch(uip_conn->lport)//本地監聽端口對應的事件處理程序 
    {
        case HTONS(80):
//            httpd_appcall(); 
            break;
        case HTONS(1200):
            tcp_server_appcall(); 
            break;
        default:                          
            break;
    }            
    switch(uip_conn->rport)    //遠程鏈接1400端口
    {
        case HTONS(1400):    //遠程鏈接端口號
            tcp_client_appcall();
           break;
        default: 
           break;
    }   
}

void udp_appcall(void)
{

    switch(uip_udp_conn->lport)//本地監聽端口1600 
    {
        case HTONS(1600):
            udp_recv_appcall(); 
            break;
        default:                          
            break;
    }            
    switch(uip_udp_conn->rport)    //遠程鏈接1500端口,也就是數據發送端
    {
        case HTONS(1500):
            udp_send_appcall();
           break;
        default: 
           break;
    }   
}

能夠看到,處理過程是分端口處理的,分別是四個,TCP客戶端,服務器,UDP客戶端,UDP服務器,分別說明函數

tcp_client_connect();                   //嘗試鏈接到TCP Server端,用於TCP Client
u8 tcp_client_databuf[200];       //發送數據緩存

u8 tcp_client_sta;                //客戶端狀態
//[7]:0,無鏈接;1,已經鏈接;
//[6]:0,無數據;1,收到客戶端數據
//[5]:0,無數據;1,有數據須要發送



//這是一個TCP 客戶端應用回調函數。
//該函數經過UIP_APPCALL(tcp_demo_appcall)調用,實現Web Client的功能.
//當uip事件發生時,UIP_APPCALL函數會被調用,根據所屬端口(1400),肯定是否執行該函數。
//例如 : 當一個TCP鏈接被建立時、有新的數據到達、數據已經被應答、數據須要重發等事件
void tcp_client_appcall(void)
{          
     struct tcp_appstate *s = (struct tcp_appstate *)&uip_conn->appstate;
    if(uip_aborted())tcp_client_aborted();        //鏈接終止       
    if(uip_timedout())tcp_client_timedout();    //鏈接超時   
    if(uip_closed())tcp_client_closed();        //鏈接關閉       
     if(uip_connected())tcp_client_connected();    //鏈接成功        
    if(uip_acked())tcp_client_acked();            //發送的數據成功送達 
     //接收到一個新的TCP數據包 
    if (uip_newdata())
    {
        if((tcp_client_sta&(1<<6))==0)//還未收到數據
        {
            if(uip_len>199)
            {           
                ((u8*)uip_appdata)[199]=0;
            }            
            strcpy((char*)tcp_client_databuf,uip_appdata);                                   
            tcp_client_sta|=1<<6;//表示收到客戶端數據
        }                  
    }else if(tcp_client_sta&(1<<5))//有數據須要發送
    {
        s->textptr=tcp_client_databuf;
        s->textlen=strlen((const char*)tcp_client_databuf);
        tcp_client_sta&=~(1<<5);//清除標記
    }  
    //當須要重發、新數據到達、數據包送達、鏈接創建時,通知uip發送數據 
    if(uip_rexmit()||uip_newdata()||uip_acked()||uip_connected()||uip_poll())
    {
        tcp_client_senddata();
    }                                               
}


//這裏咱們假定Server端的IP地址爲:192.168.1.101
//這個IP必須根據Server端的IP修改.
//嘗試從新鏈接
void tcp_client_connect()
{
    uip_ipaddr_t ipaddr;
    uip_ipaddr(&ipaddr,192,168,1,100);    //設置IP爲192.168.1.103
    uip_connect(&ipaddr,htons(1400));     //端口爲1400
}




//終止鏈接,回調函數                    
void tcp_client_aborted(void)
{
    tcp_client_sta&=~(1<<7);    //標誌沒有鏈接
    tcp_client_connect();        //嘗試從新鏈接
    uip_log("tcp_client aborted!\r\n");//打印log
}


//鏈接超時,回調函數    
void tcp_client_timedout(void)
{
    tcp_client_sta&=~(1<<7);    //標誌沒有鏈接       
    uip_log("tcp_client timeout!\r\n");//打印log
}


//鏈接關閉,回調函數
void tcp_client_closed(void)
{
    tcp_client_sta&=~(1<<7);    //標誌沒有鏈接
    tcp_client_connect();        //嘗試從新鏈接
    uip_log("tcp_client closed!\r\n");//打印log
}    


//鏈接創建,回調函數
void tcp_client_connected(void)
{ 
     tcp_client_sta|=1<<7;        //標誌鏈接成功
      uip_log("tcp_client connected!\r\n");//打印log      
}


//發送的數據成功送達
void tcp_client_acked(void)
{                                                
    struct tcp_appstate *s=(struct tcp_appstate *)&uip_conn->appstate;
    s->textlen=0;//發送清零
    uip_log("tcp_client acked!\r\n");//表示成功發送         
}


//發送數據給服務端
void tcp_client_senddata(void)
{
    struct tcp_appstate *s = (struct tcp_appstate *)&uip_conn->appstate;
    //s->textptr:發送的數據包緩衝區指針
    //s->textlen:數據包的大小(單位字節)           
    if(s->textlen>0)uip_send(s->textptr, s->textlen);//發送TCP數據包     
}

TCP客戶端的使用如上,服務器的使用以下測試

uip_listen(HTONS(1200));            //監聽1200端口,用於TCP Server

監聽端口,天然就是服務器了,回調以下

  
u8 tcp_server_databuf[200];       //發送數據緩存      
u8 tcp_server_sta;                //服務端狀態
//[7]:0,無鏈接;1,已經鏈接;
//[6]:0,無數據;1,收到客戶端數據
//[5]:0,無數據;1,有數據須要發送

        
//這是一個TCP 服務器應用回調函數。
//該函數經過UIP_APPCALL(tcp_demo_appcall)調用,實現Web Server的功能.
//當uip事件發生時,UIP_APPCALL函數會被調用,根據所屬端口(1200),肯定是否執行該函數。
//例如 : 當一個TCP鏈接被建立時、有新的數據到達、數據已經被應答、數據須要重發等事件
void tcp_server_appcall(void)
{
     struct tcp_appstate *s = (struct tcp_appstate *)&uip_conn->appstate;
    if(uip_aborted())tcp_server_aborted();        //鏈接終止
     if(uip_timedout())tcp_server_timedout();    //鏈接超時   
    if(uip_closed())tcp_server_closed();        //鏈接關閉       
     if(uip_connected())tcp_server_connected();    //鏈接成功        
    if(uip_acked())tcp_server_acked();            //發送的數據成功送達 
    //接收到一個新的TCP數據包 
    if (uip_newdata())//收到客戶端發過來的數據
    {
        if((tcp_server_sta&(1<<6))==0)//還未收到數據
        {
            if(uip_len>199)
            {           
                ((u8*)uip_appdata)[199]=0;
            }            
            strcpy((char*)tcp_server_databuf,uip_appdata);                                   
            tcp_server_sta|=1<<6;//表示收到客戶端數據
        }
    }else if(tcp_server_sta&(1<<5))//有數據須要發送
    {
        s->textptr=tcp_server_databuf;
        s->textlen=strlen((const char*)tcp_server_databuf);
        tcp_server_sta&=~(1<<5);//清除標記
    }   
    //當須要重發、新數據到達、數據包送達、鏈接創建時,通知uip發送數據 
    if(uip_rexmit()||uip_newdata()||uip_acked()||uip_connected()||uip_poll())
    {
        tcp_server_senddata();
    }
}    


//終止鏈接                    
void tcp_server_aborted(void)
{
    tcp_server_sta&=~(1<<7);    //標誌沒有鏈接
    uip_log("tcp_server aborted!\r\n");//打印log
}


//鏈接超時
void tcp_server_timedout(void)
{
    tcp_server_sta&=~(1<<7);    //標誌沒有鏈接
    uip_log("tcp_server timeout!\r\n");//打印log
}


//鏈接關閉
void tcp_server_closed(void)
{
    tcp_server_sta&=~(1<<7);    //標誌沒有鏈接
    uip_log("tcp_server closed!\r\n");//打印log
}


//鏈接創建
void tcp_server_connected(void)
{                                  
//    struct tcp_appstate *s = (struct tcp_appstate *)&uip_conn->appstate;
    //uip_conn結構體有一個"appstate"字段指向應用程序自定義的結構體。
    //聲明一個s指針,是爲了便於使用。
     //不須要再單獨爲每一個uip_conn分配內存,這個已經在uip中分配好了。
    //在uip.c 中 的相關代碼以下:
    //        struct uip_conn *uip_conn;
    //        struct uip_conn uip_conns[UIP_CONNS]; //UIP_CONNS缺省=10
    //定義了1個鏈接的數組,支持同時建立幾個鏈接。
    //uip_conn是一個全局的指針,指向當前的tcp或udp鏈接。
    tcp_server_sta|=1<<7;        //標誌鏈接成功
      uip_log("tcp_server connected!\r\n");//打印log
} 


//發送的數據成功送達
void tcp_server_acked(void)
{                                 
    struct tcp_appstate *s=(struct tcp_appstate *)&uip_conn->appstate;
    s->textlen=0;//發送清零
    uip_log("tcp_server acked!\r\n");//表示成功發送         
}


//發送數據給客戶端
void tcp_server_senddata(void)
{
    struct tcp_appstate *s = (struct tcp_appstate *)&uip_conn->appstate;
    //s->textptr : 發送的數據包緩衝區指針
    //s->textlen :數據包的大小(單位字節)           
    if(s->textlen>0)uip_send(s->textptr, s->textlen);//發送TCP數據包     
}

到此,TCP結束,另外,在UIP的初始化的時候要指明IP地址網關子網掩碼子類的,以下

//配置IP地址
    uip_ipaddr(ipaddr, 192,168,1,103);    //設置本地設置IP地址
    uip_sethostaddr(ipaddr);                        
    uip_ipaddr(ipaddr, 192,168,1,1);     //設置網關IP地址(其實就是你路由器的IP地址)
    uip_setdraddr(ipaddr);                         
    uip_ipaddr(ipaddr, 255,255,255,0);    //設置網絡掩碼
    uip_setnetmask(ipaddr);

而UDP的通信是無鏈接的,不分客戶端和服務器,只分爲接收端和發送端,接收端以下

u8 udp_recv_databuf[200];       //發送數據緩存      
u8 udp_recv_sta;                //客戶端狀態

void udp_recv_appcall(void)
{
//    struct uip_appstate *s = (struct uip_appstate *)&uip_udp_conn->appstate;
    
    //接收到一個新的udp數據包 
    if (uip_newdata())//收到客戶端發過來的數據
    {
        if((udp_recv_sta&(1<<6))==0)//還未收到數據
        {
            if(uip_len>199)
            {           
                ((u8*)uip_appdata)[199]=0;
            }            
            strcpy((char*)udp_recv_databuf,uip_appdata);                                   
            udp_recv_sta|=1<<6;//表示收到客戶端數據
        }
    }
    if(uip_poll())//udp空轉
    {
        uip_log("udp_server uip_poll!\r\n");//打印log  
    }
}


//創建UDP接收連接
//創建UDP服務器須要將目標IP設置爲全1 並對應端口爲0,綁定相應的數據端口
void udp_recv_connect(void)
{
    uip_ipaddr_t ipaddr;
    static struct uip_udp_conn *c=0;    
    uip_ipaddr(&ipaddr,0xff,0xff,0xff,0xff);    //將遠程IP設置爲 255.255.255.255 具體原理見uip.c的源碼
    if(c!=0)    //已經創建鏈接則刪除鏈接
    {                            
        uip_udp_remove(c);
    }
    c = uip_udp_new(&ipaddr,0);     //遠程端口爲0
    if(c)
    {
        uip_udp_bind(c, HTONS(1600));
    }
}

其回調函數不發送數據,只接收數據,發送端以下

u8 udp_send_databuf[200];       //發送數據緩存    
u8 udp_send_sta;                //發送端狀態


//這是一個udp 發送端應用回調函數。
//該函數經過UIP_APPCALL(udp_demo_appcall)調用,實現Web Client的功能.
//當uip事件發生時,UIP_APPCALL函數會被調用,根據所屬端口(1400),肯定是否執行該函數。
//例如 : 當一個udp鏈接被建立時、有新的數據到達、數據已經被應答、數據須要重發等事件
void udp_send_appcall(void)
{         
     struct uip_appstate *s = (struct uip_appstate *)&uip_udp_conn->appstate;
    
    if(uip_poll())//當前鏈接空閒輪訓
    {    
        uip_log("udp_send uip_poll!\r\n");//打印log
        if(udp_send_sta&(1<<5))//須要發送數據
        { 
                s->textptr=udp_send_databuf;
                s->textlen=strlen((const char*)udp_send_databuf);
                udp_send_sta&=~(1<<5);//清除標記
                uip_send(s->textptr, s->textlen);//發送udp數據包    
                uip_udp_send(s->textlen);
        }

    }
    
}

//創建一個udp_client的鏈接
void udp_send_connect()
{
    uip_ipaddr_t ipaddr;
    static struct uip_udp_conn *c=0;    
    uip_ipaddr(&ipaddr,192,168,1,101);    //設置IP爲192.168.1.101
    if(c!=0)
    {                            //已經創建鏈接則刪除鏈接
        uip_udp_remove(c);
    }
    c = uip_udp_new(&ipaddr,htons(1500));     //端口爲1500
    //發送端發送的數據端口爲1500
}

只發送數據不接收數據

基本上到這裏整個程序的框架就作好了,測試用的一段代碼也貼上來

uip_polling();    //處理uip事件,必須插入到用戶程序的循環體中
        if(tcp_client_tsta!=tcp_client_sta)//TCP Client狀態改變
        {                                                             
            if(tcp_client_sta&(1<<7))
                LCD_ShowString(0,12,240,320,(u8*)"TCP Client Connected              ",LCD_BLACK);
            else
                LCD_ShowString(0,12,240,320,(u8*)"TCP Client Disconnected              ",LCD_BLACK);
            if(tcp_client_sta&(1<<6))    //收到新數據
            {
                LCD_ShowString(18,24,240,320,(u8*)"                                     ",LCD_BLACK);
                LCD_ShowString(18,24,240,320,(u8*)tcp_client_databuf,LCD_BLACK);
                printf("TCP Client RX:%s\r\n",tcp_client_databuf);//打印數據
                tcp_client_sta&=~(1<<6);        //標記數據已經被處理    
            }
            tcp_client_tsta=tcp_client_sta;
        }
        
        if(tcp_server_tsta!=tcp_server_sta)//TCP Server狀態改變
        {        
            if(tcp_server_sta&(1<<7))
                LCD_ShowString(0,48,240,320,(u8*)"TCP Server Connected              ",LCD_BLACK);
            else 
                LCD_ShowString(0,48,240,320,(u8*)"TCP Server Disconnected           ",LCD_BLACK);
            if(tcp_server_sta&(1<<6))    //收到新數據
            {
                LCD_ShowString(18,60,240,320,(u8*)"                                     ",LCD_BLACK);
                LCD_ShowString(18,60,240,320,(u8*)tcp_server_databuf,LCD_BLACK);
                printf("TCP Server RX:%s\r\n",tcp_server_databuf);//打印數據
                tcp_server_sta&=~(1<<6);        //標記數據已經被處理    
            }
            tcp_server_tsta=tcp_server_sta;
        }
        if(udp_recv_sta & (1<<6))
        {
            LCD_ShowString(18,120,240,320,(u8*)"                                     ",LCD_BLACK);
            LCD_ShowString(18,120,240,320,(u8*)udp_recv_databuf,LCD_BLACK);
            udp_recv_sta =~(1<<6);//標記數據已經被處理
        }
        
        if(keyValue == KEY_LEFT)
        {
            if(tcp_client_sta&(1<<7))    //鏈接還存在
            {
                sprintf((char*)tcp_client_databuf,"TCP Client OK %d\r\n",tclientcnt);    
                LCD_ShowString(24,36,240,320,(u8*)"                                     ",LCD_BLACK);
                LCD_ShowString(24,36,240,320,(u8*)tcp_client_databuf,LCD_BLACK);
                tcp_client_sta|=1<<5;//標記有數據須要發送
                tclientcnt++;
                keyValue = 0;
            }
        }
        if(keyValue == KEY_RIGHT)
        {
            if(tcp_server_sta&(1<<7))    //鏈接還存在
            {
                sprintf((char*)tcp_server_databuf,"TCP Server OK %d\r\n",tserivcecnt);     
                LCD_ShowString(24,72,240,320,(u8*)"                                     ",LCD_BLACK);
                LCD_ShowString(24,72,240,320,(u8*)tcp_server_databuf,LCD_BLACK);
                tcp_server_sta|=1<<5;//標記有數據須要發送
                tserivcecnt++;
                keyValue = 0;
            }
        }
        if(keyValue == KEY_DOWN)
        {
            sprintf((char*)udp_send_databuf,"UDP SEND OK %d\r\n",usendcnt);
            LCD_ShowString(18,96,240,320,(u8*)"                                     ",LCD_BLACK);
            LCD_ShowString(18,96,240,320,(u8*)udp_send_databuf,LCD_BLACK);
            udp_send_sta |= 1<<5;//標記有數據須要發送
            keyValue = 0;
            usendcnt++;
        }
    }


下一章再說說怎麼實現DHCP

 工程下載地址

http://download.csdn.net/detail/dengrengong/8542905
相關文章
相關標籤/搜索