ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

利用单片机通过ESP8266把DHT11温湿度数据进行从发主机接收信息

2020-06-09 19:05:54  阅读:302  来源: 互联网

标签:ESP8266 USART 温湿度 void 单片机 DEBUG GPIO define DHT11


刚开始学编程,菜鸟一个,大二期间在学校,用stm32f1系列芯片自己焊了一个板子通过esp8266做了简单的主从机接受信息的小项目。以前也没有接触过esp8266,在网上查找资源以及自己琢磨了一阵,做了一个简陋的收发信息的主从机项目。自己也做了好久,走了挺多错路,在这里分享一下自己的经验和心得,哪里做的或者理解不对,还请大家提出以及不要见怪。废话不多说,直接看代码。

首先是wifi.h,包含了串口和DHT11的头文件,数据的发送或接受是通过协议的方式进行发送或接受

#ifndef __wifi_H
#define __wifi_H

#include "stm32f10x.h"
#include "string.h"
#include "bsp_led.h"
#include "stdbool.h"
#include "bsp_usart.h"
#include "SYSTICK.h"
#include "DHT11.h"

#define open_cpu         0xAF
#define cpu_openstatse     0xAE

//--指令长度
#define command_length      5
//--指令头起始位置
#define cmdhead_startposit    0
//--指令头长度
#define cmdheader_length     2
//--主箱地址长度
#define mainbox_addresslength  2 
//--主箱地址起始位置
#define mainbox_startposit   2 

#define MAX_RCV_LEN 10

//从机控制指令
#define slavecmd_open  0x01 
#define slavecmd_close  0x00

extern u32 UART1_read_count;//接收数据的个数
extern u8 UART1_rcv_buf[MAX_RCV_LEN] ;

void USART1_Clear_Buf(void);
void Esp8266_Server_Init(void);
void ESP8266_Client_Init();
bool USRT_Send_ATCmd3(unsigned char *cmd,unsigned char *result);
void ESP8266_UnvarnishSend();
void USART1_Send_Len_Str(u8 *str, u8 len);
void ESP8266_SendString(u32 ulStrLength,ENUM_ID_NO_TypeDef ucId);
void TCP_Client_SendString(u32 ulStrLength,ENUM_ID_NO_TypeDef ucId);
void TCP_Client_Instruction(unsigned char addr,unsigned char zcmd);
void ESP8266_UnvarnishSend();

#endif

后面是wifi.c,里面是一些esp8266的初始化和配置等

#include "wifi.h"

u32 UART1_read_count = 0;//接收数据的个数
u8 UART1_rcv_buf[MAX_RCV_LEN] = {0};

// 设置单链接
// 返回+ok
uc8 *SetCIPMUX = "AT+CIPMUX=0\r\n";

// 设置透传模式
// 返回+ok
uc8 *SetCIPMODE = "AT+CIPMODE=1\r\n";

// 设置STATION模式
// 返回+ok
uc8 *SetCWMODE = "AT+CWMODE=1\r\n";

//加入主机热点
//返回+ok
uc8 *AddCWJAP = "AT+CWJAP=\"ESP8266\",\"0123456789\"\r\n";

// 设置TCP连接参数
// 返回+ok
uc8 *SetNETP = "AT+CIPSTART=\"TCP\",\"192.168.4.1\",8888\r\n";

bool USRT_Send_ATCmd(unsigned char *cmd,unsigned char *result)
{
unsigned char i = 0;
 unsigned char ret = 0;
 while(1)
 { 
  USART1_Clear_Buf();
 USART1_Send_Len_Str(cmd,strlen(cmd));
 delay_ms(100);
 if(NULL != strstr(UART1_rcv_buf,result))
 {
//  LED_1(ON);
  ret = SUCCESS;
  break;
 }
 else if(i++ >=10)
 {
  ret = ERROR;
  break;
 }
}
 return ret;
}

bool USRT_Send_ATCmd2(unsigned char *result)
 {
  unsigned char i = 0;
  unsigned char ret = 0;
  while(1)
  {
  USART1_Clear_Buf();
  delay_ms(100);
  if(NULL != strstr(UART1_rcv_buf,result))
  {
//    LED_2(ON);
   ret = SUCCESS;
    break; 
  }
  else if(i++ >=10)
  {
   ret = ERROR;
    break;
  }
 }
  return ret;
 }
bool USRT_Send_ATCmd3(unsigned char *cmd,unsigned char *result)
{
 unsigned char i = 0;
 unsigned char ret = 0;
 while(1)
 { 
  USART1_Clear_Buf();
// ESP8266_Usart("%s",cmd);
  USART1_Send_Len_Str(cmd,strlen(cmd));
 delay_ms(20000);
 if(NULL != strstr(UART1_rcv_buf,result))
  {
     ret = SUCCESS;
     break;
  }
 else if(i++ >=10)
 {
  ret = ERROR;
  break;
 }
  }
 return ret;
} 

void TCP_Client_Instruction(unsigned char addr,unsigned char zcmd)
  {
   u8 i =0;
   u8 sencmd_temp[8] = {0};
  u8 sencmd_Sum = 0;
  sencmd_temp[0] = open_cpu; //数据头  
  
  sencmd_temp[1] = 8;       // 数据长度  
  
  sencmd_temp[2] = addr>>8;
  sencmd_temp[3] = addr;  
  
  sencmd_temp[4] = zcmd;     //控制指令

  sencmd_temp[5] = 1;        //确认码

  sencmd_temp[6] = 1;        //校验码   
  
  for(i=0;i<8;i++)
  sencmd_Sum += sencmd_temp[i];
  
  sencmd_temp[7] = sencmd_Sum;  
  USART1_Send_Len_Str(sencmd_temp,8);
  }

void TCP_Client_SendString(u32 ulStrLength,ENUM_ID_NO_TypeDef ucId)
  {
    unsigned char cStr[100]; 
   if(ucId < 5)
  sprintf ( cStr, "AT+CIPSEND=%d,%d\r\n", ucId, ulStrLength + 2 );  //多连接模式
  else
  sprintf ( cStr, "AT+CIPSEND=%d\r\n",ulStrLength + 2 );           //单连接模式
  USRT_Send_ATCmd3(cStr,">");
  TCP_Client_Instruction(curtain_addr,slavecmd_open);
  USRT_Send_ATCmd2("SEND OK");   
  }
  
void USART1_Clear_Buf(void)
{
 memset(UART1_rcv_buf, 0, strlen(UART1_rcv_buf));
  UART1_read_count = 0;
}

void Esp8266_Server_Init()
{ 
    //等待启动成功 发送数据  收到数据
   USRT_Send_ATCmd2("Ready");           //查询
   USRT_Send_ATCmd("AT\r\n","OK");      //就绪
   USRT_Send_ATCmd("AT+CIPMUX=1\r\n","OK");    //设置多链接模式
   USRT_Send_ATCmd("AT+CWMODE=3\r\n","OK")  ; //设置STATION模式 (AP+STATION)模式 首次设定后面就不用设置了
   USRT_Send_ATCmd("AT+CIPSERVER=1,8888\r\n","OK");//开启TCP主机模式 
} 

/*配置成TCP客户端模式*/
  void ESP8266_Client_Init()
 {                 
  USRT_Send_ATCmd2("Ready");                //查询
  USRT_Send_ATCmd("AT\r\n","OK");           //就绪
  USRT_Send_ATCmd("AT+CWMODE=1\r\n","OK")  ; //设置STATION模式  首次设定后面就不用设置了
  USRT_Send_ATCmd("AT+RST\r\n","OK");       //重启模块使STA模式生效;
  USRT_Send_ATCmd("AT+CIPMUX=0\r\n","OK") ;  //设置单链接  
  USRT_Send_ATCmd3((char*)AddCWJAP,"OK");   ////加入主机热点
  USRT_Send_ATCmd3((char*)SetNETP,"OK");   //设置TCP连接参数
 } 

void USART1_Send_Len_Str(u8 *str, u8 len)
{
 u8 i;
 for(i=0; i<len; i++)
 Usart_SendByte(USART1,*str ++);
}

/*透传发送模式(只限从机给主机发数据)*/
  void ESP8266_UnvarnishSend()
  {   
//  unsigned char *str;
   unsigned char *sendtemp = "AT+CIPSEND\r\n";   
   
   USRT_Send_ATCmd((char*)SetCIPMODE,"OK");   //设置透传模式 
     
   USRT_Send_ATCmd3(sendtemp,">");
//   LED4_ON;
   TCP_Client_Instruction(curtain_addr,slavecmd_open);   
  }

/*普通发送传感器数据函数*/
void ESP8266_SendString(u32 ulStrLength,ENUM_ID_NO_TypeDef ucId)
{
  unsigned char cStr[100]; 
  if(ucId < 5)
  sprintf ( cStr, "AT+CIPSEND=%d,%d\r\n", ucId, ulStrLength + 2 );  //多连接模式
  else
  sprintf ( cStr, "AT+CIPSEND=%d\r\n",ulStrLength + 2 );           //单连接模式
  USRT_Send_ATCmd3(cStr,">");
  if(count_10ms != last_count_10ms)
   {  
     if(DHT11_Read_TempAndHumidity()==SUCCESS)
     {
      sprintf(cStr,"\r\n读取DHT11成功!\r\n\r\n湿度为%d.%d %RH ,温度为 %d.%d℃ \r\n",
      humidity_int, humidity_deci, temperature_int, temperature_deci );
     }
     else 
     {
      sprintf ( cStr, "Read DHT11 ERROR!\r\n" );
     }
       printf ( "%s", cStr );  
       USRT_Send_ATCmd2("SEND OK"); 
     last_count_10ms = count_10ms;
   }
}

在wifi里把已经把初始的本地IP地址192.168.4.1以及本地端口号8888设定好了,这里的协议类型为TCP Server利用串口助手进行输入以及连接即可进行发送相应的指令协议

下面DHT11.h,对DHT11的i/o口等进行宏定义

#ifndef __DHT11_H__
#define __DHT11_H__

#include "stm32f10x.h"
#include "SYSTICK.h"
#include "bsp_usart1.h"
#include "bsp_led.h"
#include "stdio.h"
#include "GeneralTim.h"

extern unsigned char humidity_int;     //湿度的整数部分
extern unsigned char humidity_deci;    //湿度的小数部分
extern unsigned char temperature_int; //温度的整数部分
extern unsigned char temperature_deci; //温度的小数部分

#define DHT11_GPIO_APBxClkCmd      RCC_APB2PeriphClockCmd
#define DHT11_GPIO_CLK             RCC_APB2Periph_GPIOD
#define DHT11_GPIO_PROT            GPIOA
#define DHT11_GPIO_PIN             GPIO_Pin_11

#define DHT11_L                    GPIO_ResetBits(DHT11_GPIO_PROT,DHT11_GPIO_PIN)
#define DHT11_H                    GPIO_SetBits(DHT11_GPIO_PROT,DHT11_GPIO_PIN)
#define DHT11_IN                 GPIO_ReadInputDataBit(DHT11_GPIO_PROT,DHT11_GPIO_PIN)//读取单个端口的数值

#define open_cpu         0xAF

void DHT11_State(void);
void DHT11_GPIO_Confing(void);  
unsigned char Read_Byte(void);
void DHT11_Init(void);
unsigned char DHT11_Read_TempAndHumidity(void);
void DHT11_Show(void);

#endif

接下来是DHT11.c

#include "DHT11.h"
/*
  DHT11运行机制  
 ①拉低18ms低电平
 ②发送信号结束后延时等待20-40us
 ③DHT11发送80us低电平响应信号
 ④DHT11在把总线拉高80us
 ⑤接收数据
 ⑥主机总线拉高 
*/

/*
   配置DHT11用到的IO口
  输出模式为推挽输出
*/

unsigned char humidity_int;     //湿度的整数部分
unsigned char humidity_deci;    //湿度的小数部分
unsigned char temperature_int; //温度的整数部分
unsigned char temperature_deci; //温度的小数部分

void DHT11_Init()
{
 DHT11_GPIO_Confing();
 DHT11_H; 
}

void DHT11_GPIO_Confing(void)       
{
 GPIO_InitTypeDef  GPIO_InitStructure;
 DHT11_GPIO_APBxClkCmd(DHT11_GPIO_CLK,ENABLE);
 GPIO_InitStructure.GPIO_Pin = DHT11_GPIO_PIN;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 GPIO_Init(DHT11_GPIO_PROT,&GPIO_InitStructure);
}

/*使DHT11的引脚变为上拉输入*/
 static void DHT11_GPIO_Mode_IPU(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
 GPIO_InitStructure.GPIO_Pin = DHT11_GPIO_PIN;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
 GPIO_Init(DHT11_GPIO_PROT,&GPIO_InitStructure);
}

static void DHT11_GPIO_Mode_Out_PP(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
 GPIO_InitStructure.GPIO_Pin = DHT11_GPIO_PIN;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 GPIO_Init(DHT11_GPIO_PROT,&GPIO_InitStructure);
}

void DHT11_State(void)
{
  DHT11_GPIO_Mode_Out_PP();  //设置为输出模式
  DHT11_L;
  delay_ms(18);
  DHT11_H;
  delay_us(30);
  DHT11_GPIO_Mode_IPU();
}

//从DHT11读取一个字节,MSB先行(最高有效位  二进制中代表最高值的bit)
unsigned char Read_Byte(void)
{
 unsigned char i,temp=0;
 for(i=0;i<8;i++)
 {
  while( DHT11_IN==Bit_RESET);
  delay_us(40);
  if( DHT11_IN==Bit_SET)
  {
   while( DHT11_IN==Bit_SET);
   temp|=(uint8_t)(0x01<<(7-i)); //位或赋值 把把第7-i位置1
  }
  else 
  {
   temp&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0
  }
 }
 return temp;
}

unsigned char DHT11_Read_TempAndHumidity()
{
 unsigned char rec_temp[5];
 unsigned char i; 
 DHT11_State();               //开始信号
 if(DHT11_IN==Bit_RESET)      //判断DHT11响应信号
 {
   while(DHT11_IN==Bit_RESET);//轮询80us低电平信号结束    
   while(DHT11_IN==Bit_SET);  //轮询80us高电平信号结束
   for(i=0;i<5;i++)
   {
     rec_temp[i]= Read_Byte();
   }
   DHT11_GPIO_Mode_Out_PP();    //读取结束 引脚改为输出模式
   DHT11_H;                     //主机拉高
   if((rec_temp[0]+rec_temp[1]+rec_temp[2]+rec_temp[3])==rec_temp[4])//校验
    {
      humidity_int = rec_temp[0];
      humidity_deci = rec_temp[1];
      temperature_int = rec_temp[2];
      temperature_deci = rec_temp[3];   
        return SUCCESS;
    }
   else 
   {
     return ERROR;
   }
 }
   else 
   {
     return ERROR;
   } 
}

void DHT11_Show()
{   
  if(count_100ms != last_count_100ms)
 {
//   ESP8266_UnvarnishSend();
 if(DHT11_Read_TempAndHumidity()==SUCCESS)
 {
   u8 sencmd_temp[5] = {0};

  sencmd_temp[0] = open_cpu; //数据头 
   
  sencmd_temp[1] = humidity_int;       // 湿度整数  
  
  sencmd_temp[2] = humidity_deci;      // 湿度小数  
  
  sencmd_temp[3] = temperature_int;    // 温度整数  
  
  sencmd_temp[4] = temperature_deci;   //温度小数   
  
//  sencmd_temp[5] = 1;        //确认码
//  sencmd_temp[6] = 1;        //校验码   

//  for(i=0;i<8;i++)
//  sencmd_Sum += sencmd_temp[i];
//  sencmd_temp[7] = sencmd_Sum;  

  USART1_Send_Len_Str(sencmd_temp,8);
  
//   Usart_SendArray(USART1, sencmd_temp,5);  
   printf("\r\n读取DHT11成功!\
  \r\n\r\n湿度为%d.%d %RH ,温度为 %d.%d℃ \r\n",humidity_int,humidity_deci,temperature_int,temperature_deci);
}
else
 {
  printf("Read DHT11 ERROR!\r\n");
 }
//  USRT_Send_ATCmd("+++","OK");//进入透传模式
//  USRT_Send_ATCmd("AT\r\n","OK");
 last_count_100ms = count_100ms;
   }   
} 

DHT11文件中将模块以及相应的i/o以及初始化都定义好了,并且利用printf()函数将温湿度进行串口输出,可以利用串口观看数据更加直观

接下来是串口

#ifndef __BSP_USART_H
#define __BSP_USART_H

#include "stm32f10x.h"
#include <stdio.h>
#include "bsp_led.h"
#include "wifi.h"
#include "key.h"

#define DEBUG_USART1     1
#define DEBUG_USART2     0

#if DEBUG_USART1
// 串口1-USART1
#define  DEBUG_USARTx                   USART1
#define  DEBUG_USART_CLK                RCC_APB2Periph_USART1
#define  DEBUG_USART_APBxClkCmd         RCC_APB2PeriphClockCmd
#define  DEBUG_USART_BAUDRATE           115200

// USART GPIO 引脚宏定义
#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)
#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd

#define  DEBUG_USART_TX_GPIO_PORT       GPIOA   
#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_9
#define  DEBUG_USART_RX_GPIO_PORT       GPIOA
#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_10

#define  DEBUG_USART_IRQ                USART1_IRQn
#define  DEBUG_USART_IRQHandler         USART1_IRQHandler

#elif DEBUG_USART2
//串口2-USART2
#define  DEBUG_USARTx                   USART2
#define  DEBUG_USART_CLK                RCC_APB1Periph_USART2
#define  DEBUG_USART_APBxClkCmd         RCC_APB1PeriphClockCmd
#define  DEBUG_USART_BAUDRATE           115200

// USART GPIO 引脚宏定义
#define  DEBUG_USART_GPIO_CLK           (RCC_APB2Periph_GPIOA)
#define  DEBUG_USART_GPIO_APBxClkCmd    RCC_APB2PeriphClockCmd

#define  DEBUG_USART_TX_GPIO_PORT       GPIOA   
#define  DEBUG_USART_TX_GPIO_PIN        GPIO_Pin_2
#define  DEBUG_USART_RX_GPIO_PORT       GPIOA
#define  DEBUG_USART_RX_GPIO_PIN        GPIO_Pin_3

#define  DEBUG_USART_IRQ                USART2_IRQn
#define  DEBUG_USART_IRQHandler         USART2_IRQHandler
#endif

extern uint8_t TxBuffer1[10];
extern u8 RxBuffer1[6];
extern u8 abc[6];
extern uint8_t rec_flag;
extern uint8_t rec_flag1;

void USART_Config(void);
void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data);
void Usart_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data);
void Usart_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint8_t num);
void Usart_SendStr(USART_TypeDef* pUSARTx, uint8_t *str);
void USART1_IRQHandler(void);
void ESP8266_IntGenData(unsigned char rec_tem);
void Buffercls(unsigned char *pBuffer, unsigned char vlaue, unsigned int BufferLength);
void Buffercpy(unsigned char *dBuffer, unsigned char *sBuffer, unsigned int BufferLength);

#endif  

在串口的定义上是在观看学习资料时向老师教学时用的宏定义,很喜欢这种宏定义方式,在这里我只定义了两个串口,在#define DEBUG_USART1 1 里将后面的数值进行改变就可以打开相应的串口。1打开0关闭。

bsp_usart.c

#include "bsp_usart.h"

u8 Res;
uint8_t humingjin[6]={00,01,02,03,04,05};
uint8_t TxBuffer1[10] ;   //发送数据缓存区
u8 RxBuffer1[6] = {0};    //接收数据缓存区
//u8 abc[6] = {0};
uint8_t rec_flag = 0;
uint8_t rec_flag1 = 0;
uint8_t ucTemp;
u8 banduanled[2]={'A','A'};
u8 banduanled1[2] ={'B','B'};
static void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  /* 嵌套向量中断控制器组选择 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  /* 配置USART为中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
  /* 抢断优先级*/
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  /* 子优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  /* 使能中断 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  /* 初始化配置NVIC */
  NVIC_Init(&NVIC_InitStructure);
}

void USART_Config(void)
{
 GPIO_InitTypeDef GPIO_InitStructure;
 USART_InitTypeDef USART_InitStructure;
// 打开串口GPIO的时钟
 DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);

// 打开串口外设的时钟
 DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);

// 将USART Tx的GPIO配置为推挽复用模式
 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

// 将USART Rx的GPIO配置为浮空输入模式
 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
 GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);

// 配置串口的工作参数
 // 配置波特率
 USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
 // 配置 针数据字长
 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
 // 配置停止位
 USART_InitStructure.USART_StopBits = USART_StopBits_1;
 // 配置校验位
 USART_InitStructure.USART_Parity = USART_Parity_No ;
 // 配置硬件流控制
 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
 // 配置工作模式,收发一起
 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 // 完成串口的初始化配置
 USART_Init(DEBUG_USARTx, &USART_InitStructure);

// 串口中断优先级配置
 NVIC_Configuration();

// 使能串口接收中断
 USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE); 

// 使能串口
 USART_Cmd(DEBUG_USARTx, ENABLE);     
}

/* 发送一个字节 */
void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data)
{
 USART_SendData(pUSARTx, data);
 while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
}

/* 发送两个字节的数据 */
void Usart_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data)
{
 uint8_t temp_h,temp_l;
// uint8_t rec_tem;
 temp_h = (data&0xff00) >> 8 ;
 temp_l = data&0xff;

USART_SendData(pUSARTx, temp_h);//高8位;
 while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );

USART_SendData(pUSARTx, temp_l);//低8位;
 while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
}

/* 发送8位数据的数组 */
void Usart_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint8_t num)
{
 uint8_t i;
 for( i=0; i<num; i++ )
  {
  Usart_SendByte(pUSARTx, array[i]);
 }
 while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );
}

/* 发送字符串 */
void Usart_SendStr(USART_TypeDef* pUSARTx, uint8_t *str)
{
 uint8_t i=0;
 do
  {
  Usart_SendByte(pUSARTx, *(str+i));
  i++;
 }while(*(str+i) != '\0');
 while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );
}

/////重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
  /* 发送一个字节数据到串口 */
  USART_SendData(DEBUG_USARTx, (uint8_t) ch);

/* 等待发送完毕 */
  while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);  
 return (ch);
}

///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
  /* 等待串口输入数据 */
  while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);

return (int)USART_ReceiveData(DEBUG_USARTx);
}

bool USRT_Send(unsigned char *cmd,unsigned char *result) 
{
     unsigned char ret = 0;
     if(NULL != strstr(cmd,result))
    ret = SUCCESS;
   else 
    ret = ERROR;   
   return ret;
}

void ESP8266_IntGenData(unsigned char rec_tem)
{   
  static unsigned char rec_count = 0;//--接收计数
  static unsigned char start_rec = 0;//--贞开始
  if(rec_tem == open_cpu||rec_tem == cpu_openstatse)
  { 
   rec_count = 0;
   start_rec = 1;
  }
  if(start_rec == 1)
  {   
     RxBuffer1[rec_count++] = rec_tem;
     if(rec_count == command_length)
     {
         start_rec = 0;
         rec_flag = 1; 
//             Buffercpy(abc,RxBuffer1,6);
                   LED3_TOGGLE;      
     } 
   }
   }

void DEBUG_USART_IRQHandler(void) 
{      
     unsigned char rec_tem = 0;   //--接收缓存  
    if(USART_GetITStatus(DEBUG_USARTx, USART_IT_RXNE) != RESET)  //判断读寄存器是否非空   接受中断
   {       
    rec_tem = USART_ReceiveData(DEBUG_USARTx);    //将读寄存器的数据缓存到接收缓冲区里  
    UART1_rcv_buf[UART1_read_count++] = rec_tem;
      ESP8266_IntGenData(rec_tem);
    USART_ClearITPendingBit(DEBUG_USARTx,USART_IT_RXNE);         
     }
}

//--以某个数清数组
void Buffercls(unsigned char *pBuffer, unsigned char vlaue, unsigned int BufferLength)
{
  while(BufferLength--)
  {
   *pBuffer = vlaue;  
    pBuffer++;
  }
}

//--把一个数组的内容复制到另一个数组
void Buffercpy(unsigned char *dBuffer, unsigned char *sBuffer, unsigned int BufferLength)
{
  while(BufferLength--)
  {
   *dBuffer = *sBuffer;
   
    dBuffer++;
    sBuffer++;
  }
} 

数据的发送和结束都是利用串口,在串口中断函数里,有接收指令的函数,用ESP8266_IntGenData()接收指令,我是用AF AE做指令头共8位数据,并且利用数据分析函数,用来解析接收到的数据。

最后则是主函数main
在主函数里放置的数据解析函数,用来解析接收到的数据,若接收完整则送到串口中。这份代码可以做主机也可以做从机,只要在主函数里将相应的函数初始化打开就可以了。在这里解析函数没有给出,是根据ESP8266_IntGenData()里的最终的 rec_flag = 1这个标志来进行判断执行相应的功能。

#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_usart.h"
#include "wifi.h"
#include "systick.h"
#include "DHT11.h"
#include "analysis_command.h"

int main(void)
{ 
 USART_Config();
 KEY_GPIO_Config();
 delay_Init(72);
 LED_Init();
//  ESP8266_Client_Init();
//   TCP_Client_SendString(6,Multiple_ID_2);
 Esp8266_Server_Init();

DHT11_Init();
DHT11_Show();

while(1)
{
    Analyze_instruction(RxBuffer1,6);
}
}

这个小项目是我和同学一起捣鼓了近一个月的时间,有收获也有不足。
实现功能:
1,能通过esp8266进行控制单片机执行相应的功能,如点灯等
2,利用主机给从机发送数据,通过主机把DHT11监测的数据,将其发送给从机并将其用串口打印出来

缺点:
1,从机连接主机时候不稳定
2,在从机接收主机发送的温湿度数据时,数据发送完整,但是从机只能接收一段时间,一段时间后就死机了,不在接收数据。不知道什么原因,尚未解决
在这里插入图片描述
总的来说,这次的项目虽说不是完成的特别好,但是收获还是挺多的,代码里有一些是在网上借鉴的代码,以及学习资料里的,如有不足,还请批评指正。

标签:ESP8266,USART,温湿度,void,单片机,DEBUG,GPIO,define,DHT11
来源: https://blog.csdn.net/qq_45476045/article/details/106606805

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有