目录
1.ESP8266 作为设备
2.ESP8266作为服务器
注意:1.在中断中一般不直接在中断服务函数里处理数据,而是在收到数据后直接丢给队列,再处理数据;
2.在中断服务函数里尽量减少使用延时函数及打印函数。
1.ESP8266 作为设备
1.1项目需求
ESP8266接入同一WIFI局域网下的服务器,向服务器发送数据
ESP-01s出厂波特率正常是115200, 注意:AT指令,控制类都要加回车,数据传输时不加回车。
上电后,串口输出系统开机信息,购买的部分模块可能电压不稳乱码,以 ready 为准。
通过一下命令配置成9600波特率
AT+UART=9600,8,1,0,0
1.设置工作模式
AT+CWMODE=3 //1. 是station(设备)模式 2.是AP(路由)模式 3.是双模
OK
2.以设备模式接入家中路由器配置
AT+CWJAP="TP-LINK_3E30","18650711783" //指令
WIFI CONNECTED //结果
WIFI GOT IP //结果
OK //结果
3.连接服务器
AT+CIPSTART="TCP","192.168.0.113",8888 //指令,注意双引号逗号都要半角(英文)输入
CONNECT //结果:成功
OK //结果:成功
4.开启透传模式
AT+CIPMODE=1 //开启透传模式
Response :OK
5.发送数据
AT+CIPSEND //带回车
Response: > //这个时候随意发送接收数据咯
CubeMX设置
打开串口1、及其中断;打开串口2;打开GPIO8-led;中断优先级降低;
函数代码
#include "string.h"
#include "stdio.h"
uint8_t buf=0;
unsigned char ch[200] ;
uint16_t UART1_RX_STA=0;
int LAN_mark=0;
int other_land_mark=0;
int suceed_mark=0;
int error=1;
char LAN_connect[] ="AT+CWJAP=\"yangkai\",\"12345678\"\r\n";
char TCP_server_connect[] ="AT+CIPSTART=\"TCP\",\"172.20.10.5\",80\r\n";
char touchuan_start[] ="AT+CIPMODE=1\r\n";
char datatransport_start[] ="AT+CIPSEND\r\n";
char reset[] ="AT+RST\r\n";
char my_word[] ="hello world\r\n";
int fputc(int ch1,FILE *f)
{
uint8_t temp[1]={ch1}; //必须要用uint8_t承接,将int char变为uint8_t
HAL_UART_Transmit(&huart1, temp, 1, 0xffff);
return ch1;
}
//重写串口中断服务函数——————串口接受到的数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//如果来自串口1的数捿
if(huart->Instance==USART1){
//如果没有接收完成
if((UART1_RX_STA & 0x8000)==0){
//如果已经收到迿0x0d回车
if(UART1_RX_STA & 0x4000){
//如果这个数是0x0a换行
if(buf==0x0a){
//,接收完成,弿始下丿次接政
UART1_RX_STA|=0x8000;
//可以用ch匹配数据了
//HAL_UART_Transmit(&huart2, ch, strlen(ch), 0xffff);
// 这里用来测试可以,但是不能用串口2来打印CH,影响串口接收函数,影响时序。
if(!strcmp(ch,"WIFI GOT IP")){ //收到wifi got ip
LAN_mark=1;
}
if(!strcmp(ch,"OK")){ //收到OK
other_land_mark=1;
}
if(!strcmp(ch,"LED")){ //收到led翻转LED
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
}
// 查看是否收到 FAIL
if(!strcmp(ch, "FAIL"))
{
int i = 0;
for (i = 0; i < 5; i++)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
HAL_Delay(1000);
}
printf(reset);
}
memset(ch,'\0',200);
UART1_RX_STA=0;
//如果这个数不昿0x0a换行
}else{
//接收失败,数据清穿
UART1_RX_STA=0;
//memset(ch,0,200);
}
//如果没有收到迿0x0d
}else{
//如果现在这个数是0x0d回车
if(buf==0x0d){
//状濁为标记改变为收到了0x0d
UART1_RX_STA|=0x4000;
//如果现在这个数不昿0x0d换行
}else{
//进行接收进入ch里面
ch[UART1_RX_STA&0x3fff]=buf;
UART1_RX_STA++;
if(UART1_RX_STA>199)
UART1_RX_STA = 0;
}
}
}
//重新弿启串口中断接政
HAL_UART_Receive_IT(&huart1, &buf,1);
}
}
main函数中代码
HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
//打开串口1接收中断 接收到的字符存在buf里,有一个字?
HAL_UART_Receive_IT(&huart1, &buf, 1);
HAL_UART_Transmit(&huart2, "let's go\r\n", strlen("let's go\r\n"), 100);
printf(LAN_connect);
//printf(LAN_connect); //发送联网指令 "yangkai\",\"12345678\"\r\n";
//while(!LAN_mark) HAL_Delay(50); //接收到 wifi GOTIP执行下一步LAN_mark变为1
while(!other_land_mark) HAL_Delay(50); //接收到OK执行下一步other_land_mark 变为1
HAL_UART_Transmit(&huart2, (uint8_t *)"111", strlen("111"), 100); //连上就111
other_land_mark=0; //other_land_mark接收到OK执行下一步
printf(TCP_server_connect); //发送"TCP\",\"172.20.10.5\",80\r\n";
while(!other_land_mark) HAL_Delay(50); //接收到OK执行下一步other_land_mark 变为1
other_land_mark=0; //other_land_mark接收到OK执行下一步
printf(touchuan_start); //AT+CIPMODE=1\r\n";
while(!other_land_mark) HAL_Delay(50); //other_land_mark接收到OK执行下一步
other_land_mark=0; //重新置0
printf(datatransport_start); //"AT+CIPSEND\r\n"
while(!other_land_mark) HAL_Delay(50); //other_land_mark接收到OK执行下一步
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//如果sta高位丿1 ==受到带换行的数据
HAL_UART_Transmit(&huart2, (uint8_t *)"已连接服务器\r\n", strlen("已连接服务器\r\n"), 100); //连上就111
printf("hello yk\r\n");
//printf("hello world.\r\n");
HAL_Delay(3000);
}
2.ESP8266作为服务器
步骤:
//0重启
+STA_CONNECTED:"c0:a5:dd:54:0c:ef"
+DIST_STA_IP:"c0:a5:dd:54:0c:ef","192.168.4.2"
WIFI DISCONNECT
隔5秒后下一个
//1 配置成双模
AT+CWMODE=2
Response :OK
//2 使能多链接
AT+CIPMUX=1
Response :OK
//3 建立TCPServer
AT+CIPSERVER=1,8888 // default port = 333
Response :OK
//然后TCP client去连接服务器1,8888
Response :0,CONNECT
while(1){
//4 发送数据设置
AT+CIPSEND=0,4 // 发送4个字节在连接0通道上
//5 发送数据
"hello yk"
Response :SEND OK
}
//断开连接
AT+CIPCLOSE=0
Response :0, CLOSED OK
CubeMX是同样上的设置
函数代码如下
#include "string.h"
#include "stdio.h"
uint8_t buf=0;
unsigned char ch[200] ;
uint16_t UART1_RX_STA=0;
int TCP_mark=0;
int other_land_mark=0;
char mode_AP[] ="AT+CWMODE=2\r\n";
char mutiple_connect[] ="AT+CIPMUX=1\r\n";
char TCPserver[] ="AT+CIPSERVER=1,8888\r\n";
char data_trans[] ="AT+CIPSEND=0,11\r\n";
char reset[] ="AT+RST\r\n";
char my_word[] ="hello world";
int fputc(int ch1,FILE *f)
{
uint8_t temp[1]={ch1}; //必须要用uint8_t承接,将int char变为uint8_t
HAL_UART_Transmit(&huart1, temp, 1, 0xffff);
return ch1;
}
//重写串口中断服务函数——————串口接受到的数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//如果来自串口1的数捿
if(huart->Instance==USART1){
//如果没有接收完成
if((UART1_RX_STA & 0x8000)==0){
//如果已经收到迿0x0d回车
if(UART1_RX_STA & 0x4000){
//如果这个数是0x0a换行
if(buf==0x0a){
//,接收完成,弿始下丿次接政
UART1_RX_STA|=0x8000;
//可以用ch匹配数据了
//HAL_UART_Transmit(&huart2, ch, strlen(ch), 0xffff);
// 这里用来测试可以,但是不能用串口2来打印CH,影响串口接收函数,影响时序。
if(!strcmp(ch,"0,CONNECT")){ //收到0,CONNECT
TCP_mark=1;
}
if(!strcmp(ch,"OK")){ //收到OK
other_land_mark=1;
}
if(!strcmp(ch,"LED")){ //收到led翻转LED
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
}
// 查看是否收到 FAIL
if(!strcmp(ch, "ERROR"))
{
int i = 0;
for (i = 0; i < 5; i++)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8);
HAL_Delay(1000);
}
printf(reset);
}
memset(ch,'\0',200);
UART1_RX_STA=0;
//如果这个数不昿0x0a换行
}else{
//接收失败,数据清穿
UART1_RX_STA=0;
//memset(ch,0,200);
}
//如果没有收到迿0x0d
}else{
//如果现在这个数是0x0d回车
if(buf==0x0d){
//状濁为标记改变为收到了0x0d
UART1_RX_STA|=0x4000;
//如果现在这个数不昿0x0d换行
}else{
//进行接收进入ch里面
ch[UART1_RX_STA&0x3fff]=buf;
UART1_RX_STA++;
if(UART1_RX_STA>199)
UART1_RX_STA = 0;
}
}
}
//重新弿启串口中断接政
HAL_UART_Receive_IT(&huart1, &buf,1);
}
}
//main函数中代码
HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
//打开串口1接收中断 接收到的字符存在buf里,有一个字?
HAL_UART_Receive_IT(&huart1, &buf, 1);
HAL_UART_Transmit(&huart2, "let's go\r\n", strlen("let's go\r\n"), 100);
printf(mode_AP); //设置路由器模式
while(!other_land_mark) HAL_Delay(50); //接收到OK执行下一步other_land_mark 变为1
HAL_UART_Transmit(&huart2, (uint8_t *)"111", strlen("111"), 100); //连上就111
other_land_mark=0; //other_land_mark接收到OK执行下一步
printf(mutiple_connect); //使能多连接
while(!other_land_mark) HAL_Delay(50); //接收到OK执行下一步other_land_mark 变为1
HAL_UART_Transmit(&huart2, (uint8_t *)"222", strlen("222"), 100); //连上就111
other_land_mark=0; //other_land_mark接收到OK执行下一步
printf(TCPserver); //建立TCP服务器
while(!TCP_mark) HAL_Delay(50); //TCP_mark接收到0,CONNECT执行下一步
HAL_UART_Transmit(&huart2, (uint8_t *)"333", strlen("333"), 100); //连上就111
TCP_mark=0; //重新置0
printf(data_trans); //设置数据传输端口和字数
while(!other_land_mark) HAL_Delay(50); //other_land_mark接收到OK执行下一步
HAL_UART_Transmit(&huart2, (uint8_t *)"已建立服务器\r\n", strlen("已建立服务器\r\n"), 100); //连上就111
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_UART_Transmit(&huart2, (uint8_t *)"hello yk\r\n", strlen("hello yk\r\n"), 100);
printf(data_trans);
HAL_Delay(2000);
//发送数据
printf(my_word);
HAL_Delay(2000);
//data2=SBUF; //接受外部数据后产生中断 进入interrupt 4
}
/* USER CODE END 3 */
}