【STM32】esp8266连接wifi
1.配置stm32cubemx
使用串口二接收esp8266的数据,单片机接收,使用串口1将数据发送给串口助手
串口2波特率设置74880,串口1设置115200
在初始化的时候需要将复位引脚拉低20ms,然后再拉高20ms,
设置GPIOB的输出模式
对PB12做输出处理
2.esp8266初始化
需要将复位引脚拉低20ms,再拉高20ms
esp8266初始化化的时候有信息,我们可以通过串口2获取信息,然后串口1输出
需要自己实现fputc
我们发现下面有乱码,应该怎么处理,这里会涉及到波特率的转换
3.波特率转换
当我们遇到csum 0xde,需要转换波特率
先处理波特率转换之前的数据,先打印到串口1
void esp8266_response(const char*msg,uint32_t timeout)
{
uint32_t Curtick=HAL_GetTick();//获取当前时间
uint8_t data;
uint8_t i=0;
while(1)
{
if(HAL_GetTick()-Curtick>=timeout)//如果超时2s就break
break;
if(HAL_UART_Receive(&huart2,(uint8_t*)&data,1,10)==HAL_TIMEOUT)//如果10ms没收到esp8266发给单片机的数据,就返回HAL_TIMEOUT
continue; //如果初始化成功,不会HAL_TIMEOUT,就不continue;
printf("%c",data); //单片机把串口2的数据一个字节一个字节读到data中,然后通过printf打印到串口1 //这里串口2的波特率为74880
if(data==msg[i]) //chksum 0xde\r\n //匹配到的话,就是初始化成功
{
i++;
if(i==strlen(msg))
{
break;
}
}
else //重新匹配
{ i=0;
}
}
}
波特率转换,需要转换波特率为115200.
//直接复制uart中的
void esp8266_setbaud(uint32_t baud)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = baud;//需要传参修改需要的波特率
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2);
}
这里的ready只剩下了eady,这是因为串口涉及到硬件,串口转换很快,将数据给你放到data,printf还没来得及处理,已经串口下次转换了,所以就会覆盖,所以我们将串口转换的值放到缓冲区。然后统一输出到串口1
缓冲区及下标
接下来需要将串口2的波特率转换为115200
void esp8266_setbaud(uint32_t baud)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = baud;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2);
}
4.连接wifi
使用指令即可
void esp8266_link_wifi(const char*name,const char*password)
{
char buffer[128];
sprintf(buffer,"AT+CWJAP=\"%s\",\"%s\"",name,password);//构建指令字符串
HAL_UART_Transmit(&huart2,(uint8_t*)buffer,strlen(buffer),HAL_MAX_DELAY);//向esp8266,串口2发送指令字符串
HAL_UART_Transmit(&huart2,(uint8_t*)"\r\n",2,HAL_MAX_DELAY);
}
根据esp8266_response(const char*msg,uint32_t timeout)返回值判断是否发生成功,修改esp8266_response函数
uint8_t esp8266_response(const char*msg,uint32_t timeout)
{
uint32_t Curtick=HAL_GetTick();//获取当前时间
uint8_t data;
uint8_t i=0;
while(1)
{
if(HAL_GetTick()-Curtick>=timeout)//如果超时2s就break
return 0;
if(HAL_UART_Receive(&huart2,(uint8_t*)&data,1,10)==HAL_TIMEOUT)//如果10ms没收到esp8266发给单片机的数据,就返回HAL_TIMEOUT
continue; //如果初始化成功,不会HAL_TIMEOUT,就不continue;
//printf("%c",data); //单片机把串口2的数据一个字节一个字节读到data中,然后通过printf打印到串口1 //这里串口2的波特率为74880
buffer[num++]=data;
if(data==msg[i]) //chksum 0xde\r\n //匹配到的话,就是初始化成功
{
i++;
if(i==strlen(msg))
{
return 1; //匹配成功
}
}
else //重新匹配
{ i=0;
}
}
}
void esp8266_link_wifi(const char*name,const char*password)
{
char buffer[512];
sprintf(buffer,"AT+CWJAP=\"%s\",\"%s\"",name,password);
HAL_UART_Transmit(&huart2,(uint8_t*)buffer,strlen(buffer),HAL_MAX_DELAY);
HAL_UART_Transmit(&huart2,(uint8_t*)"\r\n",2,HAL_MAX_DELAY);
if(esp8266_response(buffer,2000))//esp8266串口收到
{
printf("%s",buffer);
}
else //发送失败
{
printf("%s",buffer);
printf("connect fail");
}
memset(buffer,0,512);//清空缓冲区
}
esp8266.c
#include "esp8266.h"
#include <stdio.h>
#include <string.h>
extern UART_HandleTypeDef huart2;
extern uint8_t buffer[512];
extern uint16_t num;
void esp8266_init(void)
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET);
HAL_Delay(20);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET);
HAL_Delay(20);
esp8266_response("chksum 0xde\r\n",2000);
HAL_Delay(50);
esp8266_setbaud(115200);
esp8266_response("ready\r\n",1000);
printf("%s",buffer);
memset(buffer,0,512);
}
uint8_t esp8266_response(const char*msg,uint32_t timeout)
{
uint32_t Curtick=HAL_GetTick();//获取当前时间
uint8_t data;
uint8_t i=0;
while(1)
{
if(HAL_GetTick()-Curtick>=timeout)//如果超时2s就break
return 0;
if(HAL_UART_Receive(&huart2,(uint8_t*)&data,1,10)==HAL_TIMEOUT)//如果10ms没收到esp8266发给单片机的数据,就返回HAL_TIMEOUT
continue; //如果初始化成功,不会HAL_TIMEOUT,就不continue;
//printf("%c",data); //单片机把串口2的数据一个字节一个字节读到data中,然后通过printf打印到串口1 //这里串口2的波特率为74880
buffer[num++]=data;
if(data==msg[i]) //chksum 0xde\r\n //匹配到的话,就是初始化成功
{
i++;
if(i==strlen(msg))
{
return 1;
}
}
else //重新匹配
{ i=0;
}
}
}
void esp8266_setbaud(uint32_t baud)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = baud;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart2);
}
void esp8266_link_wifi(const char*name,const char*password)
{
char buffer[512];
sprintf(buffer,"AT+CWJAP=\"%s\",\"%s\"",name,password);
HAL_UART_Transmit(&huart2,(uint8_t*)buffer,strlen(buffer),HAL_MAX_DELAY);
HAL_UART_Transmit(&huart2,(uint8_t*)"\r\n",2,HAL_MAX_DELAY);
if(esp8266_response(buffer,2000))//esp8266串口收到
{
printf("%s",buffer);
}
else
{
printf("%s",buffer);
printf("connect fail");
}
memset(buffer,0,512); //清空缓冲区
}
esp8266.h
#ifndef _ESP8266_H_
#define _ESP8266_H_
#include "stm32f4xx_hal.h"
void esp8266_init(void);
uint8_t esp8266_response(const char*msg,uint32_t timeout);
void esp8266_setbaud(uint32_t baud);
void esp8266_link_wifi(const char*name,const char*password);
#endif