Files
FreeRTOS_LoRa_Environment_A…/STM32/Gateway_Node/User/main.c

280 lines
8.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "USART.h"
#include "LED.h"
#include "ESP8266.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "App_MQTT.h"
/* 创建一个新任务,需要创建任务句柄,任务句柄与任务函数一一对应。 */
TaskHandle_t xTaskWorkStatusLedHdlr;
TaskHandle_t xTaskWifiJoinApHdlr;
TaskHandle_t xTaskWifiNwkInitHdlr;
TaskHandle_t xTaskMqttPublishHdlr;
TaskHandle_t xTaskMqttSubscribeHdlr;
/* 创建队列句柄 */
QueueHandle_t xQueueUsart1IrqHdlr;
QueueHandle_t xQueueUsart2IrqHdlr;
QueueHandle_t xQueueUsart3IrqHdlr;
/**
* @brief 状态指示LED任务
* @note 通过控制PC13引脚的LED灯实现系统状态的指示功能。
* @param *pvParameters 任务参数,若没有特定的参数则设置为空指针
* @retval None
*/
void vTaskWorkStatusLed(void *pvParameters)
{
while(1)
{
vPc13LedOn();
vTaskDelay(1000);
vPc13LedOff();
vTaskDelay(1000);
}
}
/**
* @brief 初始化Wi-Fi模块网络任务
* @note 通过ESP8266模块初始化MQTT协议连接。
* @param *pvParameters 任务参数,若没有特定的参数则设置为空指针
* @retval None
*/
void vTaskWifiNetWorkInit(void *pvParameters)
{
while (1)
{
vEsp8266GpioConfig();
vEsp8266AtTest();
if (bEsp8266NetModeChoose(STA) == pdTRUE)
{
vUsartSendString(USART1, "Set ESP8266 Net Mode Successfully.\r\n");
} else
{
/* code */
vUsartSendString(USART1, "Set ESP8266 Net Mode Failed.\r\n");
continue;
}
if (bEsp8266JoinAp(ESP8266_APSSID, ESP8266_APPWD) == pdTRUE)
{
vUsartSendString(USART1, "Wifi Join To AP Successfully.\r\n");
} else
{
/* code */
vUsartSendString(USART1, "Wifi Join To AP Failed.\r\n");
continue;
}
#if (ESP8266_MQTT_SERVER_MODE == ALIYUN)
if (bEsp8266MqttInit(ESP8266_ALIYUN_MQTT_USERNAME, ESP8266_ALIYUN_MQTT_PASSWORD, ESP8266_ALIYUN_MQTT_CLIENTID,
ESP8266_ALIYUN_MQTT_IP, ESP8266_ALIYUN_MQTT_PORT, ESP8266_ALIYUN_MQTT_SUBSCRIBE_TOPIC) == pdTRUE)
{
/* code */
vUsartSendString(USART1, "Aliyun MQTT Init Successfully.\r\n");
/* 通知MQTT发布任务 */
xTaskNotifyGive(xTaskMqttPublishHdlr);
xTaskNotifyGive(xTaskMqttSubscribeHdlr);
vTaskDelete(NULL);
} else
{
/* code */
vUsartSendString(USART1, "Aliyun MQTT Init Failed.\r\n");
continue;
}
#elif (ESP8266_MQTT_SERVER_MODE == EMQX)
if (bEsp8266MqttInit(ESP8266_EMQX_MQTT_USERNAME, ESP8266_EMQX_MQTT_PASSWORD, ESP8266_EMQX_MQTT_CLIENTID,
ESP8266_EMQX_MQTT_SERVER_IP, ESP8266_EMQX_MQTT_SERVER_PORT, ESP8266_EMQX_MQTT_SUBSCRIBE_TOPIC) == pdTRUE)
{
/* code */
vUsartPrintf(USART1, "EMQX MQTT Init Successfully.\r\n");
xTaskNotifyGive(xTaskMqttPublishHdlr);
xTaskNotifyGive(xTaskMqttSubscribeHdlr);
vTaskDelete(NULL);
} else
{
/* code */
vUsartSendString(USART1, "EMQX MQTT Init Failed.\r\n");
continue;
}
#endif
}
}
/**
* @brief MQTT发布测试任务
* @note 通过ESP8266模块向MQTT服务器发布测试消息。
* @param *pvParameters 任务参数,若没有特定的参数则设置为空指针
* @retval None
*/
void vTaskMqttPublish(void *pvParameters)
{
/* 任务通知接收函数 */
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
char *pcJsonMsg = "{\"temperature\":23,\"humidity\":60}";
while (1)
{
/* code */
#if (ESP8266_MQTT_SERVER_MODE == ALIYUN)
while (bMqttPublish(ESP8266_ALIYUN_MQTT_PUBLISH_TOPIC, pcJsonMsg) == pdTRUE)
{
/* code */
vUsartSendString(USART1, "MQTT Publish Successfully.\r\n");
}
vUsartSendString(USART1, "MQTT Publish Failed.\r\n");
vTaskDelay(2000);
#elif (ESP8266_MQTT_SERVER_MODE == EMQX)
while (bMqttPublish(ESP8266_EMQX_MQTT_PUBLISH_TOPIC, pcJsonMsg) == pdTRUE)
{
/* code */
vUsartSendString(USART1, "MQTT Publish Successfully.\r\n");
}
vUsartSendString(USART1, "MQTT Publish Failed.\r\n");
vTaskDelay(2000);
#endif
}
}
/**
* @brief MQTT订阅任务
* @note 通过ESP8266模块订阅MQTT主题并处理接收到的命令。
* @param *pvParameters 任务参数,若没有特定的参数则设置为空指针
* @retval None
*/
void vTaskMqttSubscribe(void *pvParameters)
{
while (1)
{
/* code */
if (xMqttCmdParse(ESP8266_EMQX_MQTT_SUBSCRIBE_TOPIC) == MQTT_CMD_LED_ON)
{
/* code */
vUsartPrintf(USART1, "Lights on\r\n");
}
else if (xMqttCmdParse(ESP8266_EMQX_MQTT_SUBSCRIBE_TOPIC) == MQTT_CMD_LED_OFF)
{
/* code */
vUsartPrintf(USART1, "Lights off\r\n");
}
else if (xMqttCmdParse(ESP8266_EMQX_MQTT_SUBSCRIBE_TOPIC) == MQTT_CMD_FAN_ON)
{
/* code */
vUsartPrintf(USART1, "Fan on\r\n");
}
else if (xMqttCmdParse(ESP8266_EMQX_MQTT_SUBSCRIBE_TOPIC) == MQTT_CMD_FAN_OFF)
{
/* code */
vUsartPrintf(USART1, "Fan off\r\n");
}
else if (xMqttCmdParse(ESP8266_EMQX_MQTT_SUBSCRIBE_TOPIC) == MQTT_CMD_HUMIDIFIER_ON)
{
/* code */
vUsartPrintf(USART1, "Humidifier on\r\n");
}
else if (xMqttCmdParse(ESP8266_EMQX_MQTT_SUBSCRIBE_TOPIC) == MQTT_CMD_HUMIDIFIER_OFF)
{
/* code */
vUsartPrintf(USART1, "Humidifier off\r\n");
}
vTaskDelay(1000);
}
}
/**
* @brief 创建所有任务列表
* @note 在此函数中创建所有需要的任务,并为每个任务分配适当的堆栈大小和优先级。
* @param None
* @retval None
*/
void vCreateTasksList(void)
{
xTaskCreate(
(TaskFunction_t ) vTaskWorkStatusLed,
(char * ) "TaskName_StateLed",
(configSTACK_DEPTH_TYPE) 256,
(void * ) NULL,
(UBaseType_t ) 2,
(TaskHandle_t * ) &xTaskWorkStatusLedHdlr);
xTaskCreate(
(TaskFunction_t ) vTaskWifiNetWorkInit,
(char * ) "TaskName_WifiInitMQTTProtocol",
(configSTACK_DEPTH_TYPE) 512,
(void * ) NULL,
(UBaseType_t ) 2,
(TaskHandle_t * ) &xTaskWifiNwkInitHdlr);
xTaskCreate(
(TaskFunction_t ) vTaskMqttPublish,
(char * ) "TaskName_MqttPublishTest",
(configSTACK_DEPTH_TYPE) 512,
(void * ) NULL,
(UBaseType_t ) 2,
(TaskHandle_t * ) &xTaskMqttPublishHdlr);
xTaskCreate(
(TaskFunction_t ) vTaskMqttSubscribe,
(char * ) "TaskName_MqttSubscribe",
(configSTACK_DEPTH_TYPE) 512,
(void * ) NULL,
(UBaseType_t ) 2,
(TaskHandle_t * ) &xTaskMqttSubscribeHdlr);
}
/**
* @brief 创建所有队列列表
* @note 在此函数中创建所有需要的队列,并为每个队列分配适当的长度和项大小。
* @param None
* @retval None
*/
void vCreateQueuesList(void)
{
#if (ENABLE_FREERTOS_API_QUEUE_USART1_IRQ == 1)
xQueueUsart1IrqHdlr = xQueueCreate(
(UBaseType_t) 64,
(UBaseType_t) sizeof(uint8_t *));
#endif
#if (ENABLE_FREERTOS_API_QUEUE_USART2_IRQ == 1)
xQueueUsart2IrqHdlr = xQueueCreate(
(UBaseType_t) 1024,
(UBaseType_t) sizeof(char *));
#endif
#if (ENABLE_FREERTOS_API_QUEUE_USART3_IRQ == 1)
xQueueUsart3IrqHdlr = xQueueCreate(
(UBaseType_t) 64,
(UBaseType_t) sizeof(uint8_t *));
#endif
}
/**
* @brief 创建所有信号量列表
* @note 在此函数中创建所有需要的信号量。
* @param None
* @retval None
*/
void vCreateSemaphoresList(void)
{
}
/**
* @brief 主函数
* @note 初始化系统各个模块,创建任务、队列和信号量,并启动调度器。
* @param None
* @retval int
*/
int main(void)
{
vUsartInit(USART1, 115200);
vUsartInit(USART2, 115200);
vUsartInit(USART3, 115200);
vDelayInit();
vPc13LedInit();
vCreateTasksList();
vCreateQueuesList();
vCreateSemaphoresList();
vTaskStartScheduler();
while(1)
{
}
}