天天看點

物聯網綜合練習之單片機TCP伺服器

/*************************************************************************************************

PROJECT:     wifi遙控小車

HARDWARE:    STC89C52RC單機, L239D直流電機驅動器, ESP8266安信可wifi子產品

SOFTWARE:    Eclipse安卓開發環境

AUTHOR:       DDDDD

DATE:         2014-12-5

*************************************************************************************************/

本章介紹,如何利用wifi子產品在單片機上建立TCP伺服器,進而用android用戶端來操作單片機。wifi子產品采用安信可ESP8266,

價格低,性能穩定。通過序列槽傳輸與單片機通信,波特率115200

物聯網綜合練習之單片機TCP伺服器

1、STC89C52RC單片機波特率設定,由于波特率為115200,這個傳輸速率已經非常高,必須用T2定時器作為波特率發生器

    波特率:序列槽每秒鐘發送或者接收的位數,

    設發送一位需要的時間是T,則波特率buad=1/T

    序列槽發送條件:向SBUF寫入資料,則立馬回發送

                 發送完成後 TI 由硬體置1,需要手動清0

    序列槽接受收件:REN = 1,允許接收

                 RI = 0;

    接收完畢後RI會由硬體置1,需要手動清零

    序列槽初始化配置: 

點選(此處)折疊或打開

void serial_init()

{

    EA = 0;                //關閉所有中斷

    SCON = 0x40;           //工作方式 1, 8位異步串行收發,波特率由定時器 1 控制

    PCON = 0;

    RCAP2H = 0xff;

    RCAP2L = 0xfd;         //方式1和方式3的波特率=fosc/(32-(65535-(RCAP2H,RCAP2L))

    TH2=0xFF;

    TL2=0xFD;              //設定波特率為115200

    T2CON=0x34;            //将定時器2設定為波特率發生器(接收和發送都用Timer2)

    ET2 = 0;               //關閉定時器1中斷

    TI = 0;

    RI = 0;

    REN = 1;               //允許接收

    ES = 1;                //開啟序列槽中斷

    EA = 1;                //開啟總中斷

    TR2 = 1;               //開啟定時器 2

}

2、直流電機驅動晶片L293D

物聯網綜合練習之單片機TCP伺服器

    L293D是一款典型的直流電機控制晶片,可以很輕松的控制電機的正反轉。IN1、IN2、IN3、IN4是輸入引腳,對應的輸出引腳是

    OUT1、OUT2、OUT3、OUT4。EN1是1、2号引腳的是能控制端,EN2是3、4号引腳的是能控制端,高電平是能。當輸入為1時,輸出

    為0;當輸入為0時,輸出為1。

3、單片機供電部分:

   采用兩節3.7v锂電池串聯供電,7805輸出5v穩壓給單片機供電,直流電機直接由7.4v供電。必要說明:單片機和直流電機分别用倆

   組電池供電,因為直流電機在啟動時會将電池電壓拉低,如果用同一組電池供電,單片機會複位。 

物聯網綜合練習之單片機TCP伺服器
物聯網綜合練習之單片機TCP伺服器

4、ESP8266WIFI子產品

   子產品已經內建一些指令,采用序列槽通訊将指令發送過去,子產品就會有相應的響應,ESP8266指令集: 

9、AT+CWMODE=3            設定為模式3

        OK

10、AT+RST                重新開機生效

11、AT+CIPMUX=1            開啟多連結

12、AT+CIPSERVER=1,8765 配置為TCP伺服器,端口号8765

13、AT+CIPSTO=600        設定逾時時間

以上是需要發送的指令,當上述操作完成之後,就可以等待android用戶端的指令了,下面是子產品收到一條指令的格式

14、+IPD,7:hello

    OK                   收到資料hello

   必要說明:給子產品發送指令時,必須以回車符作為結尾,否則子產品無響應。是以在序列槽發送資料的時候,采用十六進制發送。

            當子產品收到指令時,會将指令通過序列槽發送給MCU,發送的格式

        +IPD,7:hello

        OK   

           這代表收到伺服器的資料hello    

5、源代碼

   car.h

#include reg52.h>

sbit zq1 = P0^0;

sbit zq2 = P0^1;

sbit yq1 = P0^2;

sbit yq2 = P0^3;

sbit zh1 = P0^4;

sbit zh2 = P0^5;

sbit yh1 = P0^6;

sbit yh2 = P0^7;

#define FAN_ZHUAN {zq1 = 1; zq2 = 0; yq1 = 1; yq2 = 0; zh1 = 1; zh2 = 0; yh1 = 1; yh2 = 0;}

#define ZHENG_ZHUAN {zq1 = 0; zq2 = 1; yq1 = 0; yq2 = 1; zh1 = 0; zh2 = 1; yh1 = 0; yh2 = 1;}

#define ZUO_ZHUAN {zq1 = 0; zq2 = 0; yq1 = 0; yq2 = 1; zh1 = 0; zh2 = 0; yh1 = 0; yh2 = 1;}

#define YOU_ZHUAN {zq1 = 0; zq2 = 1; yq1 = 0; yq2 = 0; zh1 = 0; zh2 = 1; yh1 = 0; yh2 = 0;}

#define TING_CHE     {zq1 = 0; zq2 = 0; yq1 = 0; yq2 = 0; zh1 = 0; zh2 = 0; yh1 = 0; yh2 = 0;}

   main.c

/****************************************************

序列槽程式serial UART

波特率:序列槽每秒鐘發送或者接收的位數,

設發送一位需要的時間是T,則波特率buad=1/T

序列槽發送條件:向SBUF寫入資料,則立馬回發送

               發送完成後 TI 由硬體置1,需要手動清0

序列槽接受收件:REN = 1,允許接收

                RI = 0;

             接收完畢後RI會由硬體置1,需要手動清零

*********************************************************/

#include car.h>

#include intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit dula=P2^0;        //段選信号的鎖存器控制

sbit wela=P2^1;        //位選信号的鎖存器控制

sbit cs88=P2^2;        //點陣管的鎖存器控制 cs88=0;//關點陣管

sbit DS1302=P2^7;      //定義DS1302時鐘使能端,用于HJ-C52實驗闆複位,與本實驗無關

sbit SD=P2^6;         //定義SD卡使能端,用于HJ-C52實驗闆複位,與本實驗無關

void cmg88()          //關數位管,點陣函數 cmg88();//關數位管,點陣函數

    dula=1;

    P0=0x00;

    dula=0;

    cs88=0x00;

    cs88=1;

sbit LED6 = P1^6;

sbit LED5 = P1^5;

sbit LED4 = P1^4;

sbit LED0 = P1^0;

uchar buf;

uchar idata tcp_buf[55];

uchar tcp_flag = 0;

uchar rcv_flag = 0;

uchar count = 0;

uchar cnt = 0;

extern void delay_3s();

extern void delay_ms();

extern void delay_10ms();

extern void delay_s();

extern void delay_10s();

extern void lcd_1602_init();

extern void lcd_1602_write_char(uchar x, uchar y, uchar *ch);

extern void lcd_1602_write_string(uchar x, uchar y, uchar *string);

extern int lcd_1602_busy();

extern void lcd_1602_write_cmd(uchar cmd);

extern void lcd_1602_write_data(uchar dat);

extern void delay();

void serial_init();

unsigned char code AT_RST[8] = {0x41, 0x54, 0x2B, 0x52, 0x53, 0x54, 0x0D, 0x0A };     //AT+RST 複位

unsigned char code AT_CWMOD2E[13] = {0x41, 0x54, 0x2B, 0x43, 0x57, 0x4D, 0x4F, 0x44, 0x45, 0x3D, 0x32, 0x0D, 0x0A}; //AT+CWMODE=2     設定為AP模式

unsigned char code AT_CIPSTART[40] = {0x41, 0x54, 0x2B, 0x43, 0x49, 0x50, 0x53, 0x54, 0x41, 0x52, 0x54, 0x3D, 0x22,

                                 0x54, 0x43, 0x50, 0x22, 0x2C, 0x22, 0x31, 0x39, 0x32, 0x2E, 0x31, 0x36, 0x38,

                                 0x2E, 0x34, 0x2E, 0x31, 0x30, 0x30, 0x22, 0x2C, 0x38, 0x37, 0x36, 0x35, 0x0D, 0x0A};

                                 //AT+CIPSTART="TCP","192.168.4.100",8765,設定子產品為TCP用戶端,連結192.168.4.100,端口8765

unsigned char AT_CIPSEND[14] = {0x41, 0x54, 0x2B, 0x43, 0x49, 0x50, 0x53, 0x45, 0x4E, 0x44, 0x3D, 0x34, 0x0D, 0x0A};

                                //AT+CIPSEND=4 發送4個位元組

uchar code AT_CWMODE3[13] = {0x41, 0x54, 0x2B, 0x43, 0x57, 0x4D, 0x4F, 0x44, 0x45, 0x3D, 0x33, 0x0D, 0x0A};    //AT+CWMODE=3

uchar code AT_CIPMUX[13] = {0x41, 0x54, 0x2B, 0x43, 0x49, 0x50, 0x4D, 0x55, 0x58, 0x3D, 0x31, 0x0D, 0x0A}; //AT+CIPMUX=1 開啟多連結

uchar code AT_CIPSERVER[21] = {0x41, 0x54, 0x2B, 0x43, 0x49, 0x50, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x3D, 0x31, 0x2C, 0x38, 0x37, 0x36, 

                               0x35, 0x0D, 0x0A};    

                                //AT+CIPSERVER=1,8765 開啟tcp伺服器,端口号8765

uchar code AT_CIPSTO[15] = {0x41, 0x54, 0x2B, 0x43, 0x49, 0x50, 0x53, 0x54, 0x4F, 0x3D, 0x36, 0x30, 0x30, 0x0D, 0x0A};    

                                //AT+CIPSTO=600 設定伺服器逾時時間600s

void main()

    int i = 0;

    WDT_CONTR = 0;

    DS1302=0;             //關DS1302子產品,與本實驗無關

    SD=0;                //關SD卡子產品,與本實驗無關

    cmg88();            //關數位管,點陣函數

    delay_10ms();

    TING_CHE

    serial_init(); //tomd = 0x20

     for(i=0; i8; i++)

    {

        SBUF = AT_RST[i];

        delay_ms();

    }

    delay_s();

    rcv_flag++;

     for(i=0; i13; i++)                     //設定模式3

        SBUF = AT_CWMODE3[i];

     for(i=0; i8; i++)                 //重新開機生效

     for(i=0; i13; i++)                 //設定多連結

        SBUF = AT_CIPMUX[i];

     for(i=0; i21; i++)                 //建立tcp伺服器,端口号8765

        SBUF = AT_CIPSERVER[i];

     for(i=0; i15; i++)                 //設定逾時時間600s

        SBUF = AT_CIPSTO[i];

     while(1);            

void serial_interrup() interrupt 4

    if(TI)

        TI = 0;

    if(RI)

        RI = 0;

        tcp_buf[count] = SBUF;        //儲存一個位元組

        if(tcp_buf[0]==0x23)        //用操作碼以#開頭,檢測到#就開始儲存資料

        {

            count++;

        }

        else

            count=0;

        if(count>3)                    //使用者操作碼有4個字元,超出就不是使用者操作碼

             if(tcp_buf[1] == 'u' && tcp_buf[2] == 'p')     //up前進

            {

                LED4 = 0;

                ZHENG_ZHUAN

            }

            if(tcp_buf[1] == 'd' && tcp_buf[2] == 'n')     //dn後退

                LED4 = 1;

                FAN_ZHUAN

            if(tcp_buf[1] == 'z' && tcp_buf[2] == 'z')     //zz左轉

                LED5 = 1;

                ZUO_ZHUAN

            if(tcp_buf[1] == 'y' && tcp_buf[2] == 'z')     //yz右轉

                LED5 = 0;

                YOU_ZHUAN

            if(tcp_buf[1] == 's' && tcp_buf[2] == 'p')     //sp停車

                LED6 = 0;

                TING_CHE

            count=0;                                     //超出4個字元,非使用者操作碼,清零count,重新接收資料

   delay.c

void delay_us() //誤差 -0.234375us

    unsigned char a;

    for(a=3;a>0;a--);

void delay_10us() //誤差 -0.173611111111us

    unsigned char a,b;

    for(b=1;b>0;b--)

        for(a=43;a>0;a--);

void delay_ms() //誤差 -0.651041666667us

    for(b=102;b>0;b--)

        for(a=3;a>0;a--);

void delay_10ms() //誤差 -0.000000000002us

    for(b=249;b>0;b--)

        for(a=17;a>0;a--);

void delay_100ms() //誤差 -0.000000000023us

    for(b=221;b>0;b--)

        for(a=207;a>0;a--);

void delay_s() //誤差 -0.000000000227us

    unsigned char a,b,c;

    for(c=13;c>0;c--)

        for(b=247;b>0;b--)

            for(a=142;a>0;a--);

    _nop_; //if Keil,require use intrins.h

void delay_3s() //誤差 -0.000000000682us

    for(c=93;c>0;c--)

        for(b=178;b>0;b--)

            for(a=82;a>0;a--);

void delay_5s() //誤差 -0.000000001137us

    for(c=179;c>0;c--)

        for(b=220;b>0;b--)

            for(a=57;a>0;a--);

   serial.c

      SCON = 0x40;         //工作方式 1, 8位異步串行收發,波特率由定時器 1 控制

      TL2=0xFD;            //設定波特率為115200

上一篇: 字元位元組
下一篇: 位元組對齊

繼續閱讀