主控 | STM32F103C8T6 |
WIFI模块 | ESP01S |
开发语言 | C |
开发编译器· | KEIL |
组网方式 | WIFI |
服务器协议 | MQTT |
STM32 | ESP01S |
3.3V | 3.3V |
GND |
GND |
GPIO2 (USRAT2-TX) |
RX |
GPIO3 (USART3-RX) | TX |
进入循环函数:在STM32对ESP01S进行USART通信发送完AT指令后,进行串口监听,然后接收AT反馈指令,接着调用strstr()函数对指令进行解析,当解析到AT指令任务实现的反馈指令后,才执行下一步,跳出循环函数
_Bool ESP8266_SendCmd(char *cmd, char *res, u16 time)
{
Usart2_SendString((unsigned char *)cmd, strlen((const char *)cmd));
while(time--)
{
if(ESP8266_WaitRecive() == REV_OK) //如果收到数据
{
if(strstr((const char *)esp8266_buf, res) != NULL) //如果检索到关键词
{
ESP8266_Clear(); //清空缓存
return 0;
}
}
delay_ms(10);
}
return 1;
}
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
// while((USART2->SR&0X40)==0);//循环发送,直到发送完毕
// USART2->DR = (u8) ch;
while((USART2->SR&0X40)==0);//循环发送,直到发送完毕 (若需要使用usart串口通信进行信息验证调试则取消注释,正常使用请关闭,避免printf打印两次)
USART2->DR = (u8) ch;
return ch;
}
#endif
#include
//C库重写
#include
void USART1_printf (char * Data, ... )
{
const char *s;
int d;
char buf[16];
va_list ap;
va_start(ap, Data);
while ( * Data != 0 ) // 判断是否到达字符串结束符
{
if ( * Data == 0x5c ) //'\'
{
switch ( *++Data )
{
case 'r': //回车符
USART_SendData(USART1, 0x0d);
Data ++;
break;
case 'n': //换行符
USART_SendData(USART1, 0x0a);
Data ++;
break;
default:
Data ++;
break;
}
}
else if ( * Data == '%')
{ //
switch ( *++Data )
{
case 's': //字符串
s = va_arg(ap, const char *);
for ( ; *s; s++)
{
USART_SendData(USART1,*s);
while( USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );
}
Data++;
break;
case 'd':
//十进制
d = va_arg(ap, int);
myitoa(d, buf, 10);
for (s = buf; *s; s++)
{
USART_SendData(USART1,*s);
while( USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET );
}
Data++;
break;
default:
Data++;
break;
}
}
else USART_SendData(USART1, *Data++);
while ( USART_GetFlagStatus ( USART1, USART_FLAG_TXE ) == RESET );
}
}
由于在stm32内,无法使用stdlib.h的C语言库,因此我们重写编写了stdlib.h库的部分函数
#ifndef __MYSTDLIB_H
#define __MYSTDLIB_H
/*
将整数转化为字符串:
num,转换对象
str,转换后存储字符串的数组
radix,转换(给于的字符串)的长度
*/
char *myitoa(int num,char *str,int radix)
{
/* 索引表 */
char index[]="0123456789abcdefghijklmnopqrstuvwxz";
unsigned unum; /* 中间变量 */
int i=0,j,k;
/* 确定unum的值 */
if(radix==10&&num<0) /* 十进制负数 */
{
unum=(unsigned)-num;
str[i++]='-';
}
else unum=(unsigned)num; /* 其它情况 */
/* 逆序 */
do
{
str[i++]=index[unum%(unsigned)radix];
unum/=radix;
}while(unum);
str[i]='\0';
/* 转换 */
if(str[0]=='-') k=1; /* 十进制负数 */
else k=0;
/* 将原来的“/2”改为“/2.0”,保证当num在16~255之间,radix等于16时,也能得到正确结果 */
char temp;
for(j=k;j<=(i-k-1)/2.0;j++)
{
temp=str[j];
str[j]=str[i-j-1];
str[i-j-1]=temp;
}
return str;
}
/*
将字符串转换成整数
str,转换的字符串数组目标
返回值:为转换后的整数;
*/
int myatoi(char * str)
{
int n=0;//保存整形
char firstChar = *str;//记录str的第一个字符
if (firstChar == '+' || firstChar == '-')//+123 -123
{
++str;
}
while(*str == '0')//00123 -00123
{
++str;
}
while (*str)
{
char temp = *str;
if (*str < '0' || *str> '9')
{
puts("literal does not match format string ") ;
return n;//该字符串含有非数字字符,不能转为整数
}
else
{
temp -= '0';
n = n * 10 + temp;//将字符串转为整形
}
str++;
}
if (firstChar == '-')
{
n = -n;
}
return n;
}
#endif
如果要本第一、二章优化拓展的完整工程文件,可以直接到百度网盘提取(解压密码同下)
链接:https://pan.baidu.com/s/1ECxx125pRlKVo366fzyTiw?pwd=1016
提取码:1016
本文为作者独立编写
本BLOG上所有的原创文章未经本人许可,不得用于商业用途及传统媒体。网络媒体转载请注明出处,否则属于侵权行为。