#esp8266 01s
stm32与wifi模块通信使用串口,stm32与电脑通信也使用串口,在这里我们使用串口1连接电脑进行通信(这里使用ch340n芯片),串口2与wifi模块进行通信。
在上一节中我们通过八个步骤配置wifi模块,但是这里我们需要用单片机代替人工操作。在前面部分已经介绍过“printf”的使用方式。
usart1和usart2的配置方式是一样的。下文中进行了一定的修改,u1_printf()为串口1的输出,u2_printf()为端口二的输出。
函数介绍:
首先介绍一下
windows中\r\n表示回车+换行 Linux中\n表示回车+换行 Mac中\r表示回车+换行
(1)sizeof()与strlen()函数的区别:sizeof()把\0也算入其中,而strlen()未\0未算入其中。
(2)memset函数,void *memset(void*str,int c,size_t n)将已开辟内存空间str的首个字节的值设为值c。
char str[50];
strcpy(str,"huifeideqiewang")
memset(str,'*',10);
printf("%s\n",str);
如在此函数中printf将输出**********ewang。
(3)strstr函数介绍,char *strstr(const char *str1,const char *str2)判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则返回NULL。
例:
const char str1[10] = "huifeideqie";
const char str2[10] = "huifei";
char *ret;
ret =strstr(str1,str2);
printf("子字符串是:%s\n",ret);
此代码将输出"子字符串是:deqie"。
const char str1[10] = "huifeideqie";
const char str2[10] = "huifee";
char *ret;
ret =strstr(str1,str2);
printf("子字符串是:%s\n",ret);
此代码将输出"子字符串是 :(null)。
代码移植:
当要移植USART1使用USART2时要注意:
(1)USART1挂载在APB1总线上,USARET2挂载在APB2总线。
(2)USART1使用引脚9和引脚10,USART2使用引脚2和引脚3。
(3)波特率的修改,串口1使用的是9600,串口2使用的是15200
(4)删除USART_SendByte()函数,如果在串口1和串口2函数中都使用,则此程序会报错,此时在串口2中用extern声明一下,即可调用。
(5)增加中断功能NVIC()配置,如下:
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel=USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
中断函数的编程思路,首先判断是否能接收到数据,可以接收的话就接收数据,再发送到串口助手。
串口2的接受数据中断如下:
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//
{
if(USART2->DR)//判断DR寄存器中是否有数据
{
USART2_RxBuff[USART2_RxCounter]=USART_ReceiveData(USART2); //如果有数据将数据放于USART2_RxBuff[USART2_RxCounter]数组中
USART2_RxCounter++; // 每循环一次数组变量USART2_RxCounter加1
}
}
};
用单片机代替人工操作:
单片机通过串口2发送指令;如:u2_printf("AT+RST\r\n");
单片机等待响应;//计划用time判断这条指令是否执行成功,如果到了time时间没响应,表示模块响应失败;如果过了小于time的时间响应,退出这time的计划,执行下一条语句!
建立WiFi程序模块:
1、按键复位
void WIFI_Config1(int time)//wifi模块初始化
{
memset(WiFi_RX_BUF,0,1024);//容器数组WiFi_RX_BUF清零
WiFi_RxCounter = 0;//计数器清零
while(time--)
{
delay_ms(100);
if(strstr(WiFi_RX_BUF,"ready"))
break;
u1_printf("%d ",time);
}
u1_printf("\r\n");
if(time>0)
u1_printf("复位成功!\r\n");
else
u1_printf("复位失败!\r\n");
}
2、配置wifi模式
void WIFI_Config2(int time)//wifi模块初始化
{
memset(WiFi_RX_BUF,0,1024);//容器数组WiFi_RX_BUF清零
WiFi_RxCounter = 0;//计数器清零
u2_printf("AT+CWMODE=1\r\n");
while(time--)
{
delay_ms(100);
if(strstr(WiFi_RX_BUF,"OK"))
break;
u1_printf("%d ",time);
}
u1_printf("\r\n");
if(time>0)
u1_printf("配置成功!\r\n");
else
u1_printf("配置失败!\r\n");
}
3、完成配置重启
void WIFI_Config3(int time)//wifi模块初始化
{
memset(WiFi_RX_BUF,0,1024);//容器数组WiFi_RX_BUF清零
WiFi_RxCounter = 0;//计数器清零
u2_printf("AT+RST\r\n");
while(time--)
{
delay_ms(100);
if(strstr(WiFi_RX_BUF,"ready"))
break;
u1_printf("%d ",time);
}
u1_printf("\r\n");
if(time>0)
u1_printf("重启成功!\r\n");
else
u1_printf("重启失败!\r\n");
}
第二步和第三步的函数对比发现,只有发送的命令不一样,还有返回的值不一样,所以我们可以将其写成一个函数,如下:
void WIFI_Config(int time,char*cmd,char*response)
{
memset(WiFi_RX_BUF,0,1024);
WiFi_RxCounter = 0;
u2_printf("%s\r\n",cmd);
while(time--)
{
delay_ms(100);
if(strstr(WiFi_RX_BUF,response))
break;
u1_printf ("%d ",time);
}
u1_printf ("\r\n");
if(time>0)
u1_printf ("成功!\r\n");
else
u1_printf ("失败!\r\n");
}
此程序成为公共函数可实现下面多个步骤。 但在实现第4步和第七步时候,由于多重引号的问题,会报错。
当我们使用printf(""")会出现报错的情况,这里需添加一个转义字符\,我们可以printf("\"")这样使用转义字符,则不会报错。
如下为4和7的程序:
void WIFI_Router(int time)
{
memset(WiFi_RX_BUF,0,1024);
WiFi_RxCounter=0;
u2_printf("AT+CWJAP=\"%s\",\"%s\"\r\n",ID,PASSWORD);
while(time--)
{
delay_ms(1000);
if(strstr(WiFi_RX_BUF,"OK"))
break;
u1_printf(" %d",time);
}
u1_printf("\r\n");
if(time>0)
u1_printf("成功!\r\n");
else
u1_printf("失败!\r\n");
}
void WiFi_TCP(int time)
{
memset(WiFi_RX_BUF,0,1024);
WiFi_RxCounter=0;
u2_printf("AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",IP,DK);
while(time--)
{
delay_ms(1000);
if(strstr(WiFi_RX_BUF,"OK"))
break;
u1_printf(" %d",time);
}
u1_printf("\r\n");
if(time>0)
u1_printf("成功!\r\n");
else
u1_printf("失败!\r\n");
}
因为这两个配置时间将会较长所以将延时较长时间。