学习STC89C52RC 使单片机联网
摘要:51单片机通过ESP8266模块实现网络连接,主要分为三个步骤:硬件连接(串口通信线+电源)、配置AT指令(连接WiFi/服务器)和数据收发控制。关键点包括:确保波特率一致、使用3.3V电源、AT指令需加回车符。示例代码展示了初始化、WiFi连接和TCP通信的实现,通过LED指示连接状态。注意事项强调电源稳定性对网络连接的重要性,以及正确解析模块返回数据的方法。
要让 51 单片机实现上网功能,需要借助通信模块(如 ESP8266、SIM800C 等)作为 “翻译官”,因为 51 单片机本身无法直接连接网络。下面以 ESP8266 WiFi 模块为例,用 “三步法” 解释这个过程:
第一步:硬件连接
- 51 单片机 → ESP8266 模块:用 4 根线连起来(就像打电话的两头接上线):
- TXD(51 的发送) → RXD(ESP 的接收):让 51 能 “说话” 给 ESP 听。
- RXD(51 的接收) → TXD(ESP 的发送):让 ESP 能 “回答” 51。
- VCC/GND:接电源(一般 ESP 用 3.3V,别接 5V 会烧!)。
- EN:有些 ESP 模块需要接高电平(比如接 3.3V)才能开机。
第二步:教 ESP8266 “听话”(配置 AT 指令)
ESP8266 默认是 “聋哑人”,得先用 AT 指令教它 “说话” 和 “听话”。这个过程就像教小朋友背口诀:
- 开机测试:51 单片机给 ESP 发
AT(后面加个回车键),ESP 如果回OK,说明它 “醒了”。 - 连 WiFi:发
AT+CWJAP="WiFi名","密码",比如AT+CWJAP="奶奶家","123456",ESP 就会去连 WiFi。 - 设置上网模式:发
AT+CIPMUX=0(让 ESP 一次只干一件事)。 - 连服务器:发
AT+CIPSTART="TCP","服务器地址",80(比如连百度:AT+CIPSTART="TCP","www.baidu.com",80)。
第三步:让 51 单片机 “指挥” ESP 干活
51 单片机就像 “指挥官”,通过 AT 指令让 ESP8266 去上网、发数据:
-
发数据:
- 先发
AT+CIPSEND=5(告诉 ESP:我要发 5 个字符)。 - 等 ESP 回
>后,再发Hello(实际项目里可能是温度、湿度数据)。 - ESP 会把数据打包成 “上网包裹” 发给服务器。
- 先发
-
收数据:
- 服务器回的数据会先到 ESP,ESP 再把数据 “翻译” 成 AT 指令格式发给 51 单片机。
- 比如 ESP 收到
+IPD,5:World,51 单片机读到后就知道服务器回了 “World”。
关键注意事项
- 波特率要一致:51 单片机和 ESP8266 “说话” 的速度要一样(比如都设为 115200bps)。
- 电源要稳:ESP8266 上网时耗电比较大,电源不稳会断网(就像电灯电压不稳会闪)。
- 指令后加回车:AT 指令结尾要加
\r\n(就像说话要带句号)。
代码
#include "reg52.h"
#include "intrins.h"
#include "string.h"
sfr AUXR = 0x8E;
sbit D5=P3^7;
sbit D6=P3^6;
char cmd[12];
char MS[]="AT+CWMODE_CUR=1\r\n";
code char JR_lyq[] = "AT+CWJAP=\"WiFi名\",\"密码\"\r\n";
code char JR_fwq[] = "AT+CIPSTART=\"TCP\",\"电脑IP地址\",8880\r\n";
char TC[] = "AT+CIPMODE=1\r\n";
char SR[] = "AT+CIPSEND\r\n";
int i=0;
int AT_ok=0;//输入指令后返回语句,为OK则为1,否则为0
void chushihua()
{
SCON=0x50;//选择每次传输的有效数据位数 这里是8位
AUXR=0x01;//减少辐射
TMOD &= 0x0F;//选择模式
TMOD |= 0x20;
TH1=0xFD;//开始计数的初始高位
TH0=0xFD;
TR1=1;
EA=1;
ES=1;
}
void Delay1000ms() //延续1s
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void shuchu(char *p)
{
while(*p!='\0')//从字符串起始位直到\0 一位一位的发送给SBUF
{
SBUF=*p;
while(!TI);
TI=0;//输入一个数据,给一个间隔时间,这样不卡壳
p++;
}
}
void main()
{
D5 = D6 = 1;
chushihua();
Delay1000ms();
shuchu(MS);
while(!AT_ok);
AT_ok=0;
D5=0;//选择模式,检测是否连接成功,连接成功D5灯亮
shuchu(JR_lyq);
while(!AT_ok);
AT_ok=0;
D6=0; //连接网络,连接成功D6灯亮
shuchu(JR_fwq);
while(!AT_ok);
AT_ok=0; //连接服务器,连接成功D5灯灭
D5=1;
shuchu(TC);
while(!AT_ok);
AT_ok=0;//发送透传指令,发送成功D6灯灭
D6=1;
shuchu(SR);
while(!AT_ok);
AT_ok=0; //发送无限制输入指令
while(1)//循环 每隔1S 输入 xintiaobao
{
//shuchu("zhanghan shuai \r\n");
//shuru(cmd);
shuchu("xintiaobao\r\n");//心跳包
Delay1000ms();
}
}
void UART_Routine() interrupt 4
{
static int i=0;
char tmp;
if(RI)
{
RI=0;
tmp=SBUF;
if(tmp=='O' || tmp=='L')//如果检测到O或L强制将i=0
i=0;
cmd[i++]=SBUF;
if(cmd[0]=='O' && cmd[1]=='K')//检测如果返回值为OK则改变AT_ok值,并且清空字符串
{
memset(cmd, 0, sizeof(cmd)); // 清空字符串
i=0;
AT_ok=1;
}
if(cmd[0]=='L' && cmd[2]=='1')//检测如果输入值为L*1,则亮D5
{
memset(cmd, 0, sizeof(cmd));
i=0;
D5=0;
}
if(cmd[0]=='L' && cmd[2]=='0')////检测如果输入值为L*0,则亮D6
{
memset(cmd, 0, sizeof(cmd));
i=0;
D5=1;
}
if(i==sizeof(cmd))//数组满了,下标回0,清空数组
{
memset(cmd, 0, sizeof(cmd));
i=0;
}
}
}
更多推荐



所有评论(0)