/*************************************************************************************************
PROJECT: wifi遙控小車
HARDWARE: STC89C52RC單機, L239D直流電機驅動器, ESP8266安信可wifi子產品
SOFTWARE: Eclipse安卓開發環境
AUTHOR: DDDDD
DATE: 2014-12-5
*************************************************************************************************/
本章介紹,如何利用wifi子產品在單片機上建立TCP伺服器,進而用android用戶端來操作單片機。wifi子產品采用安信可ESP8266,
價格低,性能穩定。通過序列槽傳輸與單片機通信,波特率115200

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
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供電。必要說明:單片機和直流電機分别用倆
組電池供電,因為直流電機在啟動時會将電池電壓拉低,如果用同一組電池供電,單片機會複位。
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