stm32学习:hal库usart+esp8266+tcp+onenet+可以远程监督家里情况

发布时间:2023年12月17日

目录

准备材料

步骤

stm32f103c8t6

在stm32clube里创建项目

先配置调试接口SYS(博主用的是stlink,选的是SW),配置外部时钟源RCC,总线时钟频数72

配置串口(波特率为115200)

?编辑?看各自需要配置不同硬件的io口

esp8266

代码

订阅串口数据,在usart.h里,可以更改

先配置usart2中断函数,在main.c里

在main函数里配置中断优先级,和使能串口中断

再写按顺序发送AT指令来初始化esp8266函数,在esp8266.c里

我们在发送指令的同时,要判断它是否成功配置指令,在串口中断函数里有判断,来改变标志位,获取标志位来判断是否成功配置指令

构建发送到onenet的数据,最后的数据要json格式

发送onenet数据

main主函数

完整文件在标题下,博主的加了一些其他文件,你们要加到自己的文件里就把esp8266.c和esp8266.c拉到你们的项目中调用就好?


准备材料

  1. stm32f103c8t6
  2. esp8266
  3. 各种器件,例如温湿度,烟雾,灯光,按钮什么都可以(只是让我们有信息可以传,没有就传数字来测试)
  4. onenet的配置请看前面发的文章物联网平台:网络调试助手+HTTP+上传数据到onenet-CSDN博客

步骤

stm32f103c8t6

在stm32clube里创建项目

先配置调试接口SYS(博主用的是stlink,选的是SW),配置外部时钟源RCC,总线时钟频数72
配置串口(波特率为115200)

?看各自需要配置不同硬件的io口

esp8266

大家可以先学习一下AT指令,这里简单讲一下案例要用的(下面返回值空的是空行)

需要先配置好波特率,esp8266接线也是用ttl,用串口调试助手,选择厂家初始的波特率,然后就可以调试esp8266了 ,修改波特率指令是(记住勾选新行)

AT+UART=9600,8,1,0,0

代码

我们要用stm32的usart2来发送AT指令来控制esp8266来连接网络

订阅串口数据,在usart.h里,可以更改

//串口2
//串口接收缓存(1字节)
uint8_t buf1=0;
//定义最大接收字节数 200,可根据需求调整
#define UART2_REC_LEN 200
// 接收缓冲, 串口接收到的数据放在这个数组里,最大UART2_REC_LEN个字节
uint8_t UART2_RX_Buffer[UART2_REC_LEN];
//  接收状态bit15,      接收完成标志,bit14,      接收到0x0d,bit13~0,    接收到的有效字节数目
uint16_t UART2_RX_STA=0;

先配置usart2中断函数,在main.c里

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	// 判断中断是由哪个串口触发的
	if(huart->Instance == USART2)
	{
		// 判断接收是否完成(UART1_RX_STA bit15 位是否为1)
		if((UART2_RX_STA & 0x8000) == 0)
		{
			// 如果已经收到了 0x0d (回车),
			if(UART2_RX_STA & 0x4000)
			{
				// 则接着判断是否收到 0x0a (换行)
				if(buf1 == 0x0a)
				{
					// 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
					UART2_RX_STA |= 0x8000;

					// 查看是否收到 WIFI GOT IP
					if(!strcmp((char *)UART2_RX_Buffer, "WIFI GOT IP"))
						AT_Connect_Net_Flag = 1;
					
					// 查看是否收到 OK
					if(!strcmp((char *)UART2_RX_Buffer, "OK"))
						AT_OK_Flag = 1;
					
					if(!strcmp((char *)UART2_RX_Buffer, ">"))
						fuhao_Connect_Flag = 1;
					
					// 查看是否收到 FAIL
					if(!strcmp((char *)UART2_RX_Buffer, "CONNECT"))
						Client_Connect_Flag	= 1;
					
					if(!strcmp((char *)UART2_RX_Buffer, "{\"errno\":0,\"error\":\"succ\""))
						succ_Flag	= 1;
					
					memset(UART2_RX_Buffer, 0, UART2_REC_LEN);
					UART2_RX_STA = 0;
				}
				else
					// 否则认为接收错误,重新开始
					UART2_RX_STA = 0;
			}
			else	// 如果没有收到了 0x0d (回车)
			{
				//则先判断收到的这个字符是否是 0x0d (回车)
				if(buf1 == 0x0d)
				{
					// 是的话则将 bit14 位置为1
					UART2_RX_STA |= 0x4000;
				}
				else
				{
					// 否则将接收到的数据保存在缓存数组里
					UART2_RX_Buffer[UART2_RX_STA & 0X3FFF] = buf1;
					UART2_RX_STA++;
					
					// 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
					if(UART2_RX_STA > UART2_REC_LEN - 1)
						UART2_RX_STA = 0;
				}
			}
		}
		// 重新开启中断
		HAL_UART_Receive_IT(&huart2, &buf1, 1);
	}
}

在main函数里配置中断优先级,和使能串口中断


	HAL_NVIC_SetPriority(SysTick_IRQn,0,0);//设置特定中断的优先级
	HAL_UART_Receive_IT(&huart2, &buf1, 1);

再写按顺序发送AT指令来初始化esp8266函数,在esp8266.c里


#define ESP8266_WIFI_INFO		"AT+CWJAP=\"Reds\",\"23333334\"\r\n"

#define ESP8266_ONENET_INFO		"AT+CIPSTART=\"TCP\",\"183.230.40.33\",80\r\n"
//初始化ESP8266
void ESP8266_Init(void)
{
	
	while(ESP8266_SendCmd("AT\r\n", 1))
		HAL_Delay(1500);
		HAL_Delay(2000);
	
	while(ESP8266_SendCmd("AT+CWMODE=1\r\n", 1))
		HAL_Delay(1500);
		HAL_Delay(2000);
	
	while(ESP8266_SendCmd(ESP8266_WIFI_INFO, 2))
		HAL_Delay(1500);
		HAL_Delay(2000);
	
	while(ESP8266_SendCmd(ESP8266_ONENET_INFO, 3))
		HAL_Delay(1500);
		HAL_Delay(2000);

}

我们在发送指令的同时,要判断它是否成功配置指令,在串口中断函数里有判断,来改变标志位,获取标志位来判断是否成功配置指令

int AT_OK_Flag = 0;				//OK返回值的标志位
int AT_Connect_Net_Flag = 0;		//WIFI GOT IP返回值的标志位
int Client_Connect_Flag = 0;    //连接tcp服务端标志位
int fuhao_Connect_Flag = 0;    //进入发送数据标志位
int succ_Flag = 0;            //发送成功标志位



//发送命令  cmd 命令  res要选择什么标志位
int ESP8266_SendCmd(char *cmd,int res)
{
	
	unsigned char timeOut = 200;
	
	HAL_UART_Transmit(&huart2, (unsigned char *)cmd, strlen((const char *)cmd), 0xffff);
	
		if(res == 1)
		{
			while(!AT_OK_Flag&&timeOut--) HAL_Delay(50);
			if(AT_OK_Flag)
			{
				AT_OK_Flag = 0;
				return 0;
			}
		}
		else if(res == 2)
		{
			while( ( !AT_OK_Flag || !AT_Connect_Net_Flag ) && timeOut--) HAL_Delay(50);
			if(fuhao_Connect_Flag||AT_OK_Flag)
			{
				AT_OK_Flag = 0;
				AT_Connect_Net_Flag = 0;
				return 0;
			}
		}
		else if(res == 3)
		{
			while(!Client_Connect_Flag&&timeOut--)  HAL_Delay(50);
			if(Client_Connect_Flag)
			{
				Client_Connect_Flag = 0;
				return 0;
			}
		}
		else if(res == 4)
		{
			while( ( !AT_OK_Flag || !fuhao_Connect_Flag ) && timeOut--) HAL_Delay(50);
			if(fuhao_Connect_Flag||AT_OK_Flag)
			{
				AT_OK_Flag = 0;
				fuhao_Connect_Flag = 0;
				return 0;
			}
		}
	 
	return 1;

}

构建发送到onenet的数据,最后的数据要json格式

//设备id
#define DEVID	"1026566033"
//密钥
#define APIKEY	"C7elqJfUjB=ynk=fpdQVJZ7yTfY="

void OneNet_FillBuf(char *buf)
{
	
	char data[24];
	char json[128];
	
	memset(data, 0, sizeof(data));
	memset(json, 0, sizeof(json));
	
	strcpy(json, "{");
	
	memset(data, 0, sizeof(data));
	sprintf(data, "\"Test1\":123,");
	strcat(json, data);
	
	memset(data, 0, sizeof(data));
	sprintf(data, "\"Test2\":789,");
	strcat(json, data);
	
	strcat(json, "}");
	
	sprintf(buf, "POST /devices/%s/datapoints?type=3 HTTP/1.1\r\napi-key:%s\r\nHost:api.heclouds.com\r\nConnection:close\r\n"
					"Content-Length:%d\r\n\r\n",
	
					DEVID, APIKEY, strlen(json));
					
	strcat(buf, json);

}

发送onenet数据

void OneNet_SendData(void)
{
	char buf[256];
	
	memset(buf, 0, sizeof(buf));
	
	OneNet_FillBuf(buf);								
	
	ESP8266_SendData((unsigned char *)buf, strlen(buf));
	
}

main主函数

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_USART2_UART_Init();
  MX_TIM4_Init();
  /* USER CODE BEGIN 2 */
  HAL_NVIC_SetPriority(SysTick_IRQn,0,0);//设置特定中断的优先级
  HAL_UART_Receive_IT(&huart2, &buf1, 1);
	
  int i=0;
  int flag=0;
	
  ESP8266_Init();
  OneNet_SendData();
  
  
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	i++;
	if(i == 20)
	{	
	  i=0;
		if(flag==0)
		{
			open_led();
			flag =1;
		}
		else
		{
			close_led();
			flag =0;
		}
		HAL_Delay(1000);
	}
  }
  /* USER CODE END 3 */
}

完整文件在标题下,博主的加了一些其他文件,你们要加到自己的文件里就把esp8266.c和esp8266.c拉到你们的项目中调用就好?

文章来源:https://blog.csdn.net/weixin_59669309/article/details/134985447
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。