/*************************************************************************************************
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,需要手动清零
串口初始化配置:
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指令集:
必要
说明:给模块发送指令时,必须以回车符作为结尾,否则模块无响应。因此在串口发送数据的时候,采用十六进制发送。
当模块收到指令时,会将指令通过串口发送给MCU,发送的格式
5、源代码
car.h
main.c
delay.c
serial.c
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
- }
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
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,发送的格式
+IPD,7:hello
OK
这代表收到服务器的数据hello
OK
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; i8; i++)
- {
- SBUF = AT_RST[i];
- delay_ms();
- }
- delay_s();
- rcv_flag++;
-
- for(i=0; i13; i++) //设置模式3
- {
- SBUF = AT_CWMODE3[i];
- delay_ms();
- }
- delay_s();
- rcv_flag++;
-
- for(i=0; i8; i++) //重启生效
- {
- SBUF = AT_RST[i];
- delay_ms();
- }
- delay_s();
- rcv_flag++;
-
- for(i=0; i13; i++) //设置多链接
- {
- SBUF = AT_CIPMUX[i];
- delay_ms();
- }
- rcv_flag++;
-
- for(i=0; i21; i++) //创建tcp服务器,端口号8765
- {
- SBUF = AT_CIPSERVER[i];
- delay_ms();
- }
- delay_s();
- rcv_flag++;
-
- for(i=0; i15; 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,重新接收数据
- }
- }
- }
点击(此处)折叠或打开
- #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
- }