STM32F103C8T6+ESP8266WIFI+DHT11模块连接巴法云

STM32F103C8T6通过ESP8266模块连接巴法云

一、硬件介绍

1.MCU:STM32F103C8T6
2.ESP8266:正点原子WIFI模块
3.串口模块:正点原子串口模块

二、准备工作

我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

  1. ESP8266固件刷写
    我用的是安信可的固件,可以在官网上下载。正点原子也提供相关的刷写教程

  2. 硬件连接
    单片机的串口3连接WiFi模块。WiFi模块的Vcc接3.3V。串口1接在串口模块上。

三、STM32主要代码介绍

mcu跟wifi模块的代码实现(涉及串口、定时器):

  1. 实现思想
    单片机向esp8266模块发送at指令,并且在一定的时间内等待esp8266的回复,如果回复错误的指令或者超时回复就把错误通过串口1发送到电脑上。

  2. 代码介绍
    AT指令发送函数

uint8_t esp8266_send_cmd(char *cmd, char *ack, uint16_t waittime) //ESP8266发送指令(底层函数)
{
	uint8_t res = 0;
	USART3_RX_STA = 0;
	memset(USART3_RX_BUF,0,USART3_REC_LEN); //将串口3的缓存空间清0
	WIFI_printf("%s\r\n", cmd); //调用WIFI模块专用的发送函数
	if(waittime) //需要等待应答
	{
		while(--waittime) //等待倒计时
		{
			HAL_Delay(10);//HAL库延时函数
			if(USART3_RX_STA&0x8000) //接收到期待的应答结果
			{
				if(esp8266_check_cmd((uint8_t *)ack))
				{
					printf("回复信息:%s\r\n",(uint8_t *)ack);//反馈应答信息
					break; //得到有效数据
				}
				USART3_RX_STA=0; //串口3标志位清0
			} 
		}
		if(waittime==0)res=1;
	}
	return res;
}

uint8_t* esp8266_check_cmd(uint8_t *str) //ESP8266检查指令(底层函数)
{
	char *strx=0;
	if(USART3_RX_STA&0X8000) //接收到一次数据了
	{
		USART3_RX_BUF[USART3_RX_STA&0X7FFF] = 0; //添加结束符
		printf("%s\r\n",(char*)USART3_RX_BUF);
		strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
	} 
	return (uint8_t*)strx;
}

uint8_t esp8266_quit_trans(void) //ESP8266退出判断(底层函数)
{
	while((USART3->SR&0X40)==0); //等待发送空
	USART3->DR='+';      
	HAL_Delay(15); //大于串口组帧时间(10ms)
	while((USART3->SR&0X40)==0); //等待发送空
	USART3->DR='+';      
	HAL_Delay(15); //大于串口组帧时间(10ms)
	while((USART3->SR&0X40)==0); //等待发送空
	USART3->DR='+';      
	HAL_Delay(500); //等待500ms
	return esp8266_send_cmd("AT","OK",20); //退出透传判断
}

接收状态标记、接收缓冲、接收状态标记的宏定义

uint8_t USART1_RX_BUF[USART1_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.
uint16_t USART1_RX_STA=0;//接收状态标记//bit15:接收完成标志,bit14:接收到0x0d,bit13~0:接收到的有效字节数目
uint8_t USART1_NewData;//当前串口中断接收的1个字节数据的缓存

uint8_t USART2_RX_BUF[USART2_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.
uint16_t USART2_RX_STA=0;//接收状态标记//bit15:接收完成标志,bit14:接收到0x0d,bit13~0:接收到的有效字节数目
uint8_t USART2_NewData;//当前串口中断接收的1个字节数据的缓存
uint8_t RS485orBT;//当RS485orBT标志位为1时是RS485模式,为0时是蓝牙模式

uint8_t USART3_RX_BUF[USART3_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.
uint16_t USART3_RX_STA=0;//接收状态标记//bit15:接收完成标志,bit14:接收到0x0d,bit13~0:接收到的有效字节数目
uint8_t USART3_NewData;//当前串口中断接收的1个字节数据的缓存

串口3跟esp8266通信的底层函数

void WIFI_printf (char *fmt, ...)
{
	char buff[USART3_REC_LEN+1];  //用于存放转换后的数据 [长度]
	uint16_t i=0;
	va_list arg_ptr;
	va_start(arg_ptr, fmt);
	vsnprintf(buff, USART3_REC_LEN+1, fmt, arg_ptr);//数据转换
	i=strlen(buff);//得出数据长度
	if(strlen(buff)>USART3_REC_LEN)i=USART3_REC_LEN;//如果长度大于最大值,则长度等于最大值(多出部分忽略)
    HAL_UART_Transmit(&huart3,(uint8_t *)buff,i,0xffff);//串口发送函数(串口号,内容,数量,溢出时间)
    va_end(arg_ptr);
}
//WIFI模块在TCP模式下的数据发送:TCP发送的规定是先发AT+CIPSEND=数量,等待返回“>“后再发送数据内容。
//调用方法:WIFI_TCP_SEND("123\r\n"); //TCP方式发送字符123和回车换行
void WIFI_TCP_SEND (char *fmt, ...)
{
	char buff[USART3_REC_LEN+1];  //用于存放转换后的数据 [长度]
	uint16_t i=0;
	va_list arg_ptr;
	va_start(arg_ptr, fmt);
	vsnprintf(buff, USART3_REC_LEN+1, fmt, arg_ptr);//数据转换
	i=strlen(buff);//得出数据长度
	if(strlen(buff)>USART3_REC_LEN)i=USART3_REC_LEN;//如果长度大于最大值,则长度等于最大值(多出部分忽略)
	WIFI_printf("AT+CIPSEND=%d\r\n",i);//先发送AT指令和数据数量
	HAL_Delay(100);//等待WIFI模块返回">",此处没做返回是不是">"的判断。稳定性要求高的项目要另加判断。
    HAL_UART_Transmit(&huart3,(uint8_t *)buff,i,0xffff);//发送数据内容(串口号,内容,数量,溢出时间)
    va_end(arg_ptr);
}

串口1的重定向和串口3、定时器的中断回调函数,

void  HAL_UART_RxCpltCallback(UART_HandleTypeDef  *huart)//串口中断回调函数
{
	
	if(huart ==&huart3)//判断中断来源(串口3:WIFI模块)//接收完的一批数据,还没有被处理,则不再接收其他数据
	{
		if(USART3_RX_STA<USART3_REC_LEN)//还可以接收数据
		{
			__HAL_TIM_SET_COUNTER(&htim2,0); //计数器清空
			if(USART3_RX_STA==0) //使能定时器2的中断
			{
			__HAL_TIM_ENABLE(&htim2); //使能定时器2
			}
			USART3_RX_BUF[USART3_RX_STA++] = USART3_NewData;//最新接收数据放入数组
		}
		else
		{
			USART3_RX_STA|=0x8000;//强制标记接收完成
		}
		HAL_UART_Receive_IT(&huart3,(uint8_t *)&USART3_NewData,1); //再开启串口3接收中断
		

	}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	  if(htim ==&htim2)//判断是否是定时器2中断(定时器到时表示一组字符串接收结束)
    {
		USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
		USART3_RX_STA|=0x8000;//接收标志位最高位置1表示接收完成
		__HAL_TIM_CLEAR_FLAG(&htim2,TIM_EVENTSOURCE_UPDATE );//清除TIM2更新中断标志
		__HAL_TIM_DISABLE(&htim2);//关闭定时器2
    }
}
int fputc(int ch, FILE *f)                             //串口重定向
 {	 
	 HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
   return ch;
 }

##不想写了,主要核心代码可以参考正点原子的,大家不懂的可以私信,看到一定回复。

  • 11
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 31
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 31
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值