赞
踩
WIFI模块ESP-01S
使用AT指令控制1-ESP8266-AT指令初试化及部分基础知识_ch_pd-CSDN博客
通过ESP-01SWIFI模块控制LED状态模拟插座
串口1用于与ESP8266通讯,串口2连接PC,用于打印log,查看系统状态
将WIFI模块的TX和RX分别接到单片机的RX1和TX1
将CH340的TXD和RXD分别接到单片机的RX2和TX2
1. 在这个项目里,烧写完单片机之后,不光要点击复位,还要重启单片机电源,以确保WIFI模块重新启动
2. 在以后的工作中一般不直接在中断服务函数里处理数据,而是在收到数据后直接丢给队列,再处理数据
3. 在中断服务函数里尽量减少使用延时函数及打印函数
4. 2,3条在本项目中并没有实现,因为还没有学到Linux的队列概念,只是先留个印象
5. 由于之前的WIFI模块波特率改成了9600,所以现在连接CH340修改回 115200(使用AT指令修改)
CubeMX
1. 惯例配置(时钟,gpio,系统时钟)
2. 打开两个串口(uart1和uart2),并在WIFI模块对应的串口1打开中断
3. 由于在中断处理函数中使用了Delay函数,得调整中断的优先级(非必要不使用,容易造成未知错误)
4. 惯例配置,导出工程(路径,编程软件)
Keil
要在魔术棒中将MiroLIB勾选,使得可以重写printf
代码:
- #include <stdio.h>
- #include <string.h>
-
- //串口接收缓存(1字节)
- uint8_t buf=0;
-
- //定义最大接收字节数 200,可根据需求调整
- #define UART1_REC_LEN 200
-
- // 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节
- uint8_t UART1_RX_Buffer[UART1_REC_LEN];
-
- // 接收状态
- // bit15, 接收完成标志
- // bit14, 接收到0x0d
- // bit13~0, 接收到的有效字节数目
- uint16_t UART1_RX_STA=0;
-
- char buffer[12];
-
- char connect_net[] = "AT+CWJAP=\"bbb\",\"56893233\"\r\n"; //入网指令 \r\n新行
- char connect_servere[] = "AT+CIPSTART=\"TCP\",\"192.168.93.248\",8880\r\n";//连接服务器指令
-
-
- char Transparent_mode[] = "AT+CIPMODE=1\r\n"; //透传模式指令
- char data_transmission[] = "AT+CIPSEND\r\n"; //数据传输开始指令 //数据传输
- char reset[] = "AT+RST\r\n"; //重启模块指令
- char AT_OK_flag = 0; //OK返回值的标志位
- char AT_Connect_Net_Flag = 0; //WIFI GOT IP返回值的标志位
-
-
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
- {
- // 判断中断是由哪个串口触发的
- if(huart->Instance == USART1)
- {
- // 判断接收是否完成(UART1_RX_STA bit15 位是否为1)
- if((UART1_RX_STA & 0x8000) == 0)
- {
- // 如果已经收到了 0x0d (回车),
- if(UART1_RX_STA & 0x4000)
- {
- // 则接着判断是否收到 0x0a (换行)
- if(buf == 0x0a)
- {
- // 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
- UART1_RX_STA |= 0x8000;
-
- //程序运行到此处,代表数据已经完整接收,可以开始判断//
-
- //查看是否收到WIFI GOT IP
- if(strcmp(UART1_RX_Buffer,"WIFI GOT IP") == 0){
- HAL_UART_Transmit(&huart2, "111\r\n",strlen("111\r\n"), 100);
- AT_Connect_Net_Flag = 1;
- }
- //查看是否收到OK
- if(strcmp(UART1_RX_Buffer,"OK") == 0){
- HAL_UART_Transmit(&huart2, "222\r\n",strlen("222\r\n"), 100);
- AT_OK_flag = 1;
- }
-
-
- //灯控指令
- if(strcmp(UART1_RX_Buffer,"open") == 0){
- HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
- }
- if(strcmp(UART1_RX_Buffer,"close") == 0){
- HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
- }
-
-
- //如果联网失败,收到FAIL
- if(!strcmp(UART1_RX_Buffer,"FAIL")){
- HAL_UART_Transmit(&huart2, "error\r\n",strlen("error\r\n"), 100);
- int i;
- for(i = 0;i <5;i++){
- HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
- HAL_Delay(1000);}
- printf(reset);
- }
-
- memset(UART1_RX_Buffer,0,UART1_REC_LEN);
- UART1_RX_STA = 0;
- }
- else
- // 否则认为接收错误,重新开始
- UART1_RX_STA = 0;
- }
- else // 如果没有收到了 0x0d (回车)
- {
- //则先判断收到的这个字符是否是 0x0d (回车)
- if(buf == 0x0d)
- {
- // 是的话则将 bit14 位置为1
- UART1_RX_STA |= 0x4000;
- }
- else
- {
- // 否则将接收到的数据保存在缓存数组里
- UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;
- UART1_RX_STA++;
-
- // 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
- if(UART1_RX_STA > UART1_REC_LEN - 1)
- UART1_RX_STA = 0;
- }
- }
- }
- // 重新开启中断
- HAL_UART_Receive_IT(&huart1, &buf, 1);
- }
- }
-
- int fputc(int ch, FILE *f)
- {//注意,printf的重写是针对串口1的,也就是wifi的,对于串口2的数据发送不能用printf
- unsigned char temp[1]={ch};
- HAL_UART_Transmit(&huart1,temp,1,0xffff);
- return ch;
- }
-
-
- int main(void)
- {
-
- HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
- // 开启接收中断
-
- HAL_UART_Receive_IT(&huart1, &buf, 1);
- HAL_UART_Transmit(&huart2, "START\r\n",strlen("START\r\n"), 100);
-
- printf(connect_net); //发送联网AT指令并等待成功
-
- while(!AT_Connect_Net_Flag) HAL_Delay(50);//此处这个delay必须得加,不然程序会卡死
- while(!AT_OK_flag) HAL_Delay(50);//此处这个delay必须得加,不然程序会卡死
- HAL_UART_Transmit(&huart2, "5555\r\n",strlen("5555\r\n"), 100);
- AT_OK_flag = 0;
-
-
- //发送连服务器指令并等待成功
- printf(connect_servere);
- while(!AT_OK_flag) HAL_Delay(50);
- HAL_UART_Transmit(&huart2, "6665\r\n",strlen("6665\r\n"), 100);
- AT_OK_flag = 0;
-
- //发送透传模式指令并等待成功
- printf(Transparent_mode);
- while(!AT_OK_flag) HAL_Delay(50);
- HAL_UART_Transmit(&huart2, "7775\r\n",strlen("7775\r\n"), 100);
- AT_OK_flag = 0;
-
-
- //发送数据传输指令并等待成功
- printf(data_transmission);
- while(!AT_OK_flag) HAL_Delay(50);
-
- while (1)
- {
-
- printf("hhhhhhhhhhhhaaaaaaaaaa");
- HAL_UART_Transmit(&huart2, "hello shion\r\n",strlen("hello shion\r\n"), 100);
-
- HAL_Delay(3000);
- }
-
- }
-
-
-
-
实验效果:
注意!要记得将服务器打开,不然一直连接不上(以至于折磨了我好长时间调试)
在电脑串口和网络调试助手可以看到不断发来的心跳包。
同时,串口1作为单片机和WIFI的通信,而串口2作为日志发回电脑的串口助手,串口1每发送并成功接收了回应,串口2就会返回电脑成功的信息,这样用户就可以可视化的看到连接进行到了哪一步,这算是用两路串口实现了以前白盒测试和黑盒测试的效果。
当在网络助手发送“open”加上回车时,继电器会打开;反之输入“close”加上回车,继电器会闭合
在这种模式下,ESP作为路由器,由电脑连接ESP的WIFI,作为Client来接收和发送。
以下是之前学习WIFI模块时总结的,关于ESP作为STA模式下的相关命令
CubeMX
同上
通过白盒测试可知:在ESP作为STA的模式下,WIFI助手发送的数据在串口中显示的是有特定格式的:
如果发送“open”加回车,那么显示的是:+IPD,0,6:open
如果发送“close”加回车,那么显示的是:+IPD,0,7:close
因此,在KEIL中的代码中,字符串的比较不能直接和open close比较,而是和以上两个字符串进行比较!!!
代码
- #include <stdio.h>
- #include <string.h>
-
- //串口接收缓存(1字节)
- uint8_t buf=0;
-
- //定义最大接收字节数 200,可根据需求调整
- #define UART1_REC_LEN 200
-
- // 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节
- uint8_t UART1_RX_Buffer[UART1_REC_LEN];
-
- // 接收状态
- // bit15, 接收完成标志
- // bit14, 接收到0x0d
- // bit13~0, 接收到的有效字节数目
- uint16_t UART1_RX_STA=0;
-
- char buffer[12];
-
- char connect_net[] = "AT+CWJAP=\"bbb\",\"56893233\"\r\n"; //入网指令 \r\n新行
-
- char mode[] = "AT+CWMODE=2\r\n"; //路由器模式指令
- char mul_con[] = "AT+CIPMUX=1\r\n"; //使能多链接
- char server[] = "AT+CIPSERVER=1\r\n"; //建立TCPServer default port = 333
- char send[] = "AT+CIPSEND=0,5\r\n"; //发送数据
- char end[] = "AT+CIPCLOSE=0\r\n"; //断开连接
-
- char AT_Connect_Net_Flag = 0; //WIFI GOT IP返回值的标志位
-
- char AT_OK_flag = 0; //OK返回值的标志位
- char Client_Connent_Flag = 0; //客户端接入返回值标志位
-
- // 接收完成回调函数,收到一个数据后,在这里处理
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
- {
- // 判断中断是由哪个串口触发的
- if(huart->Instance == USART1)
- {
- // 判断接收是否完成(UART1_RX_STA bit15 位是否为1)
- if((UART1_RX_STA & 0x8000) == 0)
- {
- // 如果已经收到了 0x0d (回车),
- if(UART1_RX_STA & 0x4000)
- {
- // 则接着判断是否收到 0x0a (换行)
- if(buf == 0x0a)
- {
- // 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
- UART1_RX_STA |= 0x8000;
-
-
-
-
- //程序运行到此处,代表数据已经完整接收,可以开始判断//
-
- //查看是否收到WIFI GOT IP
- if(strcmp(UART1_RX_Buffer,"WIFI GOT IP") == 0){
- HAL_UART_Transmit(&huart2, "111\r\n",strlen("111\r\n"), 100);
- AT_Connect_Net_Flag = 1;
- }
- //查看是否收到OK
- if(strcmp(UART1_RX_Buffer,"OK") == 0){
- HAL_UART_Transmit(&huart2, "222\r\n",strlen("222\r\n"), 100);
- AT_OK_flag = 1;
- }
-
-
- //灯控指令
- if(strcmp(UART1_RX_Buffer,"+IPD,0,6:open") == 0){
- HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
- }
- if(strcmp(UART1_RX_Buffer,"+IPD,0,7:close") == 0){
- HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
- }
-
-
- //如果联网失败,收到FAIL
- if(!strcmp(UART1_RX_Buffer,"0,CONNECT")){
- Client_Connent_Flag = 1;
- }
-
- memset(UART1_RX_Buffer,0,UART1_REC_LEN);
- UART1_RX_STA = 0;
- }
-
-
-
-
- else
- // 否则认为接收错误,重新开始
- UART1_RX_STA = 0;
- }
- else // 如果没有收到了 0x0d (回车)
- {
- //则先判断收到的这个字符是否是 0x0d (回车)
- if(buf == 0x0d)
- {
- // 是的话则将 bit14 位置为1
- UART1_RX_STA |= 0x4000;
- }
- else
- {
- // 否则将接收到的数据保存在缓存数组里
- UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;
- UART1_RX_STA++;
-
- // 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
- if(UART1_RX_STA > UART1_REC_LEN - 1)
- UART1_RX_STA = 0;
- }
- }
- }
- // 重新开启中断
- HAL_UART_Receive_IT(&huart1, &buf, 1);
- }
- }
-
- int fputc(int ch, FILE *f)
- {//注意,printf的重写是针对串口1的,也就是wifi的,对于串口2的数据发送不能用printf
- unsigned char temp[1]={ch};
- HAL_UART_Transmit(&huart1,temp,1,0xffff);
- return ch;
- }
-
-
- int main(void)
- {
-
- HAL_NVIC_SetPriority(SysTick_IRQn,0,0);
- // 开启接收中断
-
- HAL_UART_Receive_IT(&huart1, &buf, 1);
- HAL_UART_Transmit(&huart2, "START\r\n",strlen("START\r\n"), 100);
-
-
-
- printf(mode);//发送客户端模式指令并等待成功
- while(!AT_OK_flag) HAL_Delay(50);
- AT_OK_flag = 0;
- HAL_UART_Transmit(&huart1, "mode set success\r\n", strlen("mode set success\r\n"), 100);
-
- printf(mul_con);
- while(!AT_OK_flag) HAL_Delay(50);
- AT_OK_flag = 0;
-
- printf(server);
- while(!Client_Connent_Flag) HAL_Delay(50);
- AT_OK_flag = 0;
-
- if(Client_Connent_Flag){
- HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
- HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
- }
-
- while (1)
- {
-
- printf(send);//发送数据
- HAL_Delay(2000);
- printf("wdnmd");//发给串口1的,共2个字节
- HAL_Delay(2000);
- }
-
- }
-
-
打开单片机点击复位,使得电脑连上”esp8266“的WIFI,然后在网络助手中输入相关信息之后点击连接:(要提前连好wifi的情况)1-ESP8266-AT指令初试化及部分基础知识_ch_pd-CSDN博客STA模式具体连接再次参考这个
当在网络助手发送“open”加上回车时,LED1会打开;反之输入“close”加上回车,LED1会关闭
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。