当前位置:   article > 正文

STM32+esp8266实现单片机与服务器的WiFi通信_基于stm32、esp8266及ov7670的无线图传下位机源码

基于stm32、esp8266及ov7670的无线图传下位机源码

更新源码:

         源码已上传至gitee:

stm32: 一些stm32模块使用经验记录 - Gitee.comicon-default.png?t=N7T8https://gitee.com/lrf1125962926/stm32/tree/esp8266wifi%E9%80%9A%E4%BF%A1/

设计概述:        

        本实验采用STM32F1系列+esp8266 01s模块,采用HAL库开发。主控芯片哪个系列和型号都可以,只要有两个串口(UART或者USART,以下统称串口)就行。把串口配置好,  可以直接移植使用。

        很多博主都写过STM32+esp8266的文章,但大部分都只讲一种用法或者介绍的比较模糊,翻了很多都没看懂到底要怎么操作这个WiFi模块,于是就自己埋头扒了几天官方文档,大致理了一个通用模型,把模块的工作模式分为5个,WiFi状态分为3个。

                         

 至于为什么分为5种模式,是参考了官方的测试文档:

                                        

         在开始写代码前,我建议各位先用esp-link(固件烧录器,没有就买一个,便宜,实在不想要也行,用TTL转串口)接上模块,连接电脑,用串口把指令熟悉一下,把这5种模式过一遍,文档地址:

4B-ESP8266__AT Command Examples__CN (espressif.com.cn)icon-default.png?t=N7T8https://www.espressif.com.cn/sites/default/files/documentation/4b-esp8266_at_command_examples_cn.pdf这样模块的大致工作流程就清楚了,代码写起来才条理清晰。

        因为要使用服务器和客户端,电脑可以使用NetAssist,软件很好找;手机端应用商店搜TCP,大部分都能用,最好是有4个选项,TCP的服务器和客户端,UDP的服务器和客户端。

        建议大家电脑端和手机端配合使用,电脑端建服务器,手机和esp连;手机建服务器,电脑和esp连;esp建服务器,电脑和手机连。

代码设计框架:

        代码整体需要对3个部分进行编写,串口1,串口2,esp模块。

 串口:

由于HAL库有回调机制,串口2的中断回调函数就放在了串口1

串口1和2大致相同,采用正点原子的设计,有缓冲数组和接收完成标志位。

串口2要做一点调整:

         将原来的部分注释,增加新的接收条件。这个主要是因为esp的AT指令在末尾要加上回车换行才能生效,每次模块返回的数据不知为啥又以回车换行开始,索性我就直接丢弃。

        串口的代码可以从正点原子的例程中拷贝,都一样。注意要理解清楚接收完成标志位的含义,这个标志位的不同bit设计很巧妙,用好了事半功倍。

esp8266:

初始化函数:
  1. /**
  2. * @brief esp8266wifi模块初始化
  3. * @param RUNmode:1为单连接TCP,esp做客户端;
  4. * 2为UDP传输;
  5. * 3为TCP透传;
  6. * 4为UDP透传;
  7. * 5为多连接TCP,esp做服务器;
  8. * @param wifi_mode: 1为Station 模式,连接外部wifi
  9. * 2为SoftAP 模式,开启热点
  10. * 3为SoftAP+Station 双模式
  11. * @note 检测IP是否获得:AT+CIFSR
  12. * 若要更换模块使用方式,重新调用初始化即可
  13. * 模块只有在RUNmode为模式5开启服务器后才能作为服务器,其余均为Station客户端
  14. *
  15. * @retval 0为错误,1为初始化完成
  16. */
  17. uint8_t esp8266_Init(uint8_t RUNmode,uint8_t wifi_mode)

         1、就从初始化函数开始,这是这个project集成度最高的函数,调用了所有底层函数。这个函数的逻辑就是按照参考手册给的指令集,根据传参RUNmode的值,分别对应5种运行模式进行初始化。

        2、 开头定义变量,进行常规配置,因为可能每次用到的模式不同,所以在开头加了恢复出厂设置(复位模块,这里用的函数调用),关闭回显和IP显示看个人喜好,回显就是发送指令后,模块会先返回收到的指令,再返回响应值。

  1. uint8_t ERROR_count=0;//ERROR_count用于计数错误时的尝试次数
  2. uint8_t esp_state=esp8266_OK;//获取当前的工作模式
  3. char temp1[MAX_temp_array];//用于字符串连接
  4. esp8266wifi_working_mode=RUNmode;//保存全局工作模式
  5. printf("\r\nESP8266wifi模块正在初始化\r\n");
  6. esp8266wifi_reset();//复位模块
  7. esp8266wifi_send_cmd("ATE0",0,normal_waittime);//关闭回显
  8. esp8266wifi_send_cmd("AT+CIPDINFO=0",0,normal_waittime);//关闭显示IP和端口
  9. esp8266wifi_set_wifi_mode(wifi_mode);//设置wifi模式

        esp8266wifi_working_mode是一个全局变量,有的函数需要用到。

        这里的esp8266wifi_send_cmd函数先简单介绍一下,作用是通过串口发送数据,放到后面的底层调用来讲。第一个传参是要发送的字符串;第二个是要检查的字符串,检查模块有没有反回这个子串,这里给0是不检查返回;第三个是等待时间。 

        复位函数:

  1. /**
  2. * @brief 恢复出厂设置
  3. * @param 无
  4. * @retval 无
  5. */
  6. void esp8266wifi_reset(void)
  7. {
  8. printf("正在复位...\n");
  9. esp8266wifi_send_cmd("AT+RESTORE",0,normal_waittime);
  10. delay_ms(1000);
  11. printf("复位完成\n");
  12. }

        esp8266wifi_set_wifi_mode(wifi_mode);//设置wifi模式是一个自定义函数,发送AT+CWMODE指令。

  1. /**
  2. * @brief 设置Wi-Fi模式
  3. * @param mode: 1为Station 模式,客户端
  4. * 2为SoftAP 模式,开启热点
  5. * 3为SoftAP+Station 双模式
  6. * @retval 无
  7. */
  8. void esp8266wifi_set_wifi_mode(uint8_t mode)
  9. {
  10. switch (mode)
  11. {
  12. case 1:
  13. esp8266wifi_send_cmd("AT+CWMODE=1",0,normal_waittime);
  14. break;
  15. case 2:
  16. esp8266wifi_send_cmd("AT+CWMODE=2",0,normal_waittime);
  17. break;
  18. case 3:
  19. esp8266wifi_send_cmd("AT+CWMODE=3",0,normal_waittime);
  20. break;
  21. default:
  22. break;
  23. }
  24. }

        

        

        3、接下来就是判断WIFI模式,开启热点还是连接WIFI,sprintf的作用是合并字符串,可以百度用法,传参用到的两个宏定义,就是WiFi名字和密码。

  1. if(wifi_mode==wifi_mode_Station)//连接WIFI
  2. {
  3. sprintf(temp1,"AT+CWJAP=\"%s\",\"%s\"",SoftAP_WIFI_SSID,SoftAP_WIFI_PASSWORD);
  4. ERROR_count=0;
  5. printf("\r\n正在连接WIFI...\r\n");
  6. do//连接WIFI
  7. {
  8. esp_state=esp8266wifi_send_cmd(temp1,"OK",MAX_waittime);
  9. if(esp_state==esp8266_ERROR)
  10. {
  11. ERROR_count++;
  12. delay_ms(1000);//延时1s
  13. if(ERROR_count==esp8266_Init_Try_Time)
  14. {
  15. printf("\r\n连接WIFI失败\r\n");
  16. return esp8266_ERROR;
  17. }
  18. }
  19. }while(esp_state!=esp8266_OK);
  20. printf("\r\nWIFI连接成功\r\n");
  21. }

        这里用了一个do-while语句用来在连接失败时尝试重新连接,一定次数(esp8266_Init_Try_Time,我用的5次)后放弃并结束初始化。

        还有下面的else部分没有放,代码逻辑同理,用于设置esp的WiFi名字和密码,只要修改对应的sprintf就行,不做讲解。

        4、接下来就是模式1,根据手册指令,第一步配置 WiFi 模式我放到了初始化函数的开头,因为每个模式都需要设置;第二部连接路由器在上一张图做了讲解;第三步查询地址这里不需要;第四步连接服务器,也就是这里代码所展示的。

  1. if(RUNmode==mode_1_TCP_Client)//单连接TCP,esp做Station客户端
  2. {
  3. esp8266wifi_set_trans_mode(0);//设置为普通传输模式,非透传
  4. esp8266wifi_send_cmd("AT+CIPMUX=0",0,normal_waittime);//单连接模式
  5. sprintf(temp1,"AT+CIPSTART=\"TCP\",\"%s\",%s",esp8266wifi_TCP_IP,esp8266wifi_TCP_PORT);
  6. ERROR_count=0;
  7. printf("\r\n正在连接服务器...\r\n");
  8. do//esp作为客户端连接到服务器
  9. {
  10. esp_state=esp8266wifi_send_cmd(temp1,"CONNECTED",MAX_waittime);
  11. if(esp_state==esp8266_ERROR)
  12. {
  13. ERROR_count++;
  14. delay_ms(1000);
  15. if(ERROR_count==esp8266_Init_Try_Time)
  16. {
  17. printf("\r\n连接到服务器失败\r\n");
  18. return esp8266_ERROR;
  19. }
  20. }
  21. }while(esp_state!=esp8266_OK);
  22. printf("\r\n成功连接到服务器\r\n");
  23. }

        其中esp8266wifi_set_trans_mode(0);//设置为普通传输模式是一个自定义函数:

  1. /**
  2. * @brief 设置传输模式
  3. * @param mode: 0为普通传输模式
  4. * 1为透传模式,仅⽀持 TCP 单连接和 UDP 固定通信对端的情况
  5. * @retval 无
  6. */
  7. void esp8266wifi_set_trans_mode(uint8_t mode)
  8. {
  9. switch (mode)
  10. {
  11. case 0:
  12. esp8266wifi_send_cmd("AT+CIPMODE=0",0,normal_waittime);
  13. break;
  14. case 1:
  15. esp8266wifi_send_cmd("AT+CIPMODE=1",0,normal_waittime);
  16. break;
  17. default:
  18. break;
  19. }
  20. }

        在电脑串口测试过程中,经常会遇到某一配置未更改,以至于当前配置失败的问题,因为单片机想要加入这一识别能力比较繁琐,所以我在每种模式配置时都加入了对应的前置条件,手册没写,我这里设置一遍以防万一。

        后面的4种模式原理也都是一样,可以按着我的方法,根据手册的配置指导来写。初始化时只需要配置到连接服务器,这样esp就可以接收数据了,发送数据和接收数据作为一个单独的模块去调用。

esp发送数据:

        手册中每种模式的发送数据部分,除了透传,都是要先指定数据长度,再发送数据。但是单连接和多连接的指令也不太一样,所以我写了5种模式的发送函数,再用一个封装后的发送函数,根据初始化时的设置自动调用对应的函数。

1、模式2UDP比较有代表性:

  1. //模式2
  2. /**
  3. * @brief UDP,esp发送数据到远端
  4. * @param *data: 要发送的数据
  5. * @retval state:返回1发送成功,0则失败
  6. */
  7. uint8_t mode_2_send_date(char *Data)
  8. {
  9. uint8_t state = esp8266_OK;//发送成功状态
  10. char str1[MAX_temp_array];
  11. //发送数据
  12. if(esp8266wifi_UDP_mode==0)//远端固定
  13. {
  14. sprintf(str1,"AT+CIPSEND=%d,%d",esp8266wifi_UDP_Link_ID,strlen(Data)+2);
  15. }
  16. else if(esp8266wifi_UDP_mode==2)//远端可变
  17. {
  18. sprintf(str1,"AT+CIPSEND=%d",strlen(Data)+2);
  19. }
  20. esp8266wifi_send_cmd(str1,">",normal_waittime);
  21. state=esp8266wifi_send_cmd(Data,"SEND OK",MAX_waittime);
  22. return state;
  23. }

 2、封装函数:

  1. /**
  2. * @brief esp8266模块发送数据
  3. * @param *data:要发送的数据
  4. * @param ID:要收到数据的ID号
  5. * @retval result:返回1发送成功,0则失败
  6. */
  7. uint8_t esp8266_send_data(char *data,uint8_t ID)
  8. {
  9. uint8_t result=esp8266_OK, mode = esp8266wifi_working_mode;
  10. switch (mode)
  11. {
  12. case 1:
  13. result = mode_1_send_date(data);
  14. break;
  15. case 2:
  16. result = mode_2_send_date(data);
  17. break;
  18. case 3:
  19. case 4:
  20. mode_3_and_4_send_date(data);
  21. break;
  22. case 5:
  23. result = mode_5_send_date(data,ID);
  24. break;
  25. default:
  26. break;
  27. }
  28. return result;
  29. }

 3、透传模式的发送不太一样,需要进入透传发送状态,发送AT+CIPSEND后,模块会返回一个符号“>”,这时不需要指定长度,直接输入要发送的数据。想要退出透传状态,需要发送“+++”,具体细节查看手册。要使用这两个函数时,在透传模式初始化结束后,主函数调用即可。

  1. /**
  2. * @brief 开启透传发送
  3. * @param 无
  4. * @note 仅⽀持 TCP 单连接和 UDP 固定通信对端的情况
  5. * @retval state:返回1成功,0则失败
  6. */
  7. void esp8266_start_trans(void)
  8. {
  9. esp8266wifi_send_cmd("AT+CIPSEND",">",MAX_waittime);
  10. }
  11. /**
  12. * @brief 退出透传发送
  13. * @param 无
  14. * @retval result:返回1发送成功,0则失败
  15. */
  16. uint8_t esp8266_quit_trans(void)
  17. {
  18. uint8_t result=esp8266_OK;
  19. esp8266wifi_send_string("+++");
  20. delay_ms(1000);
  21. result=esp8266wifi_send_cmd("AT","OK",MAX_waittime);
  22. if(!result)
  23. printf("quit_trans failed!");
  24. else
  25. printf("quit_trans success!");
  26. return result;
  27. }
esp接收数据:

        在串口发送数据时可以看到,使用非透传模式下的信息传输,esp在接收到数据后会向串口返回+IPD,<link ID>,数据长度:数据。在多连接下才有<link ID>。在透传模式下直接取出串口缓冲数组,在其他模式下做相应的数据截取。

  1. /**
  2. * @brief 接收数据处理,对esp8266返回的数据进行解码,并清除串口接收完成标志位
  3. * @param *true_data:接收到的有效数据
  4. * @note 以下是esp8266返回数据的HEX显示与16进制显示,串口接收数据时,已在串口接收中断中滤除开头的0D 0A
  5. *
  6. * +IPD,4:qq
  7. * 0D 0A 2B 49 50 44 2C(,) 34 3A(:) 71 71 0D 0A
  8. *
  9. * +IPD,0,4:qq
  10. * 0D 0A 2B 49 50 44 2C(,) 30 2C(,) 34 3A(:) 71 71 0D 0A
  11. *
  12. * @retval ID:发送数据的ID
  13. */
  14. uint8_t esp8266_receive_data(char *true_data,uint8_t old_date[])
  15. {
  16. uint8_t ID=0;//多连接模式的ID号
  17. uint8_t date_byte=5;//默认从第一个逗号后一位开始,逗号以前的“+IPD”和逗号都不要(+IPD,)
  18. uint8_t j,mode = esp8266wifi_working_mode;
  19. char temp[MAX_temp_array];
  20. if((mode==mode_3_TCP_transparent)||(mode==mode_4_UDP_transparent))
  21. {
  22. sprintf(true_data,"%s",(char *)old_date);
  23. }
  24. else
  25. {
  26. if(mode==mode_5_TCP_Server)//多连接模式
  27. {
  28. ID = old_date[5];
  29. }
  30. while(old_date[date_byte]!=0x3A)//冒号(:)
  31. {
  32. date_byte++;
  33. }
  34. date_byte++;//跳过冒号(:)
  35. while(old_date[date_byte]!='\0')
  36. {
  37. temp[j] = old_date[date_byte];
  38. date_byte++;
  39. j++;
  40. }
  41. temp[j] = '\0';//结束符
  42. sprintf(true_data,"%s",temp);
  43. }
  44. return ID;
  45. }
底层函数:

        1、首先是调用率最高的stm32通过串口向esp8266发送数据函数,这里需要注意的是有返回值校验部分,如果形参传值0,则不进行校验。waittime参数用于等待模块返回的时间,有新数据返回则刷新等待时间。

  1. /**
  2. * @brief 向esp8266wifi发送指令,自动加上回车换行
  3. * @param *cmd: 要发送的指令
  4. * *expect: 期望指令,检查模块返回值,查看指令执行情况,若不检查,调用时给0(不带引号)
  5. * waittime: 等待数据接收时常(ms),等待模块回应的最大时间
  6. * @retval state:应答正确返回1,0则失败
  7. */
  8. uint8_t esp8266wifi_send_cmd(char *cmd,uint8_t *expect,int waittime)
  9. {
  10. uint8_t state=0;
  11. int waittime_old=waittime;
  12. char esp8_rx_data[MAX_temp_array];
  13. char temp[MAX_temp_array];
  14. esp8266wifi_rx_sta=0;
  15. sprintf(temp,"%s\r\n",cmd);
  16. esp8266wifi_send_string(temp);
  17. while ((esp8266wifi_USART->SR & 0X40) == 0);
  18. if(waittime)
  19. {
  20. while(--waittime)
  21. {
  22. delay_ms(1);
  23. if(esp8266wifi_rx_sta&0X8000)
  24. {
  25. waittime=waittime_old;
  26. sprintf(esp8_rx_data,"%s",(char *)esp8266wifi_rx_buf);
  27. // printf("模块返回:%s\n",esp8_rx_data);
  28. if(expect)
  29. {
  30. if(esp8266wifi_check_cmd(expect,esp8_rx_data))
  31. {
  32. state=esp8266_OK;
  33. printf("模块应答正确: %s\n",expect);
  34. }
  35. }
  36. esp8266wifi_rx_sta=0;//清空接收完成标志位
  37. }
  38. }
  39. }
  40. return state;
  41. }

        2、字符串校验

  1. /**
  2. * @brief 检测应答指令
  3. * @param *str: 要验证的预期结果
  4. * @retval *strx:与预期相同返回原字符串,不同则返回NULL
  5. */
  6. uint8_t* esp8266wifi_check_cmd(uint8_t *str_target,char *str_rx)
  7. {
  8. str_rx=strstr((const char*)str_rx,(const char*)str_target);
  9. return (uint8_t *)str_rx;
  10. }

3、关闭连接函数

  1. /**
  2. * @brief 关闭当前的连接
  3. * @param ID:多连接关闭的ID,需要关闭的连接 ID 号。当 ID 为 5 时,关闭所有连接。
  4. * (开启 server 后 ID 为 5 ⽆效)
  5. */
  6. void esp8266wifi_close_connect(uint8_t ID)
  7. {
  8. uint8_t num=esp8266wifi_working_mode;//获取当前的工作模式
  9. if(num==1)//关闭单连接
  10. {
  11. esp8266wifi_send_cmd("AT+CIPCLOSE",0,MAX_waittime);//关闭单连接
  12. }
  13. else if(num==2)//关闭多连接
  14. {
  15. char str1[20];
  16. sprintf(str1,"AT+CIPCLOSE=%d",ID);
  17. esp8266wifi_send_cmd(str1,0,MAX_waittime);
  18. }
  19. }

esp8266.h:

  1. #ifndef _8266wifi_H
  2. #define _8266wifi_H
  3. #include "sys.h"
  4. #include "usart2.h"
  5. /******************************************************************************************/
  6. /* 串口更改,可以改为任意配置好的USART */
  7. /*串口,接收完成标志位,接收缓冲,串口发送函数*/
  8. #define esp8266wifi_USART USART2_UX
  9. #define esp8266wifi_rx_sta g_usart2_rx_sta
  10. #define esp8266wifi_rx_buf g_usart2_rx_buf
  11. #define esp8266wifi_send_string usart2_send_string
  12. /******************************************************************************************/
  13. /*服务器wifi 信息*/
  14. /*名称,密码*/
  15. #define SoftAP_WIFI_SSID "1111111"
  16. #define SoftAP_WIFI_PASSWORD "11111111"
  17. /*esp8266作为Station客户端wifi 信息*/
  18. /*名称,密码,通道,加密方式*/
  19. /*加密方式
  20. 0:OPEN
  21. 2:WPA_PSK
  22. 3:WPA2_PSK
  23. 4:WPA_WPA2_PSK
  24. */
  25. #define esp8266wifi_WIFI_SSID "NiDie"
  26. #define esp8266wifi_WIFI_PASSWORD "12345678"
  27. #define esp8266wifi_WIFI_channal 1
  28. #define esp8266wifi_WIFI_encoding 4
  29. /******************************************************************************************/
  30. /*TCP传输信息*/
  31. /*esp作为SoftAP服务器的IP和端口信息*/
  32. #define esp8266wifi_SoftAP_IP "192.168.4.1"
  33. #define esp8266wifi_SoftAP_PORT "8080"
  34. /*esp作为Station客户端,要接入的服务器IP和端口信息*/
  35. #define esp8266wifi_TCP_IP "192.168.1.111"
  36. #define esp8266wifi_TCP_PORT "8081"
  37. /******************************************************************************************/
  38. /*UDP传输信息*/
  39. /*UDP远端和TCP的服务器使用同一组IP和端口,方便调试*/
  40. /*IP,远程端口,连接ID,本地端口,端口保持*/
  41. #define esp8266wifi_UDP_IP "192.168.1.113"
  42. #define esp8266wifi_UDP_SoftAP_PORT "8081"
  43. #define esp8266wifi_UDP_Link_ID 4
  44. #define esp8266wifi_UDP_Local_PORT "1112"
  45. #define esp8266wifi_UDP_mode 2
  46. /*
  47. ‣ 0:收到数据后,不更改远端⽬标,默认值为 0
  48. ‣ 1:收到数据后,改变⼀次远端⽬标
  49. ‣ 2:收到数据后,改变远端⽬标
  50. */
  51. /*0 表示当前 UDP 传输建⽴后,UDP 远端不会被其他设备更改;即使有其他设备通过 UDP 协议发数据到
  52. ESP8266 UDP 端⼝ 1112,ESP8266 的第 4 号 UDP 传输的远端也不会被替换,使⽤指令
  53. “AT+CIPSEND=4, X” 发送数据,仍然是当前固定的 PC 端收到。*/
  54. /*2 表示当前 UDP 传输建⽴后,UDP 传输远端仍然会更改;UDP 传输远端会⾃动更改为最近⼀个与
  55. ESP8266 UDP 通信的远端。*/
  56. /*********************************************************************************************/
  57. /*变量定义*/
  58. /*数组最大值,等待回复时间,不校验时的等待时间*/
  59. #define MAX_temp_array 200
  60. #define MAX_waittime 3000
  61. #define normal_waittime 200
  62. /*工作模式*/
  63. extern uint8_t esp8266wifi_working_mode;
  64. /*初始化错误时的尝试次数*/
  65. #define esp8266_Init_Try_Time 5
  66. /*********************************************************************************************/
  67. /*底层函数*/
  68. uint8_t* esp8266wifi_check_cmd(uint8_t *str_target,char *str_rx);
  69. void esp8266wifi_reset(void);
  70. void esp8266wifi_set_trans_mode(uint8_t mode);
  71. void esp8266wifi_set_wifi_mode(uint8_t mode);
  72. uint8_t esp8266wifi_send_cmd(char *cmd,uint8_t *expect,int waittime);
  73. void esp8266wifi_close_connect(uint8_t ID);
  74. /*5种模式发送数据,可单独调用*/
  75. uint8_t mode_1_send_date(char *data);
  76. uint8_t mode_2_send_date(char *Data);
  77. uint8_t mode_2_send_date_IP(char *Data,char *SendIP,uint16_t SendPort);
  78. void mode_3_and_4_send_date(char *data);
  79. uint8_t mode_5_send_date(char *Data,uint8_t Link_ID);
  80. /*********************************************************************************************/
  81. /*用户调用函数*/
  82. void esp8266_start_trans(void);
  83. uint8_t esp8266_quit_trans(void);
  84. uint8_t esp8266_Init(uint8_t RUNmode,uint8_t wifi_mode);
  85. uint8_t esp8266_send_data(char *data,uint8_t ID);
  86. uint8_t esp8266_receive_data(char *true_data,uint8_t old_date[]);
  87. /*********************************************************************************************/
  88. /*初始化函数传参定义*/
  89. /*工作模式定义*/
  90. #define mode_1_TCP_Client 1
  91. #define mode_2_UDP 2
  92. #define mode_3_TCP_transparent 3
  93. #define mode_4_UDP_transparent 4
  94. #define mode_5_TCP_Server 5
  95. /*wifi模式:1为连接模式,2为热点模式,3为双开*/
  96. #define wifi_mode_Station 1
  97. #define wifi_mode_SoftAP 2
  98. #define wifi_mode_SoftAP_Station 3
  99. /*返回值状态*/
  100. #define esp8266_OK 1
  101. #define esp8266_ERROR 0
  102. #endif

主函数main.c:

        目的是在于检查信息的发送是否正确,电脑串口控制esp进行数据的发送和读取。

  1. int main(void)
  2. {
  3. HAL_Init(); /* 初始化HAL库 */
  4. sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
  5. delay_init(72); /* 延时初始化 */
  6. usart_init(115200); /* 初始化串口 */
  7. led_init(); /* 初始化LED */
  8. // OLED_Init();
  9. usart2_init(115200);
  10. if(esp8266_Init(mode_1_TCP_Client,wifi_mode_Station)==esp8266_OK)
  11. {
  12. printf("\r\nesp8266 模式 %d 初始化完成!\r\n",mode_1_TCP_Client);
  13. }
  14. else
  15. {
  16. printf("\r\nesp8266初始化失败\r\n");
  17. while(1)
  18. {
  19. LED0_TOGGLE();
  20. delay_ms(200);
  21. }
  22. }
  23. char rx_data[128];
  24. uint8_t ID=0;
  25. while (1)
  26. {
  27. if(esp8266wifi_rx_sta&0X8000)//esp收到的信息通过串口一打印
  28. {
  29. printf("\nGot Date!\n");
  30. ID = esp8266_receive_data(rx_data,esp8266wifi_rx_buf);
  31. if(ID)
  32. {
  33. printf("ID :%d,收到的信息: %s\n",ID,rx_data);
  34. }
  35. else
  36. {
  37. printf("收到的信息: %s\n",rx_data);
  38. }
  39. esp8266wifi_rx_sta=0;
  40. }
  41. if(g_usart_rx_sta&0X8000) //串口一收到的信息发送到esp
  42. {
  43. while ((USART_UX->SR & 0X40) == 0); /* 等待上一个字符发送完成 */
  44. esp8266_send_data((char *)g_usart_rx_buf,ID);
  45. // printf("%s\n",g_usart_rx_buf);
  46. g_usart_rx_sta = 0;
  47. }
  48. LED0_TOGGLE();
  49. delay_ms(500);
  50. }
  51. }

实验现象:

        开始实验前要打开电脑端的服务器,这里初始化用的模式1。等待初始化完成即可发送信息。网络助手和esp进行数据通信。

 

 总结:

本次实验有很多可以改进的地方,比如等待时间长,初始化时间也长。但是有点懒,就放着吧。读者有什么建议都可以找我,有问题的还请指正。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/37374?site
推荐阅读
相关标签
  

闽ICP备14008679号