问题遇到的现象和发生背景
STM32中用ESP8266模块连接TLINK平台,实现想要的效果。但是在测试wifi时,发现会卡在一个循环里面
用代码块功能插入代码,请勿粘贴截图
//main.c文件中的代码
#include "stm32f10x.h"
#include "Systick.h"
#include "usart.h"
#include "pwm.h"
#include "NetWork.h"
#include "TLink.h"
#include "stdio.h"
#include "string.h"
#include "Delay.h"
#include "hx.h"
#include "step_motor.h"
#include "led.h"
DeviceSta_Strcture device = {0,120,0};
int main()
{
Systick_init(72);
initUART();
initUART2();
initNVIC(NVIC_PriorityGroup_2);//开启UART2的接收和空闲中断
// TIM3_CH1_PWM_Init(20000-1,72-1);
//舵机角度参数:19500-17500(前者为0°,后者为360°)
// STEP_MOTOR_Init();
initESP8266();
LED_1(ON);
// connectAP(SSID,PWD);
// connectTlink();
// sendDeviceStatus(&device);
// TIM_SetCompare1(TIM3,19000);
// Get_Maopi(); //称毛皮重量
// Delay_ms(1000);
// Delay_ms(1000);
// Get_Maopi(); //重新获取毛皮重量
// STEP_MOTOR_LOOP (1,1,1);//电机按圈数运行//LOOP是旋转多少圈
while(1)
{
// device.Shengyu = Get_Weight();
// Delay_ms(1000);
// sendDeviceStatus(&device);
}
}
//
#include "string.h"
#include "NetWork.h"
#include "stm32f10x.h"
#include "Delay.h"
#include "usart.h"
#include "led.h"
u8 TXBuffer[TXBUFFER_LEN] = {0}; //网络通信数据发送缓冲
u8 RXBuffer[RXBUFFER_LEN] = {0}; //网络通信数据接收缓懆ҍ
/**
* 功能:查找字符串中是否包含另一个字符串
* 参数:
* dest:待查找目标字符串
* src:待查找内容
* retry_cn:查询超时时间
* 返回值:查找结果,非0为查找成功,0为失败
* 说明:
* 当发出一个AT指令后,需要一段时间等待ESP8266回复,因此就需要等待一段时间,
* 这个时间通常是几百ms(除了连接服务器和AP指令),本程序一般指令通常等待
* 2S,耗时的连接AP和服务器的设置等待为8S,其实花不了那么多时间,但如果发生超时
* 就一定可以判断是通信问题
*/
u8 findStr(u8* dest,u8* src,u16 retry_cn)
{
u16 retry = retry_cn; //超时时间
u8 result_flag = 0; //查找结果
while(strstr(dest,src)==0 && --retry!=0)//等待串口接收完毕或超时退出
{
Delay_ms(10);
}
if(retry==0) //如果超时则有问题,此时返回0
{
return 0;
}
result_flag = 1; //执行到这里说明一切正常, 表示查找成功
if(result_flag)
{
return 1;
}else
{
return 0;
}
}
/**
* 功能:初始化ESP8266
* 参数:None
* 返回值:初始化结果,非0为初始化成功,0为失败
*/
void initESP8266(void)
{
sendString(USART2,"+++"); //退出透传
Delay_ms(500);
sendString(USART2,"AT+RST\r\n"); //重启ESP8266
Delay_ms(3000);
checkESP8266(); //使用AT指令检查ESP8266是否孍
memset(RXBuffer,0,RXBUFFER_LEN); //清空接收缓冲
sendString(USART2,"ATE0\r\n"); //关闭回显
while(findStr(RXBuffer,"OK",300)==0) //设置不成功
{
sendString(USART2,"ATE0\r\n");
Delay_ms(3000);
}
// if(findStr(RXBuffer,"OK",300)==0) //设置不成势
// {
//// sendString(USART2,"ATE0\r\n");
//// Delay_ms(3000);
//// LED_1(ON);
// }
//}
* 功能:检查ESP8266是否正常
* 参数:None
* 返回值:ESP8266返回状态
* 非0 ESP8266正常
* 0 ESP8266有问题
*/
void checkESP8266(void)
{
memset(RXBuffer,0,RXBUFFER_LEN); //清空接收缓冲
sendString(USART2,"AT\r\n"); //发送AT握手指令
while(findStr(RXBuffer,"OK",500)==0)//ESP8266正常
{
sendString(USART2,"AT\r\n");
Delay_ms(500);
} //ESP8266不正常
}
// if(findStr(RXBuffer,"OK",500)==1)//ESP8266正常
// {
//// sendString(USART2,"AT\r\n");
//// Delay_ms(500);
// LED_1(ON);
// } //ESP8266不正常
//}
/**
* 功能:连接热点
* 参数:
* ssid:热点名
* pwd:热点密码
* 返回值:
* 连接结果,非0连接成功,0连接失败
* 说明:
* 失败的原因有以下几种(UART通信和ESP8266正常情况下)
* 1. WIFI名和密码不正确
* 2. 路由器连接设备太多,未能给ESP8266分配IP
*/
void connectAP(u8* ssid,u8* pwd)
{
memset(RXBuffer,0,RXBUFFER_LEN);
sendString(USART2,"AT+CWMODE?\r\n"); //查询此时WIFI工作模式
if(findStr(RXBuffer,"CWMODE:1",200)==0) //如果此时不是MODE1模式,即不是STATION模式
{
memset(RXBuffer,0,RXBUFFER_LEN);
sendString(USART2,"AT+CWMODE_CUR=1\r\n"); //设置为STATION模式
if(findStr(RXBuffer,"OK",200)==0)
{
sendString(USART2,"AT+CWMODE_CUR=1\r\n"); //设置为STATION模式
Delay_ms(800);
}
sendString(USART2,"AT+RST\r\n"); //重启ESP8266
}
memset(TXBuffer,0,RXBUFFER_LEN); //清空发送缓冲
memset(RXBuffer,0,RXBUFFER_LEN); //清空接收缓冲
sprintf(TXBuffer,"AT+CWJAP_CUR=\"%s\",\"%s\"\r\n",ssid,pwd);//连接目标AP
sendString(USART2,TXBuffer);
while(findStr(RXBuffer,"OK",800)==0) //连接成功且分配到IP
{
sendString(USART2,TXBuffer);
Delay_ms(800);
}
}
/**
* 功能:使用指定协议(TCP/UDP)连接到服务器
* 参数:
* mode:协议类型 "TCP","UDP"
* ip:目标服务器IP
* port:目标是服务器端口号
* 返回值:
* 连接结果,非0连接成功,0连接失败
* 说明:
* 失败的原因有以下几种(UART通信和ESP8266正常情况下)
* 1. 远程服务器IP和端口号有误
* 2. 未连接AP
* 3. 服务器端禁止添加(一般不会发生)
*/
void connectServer(u8* mode,u8* ip,u16 port)
{
memset(RXBuffer,0,RXBUFFER_LEN);
memset(TXBuffer,0,RXBUFFER_LEN);
sendString(USART2,"+++"); //多次连接需退出透传
Delay_ms(500);
/*格式化待发送AT指令*/
sprintf(TXBuffer,"AT+CIPSTART=\"%s\",\"%s\",%d\r\n",mode,ip,port);
sendString(USART2,TXBuffer);
while(findStr(RXBuffer,"CONNECT",800)==0)
{
sendString(USART2,TXBuffer);
Delay_ms(800);
}
memset(RXBuffer,0,RXBUFFER_LEN);
sendString(USART2,"AT+CIPMODE=1\r\n"); //设置为透传模式
while(findStr(RXBuffer,"OK",300)==0)
{
sendString(USART2,"AT+CIPMODE=1\r\n");
Delay_ms(300);
}
memset(RXBuffer,0,RXBUFFER_LEN);
sendString(USART2,"AT+CIPSEND\r\n");//开始处于透传发送状怿
// while(findStr(RXBuffer,">",200)==0)
// {
//
// }
}
/**
* 功能:透传模式下的数据发送函数
* 参数:
* buffer:待发送数据
* 返回值:None
*/
void sendBuffertoServer(u8* buffer)
{
memset(RXBuffer,0,RXBUFFER_LEN);
sendString(USART2,buffer);
}
//串口中断函数
void USART2_IRQHandler(void)
{
static u8 i = 0;
if(USART_GetITStatus(USART2, USART_IT_RXNE)) //判断接收数据寄存器是否有数据
{
RXBuffer[i++] = USART_ReceiveData(USART2);
if(i==RXBUFFER_LEN) //超出接收缓冲范围,可能的情形是ESP8266复位,为防止溢出必须设置索引
{
i = RXBUFFER_LEN-1;
}
}
if(USART_GetITStatus(USART2, USART_IT_IDLE))
{
USART_ReceiveData(USART2); //读一次UART可以清除空闲标志位
i = 0;
processDeviceStatus(&device);
}
}
运行结果及报错内容
发现灯在initESP8266();后不能点亮
我的解答思路和尝试过的方法
以为是模块损坏,用wifi模块直接连接电脑,用串口助手手动发送可以实现目的。但是用串口2在内部发送的时候却不能达到目的。检查了硬件连接,没有错误。
我将wifi初始化中的循环去掉,wifi还是没有连接上TLINK
后面重新写了初始化ESP8266的程序
void initESP8266()
{
Usart_SendStr(USART2, "+++");//退出透传
Delay_ms(500);
Usart_SendStr(USART2,"AT\r\n"); //发送AT握手指令
Delay_ms(500);
Usart_SendStr(USART2,"AT+CWMODE_CUR=1\r\n"); //设置为STATION模式
Delay_ms(800);
Usart_SendStr(USART2,"AT+RST\r\n"); //重启ESP8266
Delay_ms(3000);
Usart_SendStr(USART2,"AT+CWJAP_CUR=\"1234\",\"12345678\"\r\n");//连接目标AP
Delay_ms(800);
Usart_SendStr(USART2,"AT+CIPSTART=\"TCP\",\"tcp.tlink.io\",8647\r\n");//连接平台
Delay_ms(800);
Usart_SendStr(USART2,"AT+CIPMODE=1\r\n");
Delay_ms(200);
Usart_SendStr(USART2,"AT+CIPSEND\r\n");
Delay_ms(200);
Usart_SendStr(USART2,"HQ6XWWY8N1EJ4H5G\r\n");//连接平台
Delay_ms(800);
}
```c
//发送字符串
void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data)
{
USART_SendData(pUSARTx, data);
while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
}
/* 发送两个字节的数据 */
void Usart_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data)
{
uint8_t temp_h,temp_l;
temp_h = (data&0xff00) >> 8 ;
temp_l = data&0xff;
USART_SendData(pUSARTx, temp_h);
while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
USART_SendData(pUSARTx, temp_l);
while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
}
/* 发送8位数据的数组 */
void Usart_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint8_t num)
{
uint8_t i;
for( i=0; i<num; i++ )
{
Usart_SendByte(pUSARTx, array[i]);
}
while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );
}
/* 发送字符串 */
void Usart_SendStr(USART_TypeDef* pUSARTx, uint8_t *str)
{
uint8_t i=0;
do
{
Usart_SendByte(pUSARTx, *(str+i));
i++;
}while(*(str+i) != '\0');
while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );
}
我想要达到的结果
wifi初始化成功