飞道的博客

STM32 (十五)ESP8266WIFI

405人阅读  评论(0)

简介

1 ESP8266wifi 模块

低功耗串口WiFi模块ESP8266内置一个Tensilica(泰思立达) Xtensa架构的32位处理器L106,具有5级流水线(ARM CortexM3是3级流水线),最大时钟速度为160MHz,可以使用高达16MB的外部SPI Flash。 该模块采用串口与MCU(或其他串口设备)通信,内置 TCP/IP协议栈,能够实现串口与 WIFI 之间的转换。通过该模块,传统的串口设备只需要简单的串口配置,即可通过WiFi传输自己的数据。

wifi模块具有两种模式:AP模式 、Station模式

AP模式:就是我们平常用的热点,如无线路由器,手机热点。

Station模式:就是我们连接这些热点的设备,如手机,iPad,笔记本电脑。

2AT命令介绍

我们想要与esp8266wifi模块进行通信,那么就需要AT命令进行。就好比我们要和英国国人进行交流时,我们就要用英语交流。在这里,就需要用到esp8266的AT指令进行和pc之间的通信。

AT 即Attention,它由拨号调制解调器(Modem)的发明者贺氏公司(Hayes)为了控制Modem发明的控制协议。协议本身采用文本,每个命令均以AT打头,因此得名。90年代初,AT指令仅被用于Modem操作。

几年后,主要的移动电话生产厂商诺基亚、爱立信、摩托罗拉和HP共同为GSM 研制了一整套AT指令,其中就包括对SMS的控制。AT指令在此基础上演化并被加入GSM 07.05标准以及现在的GSM07.07标准,其中拨打电话、收发短信、收发传真等全部由AT命令实现。而在随后的GPRS控制,3G模块,以及工业上常用的PDU,均采用AT命令集来控制,这样AT指令也就成为了完全标准化和比较健全的标准。

3AT命令格式

AT指令是以AT作为开头,\r\n字符结束的字符串,每个指令执行成功与否都有相应的返回。其他的一些非预期的信息(如有人拨号进来、线路无信号等),模块将有对应的一些信息提示,接收端可做相应的处理。

注意:不同模块的AT命令可能不一样的,这要对着模块的AT指令手册来查看。可以通过esp8266应答的信息来判断你们之间是否建立通信了。(每当发送一个AT指令之后,相应地就会在结尾给PC发 OK或者ERROR)

4 常用的AT指令

这里讲解一下我们ESP8266 01S常用的AT指令:

4.1.AT+RST

重启、复位ESP8266命令

4.2.AT

AT确认模块是否正常工作

4.3.AT+CWMODE_CUR=1

设置WiFi为Station模式和使能DHCP服务

4.4 AT+CWJAP_CUR=“输入WiFiID”

输入路由器连接密码” 连接无线路由器

4.5 AT+CWJAP_CUR=“输入WiFiID”

4.6 AT+CIPSERVER=1,8080",

设置端口8080

工程创建

1 高速时钟选择外部8Mhz的晶振

2 开启debug调试功能

3 时钟树

4 打开串口2设置

5 并且使能串口中断

6.选择LED

7选择MDK_ARM编译器

8生成文件库的选择

代码讲解:

代码修改

1 添加My_esp8266.c


   
  1. #include "My_esp8266.h"
  2. #include "string.h"
  3. #include "usart.h"
  4. void u2_printf(char* fmt);
  5. char esp8266_send_cmd(char *cmd,char *ack,u16 waittime);
  6. void esp8266_test(void)//测试
  7. {
  8. if( esp8266_send_cmd( "AT", "OK", 50));
  9. }
  10. char esp8266_send_cmd(char *cmd,char *ack,u16 waittime)//发送指令和检查接收
  11. {
  12. u2_printf(cmd);
  13. if(ack&&waittime)
  14. {
  15. while(--waittime)
  16. {
  17. HAL_Delay( 10);
  18. if( strstr(( const char*)RxBuffer,( const char*)ack)) //输入on,LED0亮
  19. {
  20. Uart2_Rx_Cnt= 0;
  21. memset(RxBuffer, 0x00, sizeof(RxBuffer)); //清空数组
  22. return 1;
  23. }
  24. }
  25. }
  26. return 0;
  27. }
  28. void esp8266_start_trans(void)//ESP8266初始化
  29. {
  30. esp8266_send_cmd( "AT+CWMODE=2", "OK", 50); //设置为AP模式
  31. esp8266_send_cmd( "AT+RST", "ready", 20); //重启
  32. HAL_Delay( 1000);
  33. HAL_Delay( 1000);
  34. HAL_Delay( 1000);
  35. HAL_Delay( 1000);
  36. esp8266_send_cmd( "AT+CWSAP=\"ESP8266\",\"12345678\",1,4", "OK", 200); //设置WiFi名称、密码,模式
  37. esp8266_send_cmd( "AT+CIPMUX=1", "OK", 20); //进入透传模式
  38. esp8266_send_cmd( "AT+CIPSERVER=1,8080", "OK", 200); //设置端口8080
  39. esp8266_send_cmd( "AT+CIPSEND", "OK", 50); //开始发送数据
  40. }
  41. uint8_t esp8266_quit_trans(void)//退出透传模式
  42. {
  43. uint8_t result= 1;
  44. u2_printf( "+++");
  45. HAL_Delay( 1000);
  46. result= esp8266_send_cmd( "AT", "OK", 20);
  47. return result;
  48. }
  49. void u2_printf(char* fmt)
  50. {
  51. uint8_t num= 0;
  52. char my_ch[ 50]={ 0};
  53. while(*fmt!= 0)
  54. my_ch[num++]=*fmt++;
  55. my_ch[num++]= '\r';
  56. my_ch[num++]= '\n';
  57. HAL_UART_Transmit(&huart2, ( uint8_t *)my_ch,num, 0xffff);
  58. while( HAL_UART_GetState(&huart2) == HAL_UART_STATE_BUSY_TX);
  59. }

2.添加My_esp8266.h


   
  1. #ifndef __My_esp8266_H__
  2. #define __My_esp8266_H__
  3. #include "main.h"
  4. typedef uint16_t u16 ;
  5. extern void esp8266_test(void);
  6. extern void u2_printf(char* fmt);
  7. extern char esp8266_send_cmd(char *cmd,char *ack,u16 waittime);
  8. extern void esp8266_start_trans(void);
  9. #endif

3.main.h的Exported types中添加代码


   
  1. /* USER CODE BEGIN ET */
  2. extern char RxBuffer[ 256];
  3. extern uint8_t Uart2_Rx_Cnt;
  4. /* USER CODE END ET */

4.main.c的Private includes中添加代码


   
  1. /* USER CODE BEGIN Includes */
  2. #include <string.h>
  3. #include "My_esp8266.h"
  4. /* USER CODE END Includes */

5. main.c的Private variables中添加代码


   
  1. /* USER CODE BEGIN PV */
  2. #define RXBUFFERSIZE 256 //最大接收字节数
  3. char RxBuffer[RXBUFFERSIZE]; //接收数据
  4. uint8_t aRxBuffer; //接收中断缓冲
  5. uint8_t Uart2_Rx_Cnt = 0; //接收缓冲计数
  6. uint8_t my_test_v = 0 ;
  7. char my_order[ 15]={ 0};
  8. char receive_flag= 0;
  9. /* USER CODE END PV */

6.main.c主函数下面的USER CODE BEGIN 4下面添加中断回调函数,如下


   
  1. /* USER CODE BEGIN 4 */
  2. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  3. {
  4. /* Prevent unused argument(s) compilation warning */
  5. UNUSED(huart);
  6. /* NOTE: This function Should not be modified, when the callback is needed,
  7. the HAL_UART_TxCpltCallback could be implemented in the user file
  8. */
  9. if(Uart2_Rx_Cnt >= 255) //溢出判断
  10. {
  11. Uart2_Rx_Cnt = 0;
  12. memset(RxBuffer, 0x00, sizeof(RxBuffer));
  13. }
  14. else
  15. {
  16. static uint8_t Uart2_count= 0;
  17. RxBuffer[Uart2_Rx_Cnt] = aRxBuffer; //接收数据转存
  18. if(receive_flag== 0)
  19. {
  20. if(RxBuffer[Uart2_Rx_Cnt-Uart2_count]== '<')
  21. {
  22. Uart2_count++;
  23. if((RxBuffer[Uart2_Rx_Cnt]== '>')||Uart2_count>= 14)
  24. {
  25. uint8_t My_i= 0;
  26. for( int i=Uart2_Rx_Cnt-Uart2_count+ 1;i<Uart2_Rx_Cnt+ 1;i++)
  27. my_order[My_i++]=RxBuffer[i];
  28. receive_flag= 1;
  29. Uart2_count= 0;
  30. }
  31. }
  32. }
  33. Uart2_Rx_Cnt++;
  34. }
  35. HAL_UART_Receive_IT(&huart2, ( uint8_t *)&aRxBuffer, 1); //再开启接收中断
  36. }
  37. /* USER CODE END 4 */

7.主函数代码


   
  1. int main(void)
  2. {
  3. /* USER CODE BEGIN 1 */
  4. /* USER CODE END 1 */
  5. /* MCU Configuration--------------------------------------------------------*/
  6. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  7. HAL_Init();
  8. /* USER CODE BEGIN Init */
  9. /* USER CODE END Init */
  10. /* Configure the system clock */
  11. SystemClock_Config();
  12. /* USER CODE BEGIN SysInit */
  13. /* USER CODE END SysInit */
  14. /* Initialize all configured peripherals */
  15. MX_GPIO_Init();
  16. MX_USART2_UART_Init();
  17. /* USER CODE BEGIN 2 */
  18. HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET );
  19. HAL_UART_Receive_IT(&huart2, ( uint8_t *)&aRxBuffer, 1);
  20. esp8266_start_trans();
  21. /* USER CODE END 2 */
  22. /* Infinite loop */
  23. /* USER CODE BEGIN WHILE */
  24. while ( 1)
  25. {
  26. // HAL_Delay(20);
  27. if(receive_flag)
  28. {
  29. receive_flag= 0;
  30. if( strstr(( const char*)my_order,( const char*) "<on>")) //输入on,LED0亮
  31. {
  32. Uart2_Rx_Cnt= 0;
  33. memset(RxBuffer, 0x00, sizeof(RxBuffer)); //清空数组
  34. memset(RxBuffer, 0x00, sizeof(my_order)); //清空数组
  35. my_test_v= 1;
  36. }
  37. else if( strstr(( const char*)my_order,( const char*) "<off>"))
  38. {
  39. Uart2_Rx_Cnt= 0;
  40. memset(RxBuffer, 0x00, sizeof(RxBuffer)); //清空数组
  41. memset(RxBuffer, 0x00, sizeof(my_order)); //清空数组
  42. my_test_v= 0;
  43. }
  44. else
  45. {
  46. Uart2_Rx_Cnt= 0;
  47. memset(RxBuffer, 0x00, sizeof(RxBuffer)); //清空数组
  48. memset(RxBuffer, 0x00, sizeof(my_order)); //清空数组
  49. }
  50. }
  51. if(my_test_v== 1)
  52. HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_RESET );
  53. else
  54. HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,GPIO_PIN_SET );
  55. /* USER CODE END WHILE */
  56. /* USER CODE BEGIN 3 */
  57. }
  58. /* USER CODE END 3 */
  59. }

手机端控制

1.esp8266和核心板的连接只需要四个引脚,vcc(3.7—5v的稳定电源,不稳定的话会不断重启),gnd,rx,tx。其中,模块的rx接核心板的tx,tx接核心板的rx。

2. 初始化(4s)后,模块就会发出名字为esp8266的热点,密码为12345678。

3 手机接入后打开“tcp连接”app(这个热点没有网络,有些手机连接后一会儿后自动就断开了,所以要设置下,我是直接把数据流量关了就行了)

4 连接(IP地址一般是192.168.4.1不正确的话需要用串口助手给wifi模块发送AT指令查看连接设备的地址,当然也可以程序上发送后在线调试看数组)

5 发送数据,记住要加英文输入法的“<>”,就能控制灯的亮灭了。

需要注意的是,esp8266wifi模块相当于一个下好程序的核心板,你只需要通过给它发送串口的AT指令来进行控制它的各种动作。初始化也不是对引脚初始化,是通过串口对它发送AT指令。所以初始化后如果不给esp8266断电的话是不用再次初始化的,因为每次初始化后重启会话4s的时间,所以想不断下程序来调试的话,可以把初始化函数(esp8266_start_trans();)注释了,就不用每次都额外等4s的时间了。


转载:https://blog.csdn.net/DOF526570/article/details/128858934
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场