main.c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2025 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "spi.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "rs485.h"
#include "wifi.h"
#include "mqtt.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
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_SPI2_Init();
MX_USART1_UART_Init();
MX_USART3_UART_Init();
MX_UART5_Init();
/* USER CODE BEGIN 2 */
USART1_Init();
UART5_Init();
printf("串口初始化完成\n");
USART3_Init();
WIFI_STAConnectAP();//连接热点
WIFI_Huawei_ConnectService();
uint8_t res=0;
res=MQTT_Connect(MQTT_CLIENT_ID,MQTT_USERNAME,MQTT_PASSWD,6000);
printf("res = %d\n",res);
res=MQTT_SubscribeOneTopic(MQTT_Subscribe_Topic2,6000);
printf("res = %d\n",res);
uint32_t modbus_req_timer = 0; // 请求定时器
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// 1. LED闪烁
HAL_GPIO_TogglePin(LED5_GPIO_Port,LED4_Pin);
HAL_GPIO_TogglePin(LED5_GPIO_Port,LED5_Pin);
HAL_GPIO_TogglePin(LED5_GPIO_Port,LED6_Pin);
HAL_Delay(1000);
// 2. 每1秒发送一次Modbus请求
if (HAL_GetTick() - modbus_req_timer >= 1000)
{
modbus_req_timer = HAL_GetTick();
// 构建请求帧(从站0x01,读取寄存器0x0000开始的4个寄存器)
Modbus_Master_BuildReq(SLAVE_ADDR, REG_START_ADDR, REG_NUM);
// 通过RS485发送请求帧
RS485_SendBuff(modbus_req_frame, sizeof(modbus_req_frame));
// printf("已发送Modbus请求帧\r\n");
}
// 3. 处理USART3接收(解析响应)
USART3_RevDeal();
// 4. 保留原USART1处理
USART1_RevDeal();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
usart.c
/**
******************************************************************************
* @file usart.c
* @brief This file provides code for the configuration
* of the USART instances.
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2025 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "usart.h"
/* USER CODE BEGIN 0 */
#include "rs485.h"
#include "modbus_common.h"
#include "wifi.h"
#include "stm32f4xx_hal_uart.h"
//extern struct USART_DATA wifi_data;
struct USART_DATA usart1_data = {.rx_count=0,.rx_over_flag=0};
/* USER CODE END 0 */
UART_HandleTypeDef huart5;
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart3;
/* UART5 init function */
void MX_UART5_Init(void)
{
/* USER CODE BEGIN UART5_Init 0 */
/* USER CODE END UART5_Init 0 */
/* USER CODE BEGIN UART5_Init 1 */
/* USER CODE END UART5_Init 1 */
huart5.Instance = UART5;
huart5.Init.BaudRate = 9600;
huart5.Init.WordLength = UART_WORDLENGTH_8B;
huart5.Init.StopBits = UART_STOPBITS_1;
huart5.Init.Parity = UART_PARITY_NONE;
huart5.Init.Mode = UART_MODE_TX_RX;
huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart5.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart5) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN UART5_Init 2 */
HAL_UARTEx_ReceiveToIdle_IT(&huart5, usart1_data.rx_buff, USART_RX_LEN);
// HAL_UARTEx_ReceiveToIdle_IT(&huart5, wifi_data.rx_buff, USART_RX_LEN);
/* USER CODE END UART5_Init 2 */
}
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
HAL_UARTEx_ReceiveToIdle_IT(&huart1, wifi_data.rx_buff, USART_RX_LEN);
// HAL_UARTEx_ReceiveToIdle_IT(&huart1, usart1_data.rx_buff, USART_RX_LEN);
/* USER CODE END USART1_Init 2 */
}
/* USART3 init function */
void MX_USART3_UART_Init(void)
{
/* USER CODE BEGIN USART3_Init 0 */
/* USER CODE END USART3_Init 0 */
/* USER CODE BEGIN USART3_Init 1 */
/* USER CODE END USART3_Init 1 */
huart3.Instance = USART3;
huart3.Init.BaudRate = 9600;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart3) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART3_Init 2 */
/* USER CODE END USART3_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==UART5)
{
/* USER CODE BEGIN UART5_MspInit 0 */
/* USER CODE END UART5_MspInit 0 */
/* UART5 clock enable */
__HAL_RCC_UART5_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**UART5 GPIO Configuration
PC12 ------> UART5_TX
PD2 ------> UART5_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART5;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART5;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* UART5 interrupt Init */
HAL_NVIC_SetPriority(UART5_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(UART5_IRQn);
/* USER CODE BEGIN UART5_MspInit 1 */
/* USER CODE END UART5_MspInit 1 */
}
else if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
else if(uartHandle->Instance==USART3)
{
/* USER CODE BEGIN USART3_MspInit 0 */
/* USER CODE END USART3_MspInit 0 */
/* USART3 clock enable */
__HAL_RCC_USART3_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**USART3 GPIO Configuration
PB10 ------> USART3_TX
PB11 ------> USART3_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USART3 interrupt Init */
HAL_NVIC_SetPriority(USART3_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);
/* USER CODE BEGIN USART3_MspInit 1 */
/* USER CODE END USART3_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==UART5)
{
/* USER CODE BEGIN UART5_MspDeInit 0 */
/* USER CODE END UART5_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_UART5_CLK_DISABLE();
/**UART5 GPIO Configuration
PC12 ------> UART5_TX
PD2 ------> UART5_RX
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_12);
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
/* UART5 interrupt Deinit */
HAL_NVIC_DisableIRQ(UART5_IRQn);
/* USER CODE BEGIN UART5_MspDeInit 1 */
/* USER CODE END UART5_MspDeInit 1 */
}
else if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
else if(uartHandle->Instance==USART3)
{
/* USER CODE BEGIN USART3_MspDeInit 0 */
/* USER CODE END USART3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART3_CLK_DISABLE();
/**USART3 GPIO Configuration
PB10 ------> USART3_TX
PB11 ------> USART3_RX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11);
/* USART3 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART3_IRQn);
/* USER CODE BEGIN USART3_MspDeInit 1 */
/* USER CODE END USART3_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/*fputc函数,确定输出流*/
struct USART_DATA wifi_data={.rx_count=0,.rx_over_flag=0};
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,100);
return ch;
}
/*******************************************************************************
函数名称:USART1_Init
函数作用:串口1初始化:启动接收中断
*********************************************************************************/
uint8_t USART1Rev=0;
uint8_t usart5_rx_data;
void USART1_Init(void)
{
// HAL_UART_Receive_IT(&huart1,&USART1Rev,1);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
}
void UART5_Init(void)
{
// HAL_UART_Receive_IT(&huart5,&usart5_rx_data,1);
__HAL_UART_ENABLE_IT(&huart5, UART_IT_RXNE);
__HAL_UART_ENABLE_IT(&huart5,UART_IT_IDLE);
}
/*串口回调函数处理任务*/
uint8_t revBuff[1024]={0};
uint32_t revCount=0;
/*******************************************************************************
函数名称:HAL_UART_RxCpltCallback
函数作用:接收处理回调函数
函数入口:*huart:执行回调函数的串口
*********************************************************************************/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
// if(huart->Instance == USART1)
// {
// revBuff[revCount++] = USART1Rev;
// if(revCount >= sizeof(revBuff)) revCount = 0;
// HAL_UART_Receive_IT(&huart1,&USART1Rev,1);
// }
if(huart->Instance == USART3)
{
rev3Buff[rev3Count++] = USART3Rev;
if(rev3Count >= sizeof(rev3Buff)-1) rev3Count = 0;
HAL_UART_Receive_IT(&huart3,&USART3Rev,1);
}
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if(huart->Instance == USART1)
{
usart1_data.rx_count = Size;
usart1_data.rx_buff[Size] = '\0';
usart1_data.rx_over_flag = 1;
HAL_UARTEx_ReceiveToIdle_IT(&huart1, usart1_data.rx_buff, USART_RX_LEN);
}
if(huart->Instance == UART5)
{
wifi_data.rx_count = Size;
wifi_data.rx_buff[Size] = '\0';
wifi_data.rx_over_flag = 1;
HAL_UARTEx_ReceiveToIdle_IT(&huart5, wifi_data.rx_buff, USART_RX_LEN);
}
}
/*******************************************************************************
函数名称:USART1_RevDeal
函数作用:串口1接收处理
*********************************************************************************/
void USART1_RevDeal(void)
{
if(revCount>=4)
{
RS485_SendString(revBuff);
memset(revBuff,0,revCount);
revCount=0;
}
}
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
usart.h
/**
******************************************************************************
* @file usart.h
* @brief This file contains all the function prototypes for
* the usart.c file
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2025 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USART_H__
#define __USART_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "string.h"
/* USER CODE END Includes */
extern UART_HandleTypeDef huart5;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart3;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_UART5_Init(void);
void MX_USART1_UART_Init(void);
void MX_USART3_UART_Init(void);
/* USER CODE BEGIN Prototypes */
void USART1_Init(void);
void USART1_RevDeal(void);
void UART5_Init(void);
#define USART_RX_LEN 1024
struct USART_DATA
{
uint8_t rx_buff[USART_RX_LEN];//保存接收到的数据
uint32_t rx_count; //保存接收到数据的个数
uint8_t rx_over_flag; //接收完成标志0 -- 没有接收完成
// 1 -- 接收完成
};
extern struct USART_DATA wifi_data;
extern struct USART_DATA usart1_data;
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __USART_H__ */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
wifi.c
#include "wifi.h"
#include "usart.h"
#include <string.h>
#include <stdio.h>
void wifi_Sendbuff(uint8_t *pdata,uint32_t len)
{
if (pdata == NULL || len == 0) // 增加空指针和长度检查,更健壮
return;
HAL_UART_Transmit(&huart5, pdata, len, 100);
}
char *WIFI_FindStr(char *buff,char *ack,uint32_t timeout)
{
while((timeout--) && (strstr(buff,ack) == NULL))//解决busy的bug
{
HAL_Delay(1);
}
return strstr(buff,ack);
}
uint8_t wifi_sendcmd_revack(char *cmd,char *ack,uint32_t timeout,uint8_t cnt)
{
uint32_t len=strlen(cmd);//求出cmd字符串的长度
if(cmd==NULL) return 1;
do
{
//1.发送指令
memset(&wifi_data,0,sizeof(wifi_data));//清除接收缓冲区
wifi_Sendbuff((uint8_t *)cmd,len);
wifi_Sendbuff((uint8_t *)"\r\n",2);//命令以回车+换行结尾
printf("发送指令:%s\n", cmd); // 打印发送的AT指令
//2.等待和判断
if(ack != NULL){
if(WIFI_FindStr((char *)wifi_data.rx_buff,ack,timeout) != NULL)
{
return 0;
}
}
}while(cnt--);
return 2;
}
uint8_t WIFI_STAConnectAP(void)
{
uint8_t res = 0;
char buff[128]="\0";
//1.测试AT
res = wifi_sendcmd_revack("AT","OK",1000,1);
if(res != 0){
printf("AT测试失败\r\n");
return 1;
}
printf("AT测试成功\r\n");
//2.设置Station模式
res = wifi_sendcmd_revack("AT+CWMODE=1","OK",1000,2);
if(res != 0){
printf("AT+CWMODE,设置station模式失败\r\n");
return 2;
}
printf("AT+CWMODE,设置station模式成功\r\n");
//3.连接热点
//sprintf(buff,"AT+CWJAP=\"%s\",\"%s\"",SSID,PASSSWD);
sprintf(buff,"AT+CWJAP=\"%s\",\"%s\"",SSID,PASSSWD);
res = wifi_sendcmd_revack(buff,"GOT IP",3000,10);
if(res != 0){
printf("AT+CWJAP,连接热点失败\r\n");
return 3;
}
printf("AT+CWJAP,连接热点成功\r\n");
return 0;
}
uint8_t WIFI_Huawei_ConnectService(void)
{
uint8_t res = 0;
char buff[128]="\0";
//1.连接服务器
sprintf(buff,"AT+CIPSTART=\"TCP\",\"%s\",%s",IP,PORT);
res = wifi_sendcmd_revack(buff,"CONNECT",3000,5);
if(res != 0){
printf("AT+CIPSTART,连接服务器失败\r\n");
return 1;
}
printf("AT+CIPSTART,连接服务器成功\r\n");
//2.设置为透传模式
res = wifi_sendcmd_revack("AT+CIPMODE=1","OK",3000,5);
if(res != 0){
printf("AT+CIPMODE,设置透传模式失败\r\n");
return 2;
}
printf("AT+CIPMODE,设置透传模式成功\r\n");
//3.发送AT+CIPSEND指令
res = wifi_sendcmd_revack("AT+CIPSEND",">",3000,5);
if(res != 0){
printf("AT+CIPSEND,发送指令失败\r\n");
return 3;
}
printf("AT+CIPSEND,发送指令成功\r\n");
return 0;
}
wifi.h
#ifndef _WIFI_H_
#define _WIFI_H_
#include "stm32f4xx.h"
#include "usart.h"
#include "string.h"
//#include "stm32_eval_spi_flash.h"
#define SSID "abcde"//要连接热点的名字
#define PASSSWD "12345678"//要连接热点的密码
//安信可的透传云
//#define IP "36.137.226.30"
//#define PORT "42504"
#define IP "04ebd3a6bb.st1.iotda-device.cn-east-3.myhuaweicloud.com"
#define PORT "1883"
void wifi_Sendbuff(uint8_t *pdata,uint32_t len);
char *WIFI_FindStr(char *buff,char *ack,uint32_t timeout);
uint8_t wifi_sendcmd_revack(char *cmd,char *ack,uint32_t timeout,uint8_t cnt);
uint8_t WIFI_STAConnectAP(void);
uint8_t WIFI_Huawei_ConnectService(void);
#endif
mqtt.c
#include "mqtt.h"
#define WIFI_TX_MAX_LEN 1024
uint8_t wifi_tx_buff[WIFI_TX_MAX_LEN]="\0";//存放报文的缓冲区
uint32_t wifi_tx_len = 0;//wifi发送数据的个数
uint8_t MQTT_Connect(char *client_id,char *username,char *passwd,uint32_t timeout)
{
uint8_t res = 0;//保存返回值
//1.构成Connect报文(N个二进制数据)
MQTTPacket_connectData options = MQTTPacket_connectData_initializer;//结构体初始化
// options.cleansession = 1;//开启清除会话
options.clientID.cstring = client_id;//保存设备ID号
options.keepAliveInterval = 120;
// options.MQTTVersion = 4;//MQTT版本号:3.1.1
options.password.cstring = passwd;//保存用户密码
options.username.cstring = username;//保存用户名
// options.willFlag = 0;//不使用遗嘱功能
wifi_tx_len = MQTTSerialize_connect(wifi_tx_buff,WIFI_TX_MAX_LEN,&options);
//2.通过WIFI发送给华为云服务器
//2.1 清除WIFI接收缓冲区,方便后续接收服务器应答
memset(&wifi_data,0,sizeof(wifi_data));
//2.2 发送Connect报文
wifi_Sendbuff(wifi_tx_buff,wifi_tx_len);
// 固定报头 可变报头(会话标志+连接返回码)
//3.等待CONNACK报文(云服务器给设备端) 0x20 0x02 0x00/0x01 0x00(成功) ~ 0x05
while(timeout && wifi_data.rx_over_flag == 0)
{
timeout--;
HAL_Delay(1);
}
if(timeout == 0){//超时
res = 1;
goto over;
}
if(wifi_data.rx_count < 4){//数据不完整
res = 2;
goto over;
}
switch(wifi_data.rx_buff[3])//解析数据 -- 可变报头中的连接返回码
{
case 0:res = 0;break;
default:res = wifi_data.rx_buff[3]+2;break;
}
over:
wifi_data.rx_count = 0;
wifi_data.rx_over_flag = 0;
return res;
}
uint8_t MQTT_Publish(char *topic,char *pdata)
{
//MQTTString topicName = {NULL,{0,NULL}};
//MQTTString topicName = MQTTString_initializer;
MQTTString topicName = {0};
int len = strlen(pdata);
//1.生成Publish报文
topicName.cstring = topic;
wifi_tx_len = MQTTSerialize_publish(wifi_tx_buff,WIFI_TX_MAX_LEN,0,0,0,0,topicName,(uint8_t *)pdata,len);
//2.通过WIFI发送给华为云服务器
//2.1 清除WIFI接收缓冲区,方便后续接收服务器应答
memset(&wifi_data,0,sizeof(wifi_data));
//2.2 发送Connect报文
wifi_Sendbuff(wifi_tx_buff,wifi_tx_len);
return 0;
}
uint8_t dht11_t;
uint8_t dht11_h;
uint16_t temp_mq2,temp_mq135;
uint16_t light_val; // 光照值
uint16_t people_state; // 人体检测状态(0=无人,1=有人)
#define PUBLISH_DATA_MAX_LEN 512
char publish_data_buff[PUBLISH_DATA_MAX_LEN]="\0";
char *GetPublish_Topic1Data(void)
{
//1.缓冲区清零
memset(publish_data_buff,0,PUBLISH_DATA_MAX_LEN);
//2.赋值
sprintf(publish_data_buff,"{\
\"services\": [{\
\"service_id\": \"value_sensor\",\
\"properties\": {\
\"temp\":%.1f,\
\"hum\":%.1f,\
\"light\":%d,\
\"MQ2\":%d,\
\"MQ135\":%d\
\"people\":%d\
}\
}]\
}",dht11_t,dht11_h,light_val,temp_mq2, temp_mq135 ,people_state);
return publish_data_buff;
}
uint8_t MQTT_SubscribeOneTopic(char *topic,uint32_t timeout)
{
uint8_t res = 0;//保存返回值
MQTTString topicFilters[1];//保存topic列表 -- 只保存1个
int requestedQoSs[1];//每个主题列表的QoS
topicFilters[0].cstring = topic;
//1.构成Subscribe报文(N个二进制数据)
wifi_tx_len = MQTTSerialize_subscribe(wifi_tx_buff,WIFI_TX_MAX_LEN,0,10,1,topicFilters,requestedQoSs);
//2.通过WIFI发送给华为云服务器
//2.1 清除WIFI接收缓冲区,方便后续接收服务器应答
memset(&wifi_data,0,sizeof(wifi_data));
//2.2 发送Connect报文
wifi_Sendbuff(wifi_tx_buff,wifi_tx_len);
// 固定报头 可变报头(报文标识符) 有效载荷
//3.等待SUBACK报文(云服务器给设备端) 0x90 0x03 0x00 0x0A 0x80失败 其他成功
while(timeout && wifi_data.rx_over_flag == 0)
{
timeout--;
HAL_Delay(1);
}
if(timeout == 0){//超时
res = 1;
goto over;
}
if(wifi_data.rx_count < 4){//数据不完整
res = 2;
goto over;
}
switch(wifi_data.rx_buff[4])//解析数据 -- 可变报头中的连接返回码
{
case 0x80:res = 3;break;
default:res = 0;break;
}
over:
wifi_data.rx_count = 0;
wifi_data.rx_over_flag = 0;
return res;
}
char *GetPublish_Topic2Data(void)
{
//1.缓冲区清零
memset(publish_data_buff,0,PUBLISH_DATA_MAX_LEN);
//2.赋值
sprintf(publish_data_buff,"{ \
\"object_device_id\": \"{object_device_id}\", \
\"services\": [{ \
\"service_id\": \"$time_sync\", \
\"event_type\": \"time_sync_request\", \
\"event_time\": \"20151212T121212Z\",\
\"paras\": { \
\"device_send_time\": 1582685678789\
} \
}] \
}");
return publish_data_buff;
}
mqtt.h
#ifndef _MQTT_H_
#define _MQTT_H_
#include "stm32f4xx.h"
#include "MQTTPacket.h"
#include "usart.h"
#include "wifi.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#define MQTT_CLIENT_ID "68e775f754ed1814a9b1d74d_znly_0_0_2025100911"
#define MQTT_USERNAME "68e775f754ed1814a9b1d74d_znly"
#define MQTT_PASSWD "dbf32623f0a67d2c1ea4734ca1a939ceea83d66a3ce9ee320f4c1ba8a8b71032"
#define MQTT_Publish_Topic1 "$oc/devices/68e775f754ed1814a9b1d74d_znly/sys/properties/report"
#define MQTT_Publish_Topic2 "$oc/devices/68e775f754ed1814a9b1d74d_znly/sys/events/up"
#define MQTT_Subscribe_Topic1 "$oc/devices/68e775f754ed1814a9b1d74d_znly/user/beep"
#define MQTT_Subscribe_Topic2 "$oc/devices/68e775f754ed1814a9b1d74d_znly/sys/events/down"
uint8_t MQTT_Connect(char *client_id,char *username,char *passwd,uint32_t timeout);
uint8_t MQTT_Publish(char *topic,char *pdata);
char *GetPublish_Topic1Data(void);
uint8_t MQTT_SubscribeOneTopic(char *topic,uint32_t timeout);
char *GetPublish_Topic2Data(void);
//uint8_t MQTT_RTC_Sync(void);
#endif
结合上述所有代码,仔细分析为什么AT指令发送不出去,为什么AT测试失败,是不是串口的问题
最新发布