/** * author wulianwei * title ESP8266模块驱动 */ #include "stm32f10x.h" //网络设备驱动 #include "esp8266.h" #include "sys.h" #include "module_wrapper.h" #include "at.h" //C库 #include #include extern uart_recv_t uart_recv; extern uint8 tcp_connect_status; extern valid_data_t valid_data; //========================================================== // 函数名称: esp8266_send_data // // 函数功能: 发送数据 // // 入口参数: data:数据(数组) // len:长度 // // 返回参数: 无 // // 说明: //========================================================== static int esp8266_send_data(const void *data, int len) { char cmdBuf[SEND_SIZE]={0}; uart_recv_clear(); //清空接收缓存 //esp8266_tcp_reconnect(); snprintf(cmdBuf,SEND_SIZE,"AT+CIPSEND=%d\r\n", len); //发送命令 if(!at_send_cmd(cmdBuf, ">")) //收到‘SEND OK’时可以发送数据 { // Usart_SendString(USART2, data, len); //发送设备连接请求数据 if(!at_send_byte((char*)data,len,"SEND OK")) { return 0; } } return -1; } //========================================================== // 函数名称: esp8266_get_data // // 函数功能: 获取平台返回的数据 // // 入口参数: data:存储有效数据(数组),len:有效数据长度,timeOut:等待的时间(ms) // // 返回参数: 平台返回的原始数据 // // 说明: 不同网络设备返回的格式不同,需要去调试 //========================================================== static int esp8266_get_data(void *data,int len,int timeOut) { int minLen = 0; char *recvdiff[4] = {0};//分割字符串地址 char recvbuf[RECV_SIZE] = {0}; int data_len = 0;//有效数据长度 char *recvSign = "+IPD"; if(!uart_recv_match_wait(recvSign,timeOut)) { UsartPrintf(USART_DEBUG, "返回数据:%d,%s\r\n",uart_recv.len,uart_recv.start_addr); memcpy((char*)recvbuf, (char*)uart_recv.start_addr, uart_recv.len); split((char*)recvbuf,",",recvdiff,sizeof(recvdiff)); data_len = my_atoi(recvdiff[1]); minLen = data_len < len? data_len : len; memcpy(data,(char*)recvdiff[2],minLen); uart_recv_clear(); return data_len; } uart_recv_clear(); return -1; } //========================================================== // 函数名称: esp8266_init // // 函数功能: 初始化esp8266 // // 入口参数: 无 // // 返回参数: 0 成功 -1失败 // // 说明: //========================================================== static int esp8266_init(void) { char recv[300]; GPIO_InitTypeDef GPIO_Initure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //ESP8266复位引脚 GPIO_Initure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Initure.GPIO_Pin = GPIO_Pin_7; //GPIOA0-复位 GPIO_Initure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_Initure); GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_RESET); delay_ms(250); GPIO_WriteBit(GPIOA, GPIO_Pin_7, Bit_SET); UsartPrintf(USART_DEBUG, "1.AT\r\n"); at_send_cmd_back(AT,recv,sizeof(recv)); UsartPrintf(USART_DEBUG, "%s\r\n",recv); UsartPrintf(USART_DEBUG, "2.RESTORE\r\n"); at_send_cmd_back_wait(RESTORE,recv,sizeof(recv),1000); UsartPrintf(USART_DEBUG, "%s\r\n",recv); UsartPrintf(USART_DEBUG, "3.CWMODE\r\n"); at_send_cmd_back_wait(CWMODE,recv,sizeof(recv),500); UsartPrintf(USART_DEBUG, "%s\r\n",recv); UsartPrintf(USART_DEBUG, "4.禁止回显\r\n"); at_send_cmd_back(ATE0,recv,sizeof(recv)); UsartPrintf(USART_DEBUG, "%s\r\n",recv); if(!strstr(recv,"OK")) { UsartPrintf(USART_DEBUG,"禁止回显失败\r\n"); return -1; } UsartPrintf(USART_DEBUG, "5.禁止休眠\r\n"); at_send_cmd_back(NSLEEP,recv,sizeof(recv)); UsartPrintf(USART_DEBUG, "%s\r\n",recv); UsartPrintf(USART_DEBUG, "6.连接WiFi\r\n"); at_send_cmd_back_wait(CWJAP,recv,sizeof(recv),6000); UsartPrintf(USART_DEBUG, "%s\r\n",recv); if(!strstr(recv,"WIFI GOT IP")) { UsartPrintf(USART_DEBUG,"连接WiFi失败\r\n"); return -1; } UsartPrintf(USART_DEBUG, "\r\n ESP8266 初始化完成\r\n"); return 0; } /** * @Title TCP连接 * @Param ip:地址, port:端口 * @Return 0:成功,-1:失败 */ static void esp8266_tcp_connect(const char *ip, const char *port) { char conCmd[200]={0}; UsartPrintf(USART_DEBUG, "连接TCP服务器\r\n"); snprintf(conCmd,sizeof(conCmd),CIPSTART,ip,port); at_send_simple_cmd(conCmd); tcp_connect_status = TCP_CONNECTING; } /** * @Title TCP通道关闭 * @Return 0:成功,-1:失败 */ static int esp8266_tcp_close(void) { if(at_send_cmd(CIPCLOSE,"CLOSED")) { return -1; } tcp_connect_status = TCP_CLOSED; //tcp断开 UsartPrintf(USART_DEBUG, "断开TCP服务器\r\n"); return 0; } /** * @Title 判断tcp连接状态 * @Return 0 保持连接,-1 断开连接 */ static int esp8266_tcp_state(void) { char *statebuf[8] ={0}; char recvbuf[200] = {0}; at_send_cmd_back(CIPSTATUS,recvbuf,sizeof(recvbuf)); if(strstr(recvbuf,"OK")) { if(strstr((char *)recvbuf,"STATUS:")) { split((char*)recvbuf,":",statebuf,sizeof(statebuf)); if(statebuf[1]) { if(*(statebuf[1]) == '3') { tcp_connect_status = TCP_OPEN; //tcp连接 UsartPrintf(USART_DEBUG, "TCP服务器保持链接\r\n"); return 0; } } } } tcp_connect_status = TCP_CLOSED; //tcp断开 UsartPrintf(USART_DEBUG, "TCP服务器已断开3\r\n"); return -1; } static void esp8266_tcp_reconnect(const char *ip, const char *port) { if(esp8266_tcp_state()) { UsartPrintf(USART_DEBUG, "重连服务器\r\n"); esp8266_tcp_close(); esp8266_tcp_connect(ip,port); } } static void esp8266_tcp_online_event(void) { UsartPrintf(USART_DEBUG, "esp8266_tcp_online_event\r\n"); tcp_connect_status = TCP_OPEN;// tcp在线 } static void esp8266_tcp_close_event(void) { UsartPrintf(USART_DEBUG, "esp8266_tcp_close_event\r\n"); tcp_connect_status = TCP_CLOSED; //tcp断线 } static void esp8266_wifi_reconnect_event(void) { UsartPrintf(USART_DEBUG, "esp8266_wifi_reconnect_event\r\n"); tcp_connect_status = TCP_CLOSED; //tcp断线 } static void esp8266_recv_event(void) { int minLen = 0; char *recvdiff[4] = {0};//分割字符串地址 char recvbuf[RECV_SIZE] = {0}; int data_len = 0;//有效数据长度 int valid_data_size = sizeof(valid_data.buf); uart_recv_wait(15);//有效数据返回有延迟 memcpy((char*)recvbuf,(char*)uart_recv.start_addr,uart_recv.len); split((char*)recvbuf+strlen("+IPD,"),":",recvdiff,sizeof(uart_recv.buf)); data_len = my_atoi(recvdiff[0]); minLen = data_len < valid_data_size? data_len : valid_data_size; valid_data.len = minLen; memcpy(valid_data.buf,(char*)recvdiff[1],minLen); //有效数据前后多了一个双引号 UsartPrintf(USART_DEBUG, "esp8266_recv_event\r\n"); } void esp8266_busy_event(void) { UsartPrintf(USART_DEBUG, "esp8266_busy_event:%s\r\n",uart_recv.buf); } void esp8266_error_event(void) { UsartPrintf(USART_DEBUG, "error_event:%s\r\n",uart_recv.buf); } at_event_t esp8266_at_event[] = { { "WIFI GOT IP", esp8266_wifi_reconnect_event},//wifi重连 { "CONNECT\r\n\r\nOK", esp8266_tcp_online_event}, //tcp连接成功 { "ALREADY CONNECTED", esp8266_tcp_online_event}, //tcp连接成功 //{ "CLOSED", esp8266_tcp_close_event}, //tcp断开 { "+IPD,", esp8266_recv_event}, { "busy,", esp8266_busy_event}, { "ERROR", esp8266_error_event} }; static void esp8266_handle_event(void) { int i = 0; char *start_addr; if(uart_recv.len ==0) return; //UsartPrintf(USART_DEBUG, "uart_recv buff:%s\r\n",uart_recv.buf); for(i=0;ievent_header); if(start_addr) { uart_recv.start_addr = start_addr; event->event_callback(); uart_recv_clear(); break; } } } at_module_t at_module_esp8266 = { .init = esp8266_init, .connect = esp8266_tcp_connect, .reconnect = esp8266_tcp_reconnect, .tcpstate = esp8266_tcp_state, .send = esp8266_send_data, .recv_timeout = esp8266_get_data, .close = esp8266_tcp_close, .handle_event = esp8266_handle_event, .handle_event = esp8266_handle_event, }; int esp8266_sal_init() { if(at_module_register(&at_module_esp8266)) { return -1; } if(at_module_init()) { return -1; } return 0; }