/*************************************************************************************************
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 开启多链接
-
OK
-
12、AT+CIPSERVER=1,8765 配置为TCP服务器,端口号8765
-
OK
-
13、AT+CIPSTO=600 设置超时时间
-
OK
-
以上是需要发送的指令,当上述操作完成之后,就可以等待android客户端的命令了,下面是模块收到一条指令的格式
-
14、+IPD,7:hello
OK 收到数据hello
必要说明:给模块发送指令时,必须以回车符作为结尾,否则模块无响应。因此在串口发送数据的时候,采用十六进制发送。
当模块收到指令时,会将指令通过串口发送给MCU,发送的格式
这代表收到服务器的数据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;
-
P0=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; i<8; i++)
-
{
-
SBUF = AT_RST[i];
-
delay_ms();
-
}
-
delay_s();
-
rcv_flag++;
-
-
for(i=0; i<13; i++) //设置模式3
-
{
-
SBUF = AT_CWMODE3[i];
-
delay_ms();
-
}
-
delay_s();
-
rcv_flag++;
-
-
for(i=0; i<8; i++) //重启生效
-
{
-
SBUF = AT_RST[i];
-
delay_ms();
-
}
-
delay_s();
-
rcv_flag++;
-
-
for(i=0; i<13; i++) //设置多链接
-
{
-
SBUF = AT_CIPMUX[i];
-
delay_ms();
-
}
-
rcv_flag++;
-
-
for(i=0; i<21; i++) //创建tcp服务器,端口号8765
-
{
-
SBUF = AT_CIPSERVER[i];
-
delay_ms();
-
}
-
delay_s();
-
rcv_flag++;
-
-
for(i=0; i<15; i++) //设置超时时间600s
-
{
-
SBUF = AT_CIPSTO[i];
-
delay_ms();
-
}
-
delay_s();
-
rcv_flag++;
-
-
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
-
#include <intrins.h>
-
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
-
{
-
unsigned char a,b;
-
for(b=102;b>0;b--)
-
for(a=3;a>0;a--);
-
}
-
-
void delay_10ms() //误差 -0.000000000002us
-
{
-
unsigned char a,b;
-
for(b=249;b>0;b--)
-
for(a=17;a>0;a--);
-
}
-
-
void delay_100ms() //误差 -0.000000000023us
-
{
-
unsigned char a,b;
-
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
-
{
-
unsigned char a,b,c;
-
for(c=93;c>0;c--)
-
for(b=178;b>0;b--)
-
for(a=82;a>0;a--);
-
}
-
-
void delay_5s() //误差 -0.000000001137us
-
{
-
unsigned char a,b,c;
-
for(c=179;c>0;c--)
-
for(b=220;b>0;b--)
-
for(a=57;a>0;a--);
-
}
serial.c
-
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
-
}
阅读(2157) | 评论(0) | 转发(0) |