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

201 lines
6.5 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 "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "LED.h"
#include "DHT11.h"
#include "USART3.h"
#include "LoRa.h"
#include "Relay.h"
/* 在创建任务前,需要创建一个任务句柄,每个任务句柄与任务一一对应。 */
TaskHandle_t xStateLedTaskHdlr;
TaskHandle_t xDht11TaskHdlr;
TaskHandle_t xRelayCtrlTaskHdlr;
TaskHandle_t xLoRaToGateTskHdlr;
TaskHandle_t xLoRaRecMsgTskHdlr;
QueueHandle_t xQueueUsart3ReHdlr;
/* 创建队列句柄 */
QueueHandle_t xQueueTempHdlr;
QueueHandle_t xQueueHumiHdlr;
/* 闪烁LED任务函数参数为空指针返回NULL。 */
void vStateLedTask(void *pvParameters)
{
while(1)
{
vPc13LedOn();
vTaskDelay(1000);
vPc13LedOff();
vTaskDelay(1000);
}
}
void vDht11Task(void *pvParameters)
{
DHT11Data_t xDHT11Data;
/* 数据存储数组。要求与队列参数设置大小一一对应。 */
uint8_t ucSendTempBuffer[5] = {0};
uint8_t ucSendHumiBuffer[5] = {0};
while (1)
{
/* code */
if (vDht11Init() != 0)
{
/* 初始化失败,进行错误处理 */
// vUsart3Printf("DHT11 Init Failed\r\n.");
for (int iIndex = 0; iIndex < 5; iIndex++)
{
ucSendTempBuffer[iIndex] = 0xAA;
vTaskDelay(50);
ucSendHumiBuffer[iIndex] = 0xAA;
vTaskDelay(50);
}
}
if (vDht11ReadData(&xDHT11Data.ucTemp,&xDHT11Data.ucHumi) == 0)
{
/* code */
for (int iIndex = 0; iIndex < 5; iIndex++)
{
/* code */
ucSendTempBuffer[iIndex] = xDHT11Data.ucTemp;
vTaskDelay(50);
ucSendHumiBuffer[iIndex] = xDHT11Data.ucHumi;
vTaskDelay(50);
}
/* 写队列。第一个参数是队列句柄,第二个是写入队列的地址(如数组),第三个是因队列满造成阻塞时的等待时长,也就是无法写入数据时的等待时长,以操作系统默认时钟节拍为准。 */
xQueueSend(xQueueTempHdlr, ucSendTempBuffer, 0);
xQueueSend(xQueueHumiHdlr, ucSendHumiBuffer, 0);
} else
{
// vUsart3Printf("DHT11 Read Data Failed\r\n.");
for (int iIndex = 0; iIndex < 5; iIndex++)
{
ucSendTempBuffer[iIndex] = 0xAB;
vTaskDelay(50);
ucSendHumiBuffer[iIndex] = 0xAB;
vTaskDelay(50);
}
}
}
}
void vLoRaRecMsgTask(void *pvParameters)
{
uint8_t pucRecIsrBuffer[128] = {0};
while (1)
{
/* code */
if (xQueueReceive(xQueueUsart3ReHdlr, pucRecIsrBuffer, 0) == pdTRUE)
{
/* code */
vUsart3SendArray(pucRecIsrBuffer, 1);
}
}
}
void vLoRaToGatePktTask(void *pvParameters)
{
uint8_t ucRecTempBuffer[5] = {0};
uint8_t ucRecHumiBuffer[5] = {0};
/* 定义一个返回值判断是否接收成功 */
BaseType_t xQueueTempRetval, xQueueHumiRetval;
while (1)
{
/* code */
/* 接收队列队列句柄、给哪个接收数据缓冲区和未接收到数据的等待时长分3种情况分别为0、0~portMAX_DELAY和portMAX_DELAY三种分别对应
* 一点不等、等一点时间和等最大时间。在等待队列数据的情况下,该接收队列所在的任务会一直处于阻塞态。
*/
xQueueTempRetval = xQueueReceive(xQueueTempHdlr, ucRecTempBuffer, 0);
xQueueHumiRetval = xQueueReceive(xQueueHumiHdlr, ucRecHumiBuffer, 0);
/* 发送 */
vLoRaConnectionPkt();
vLoRaToGateIdPkt(xLoRaNode1Config.ucLoRaNode1Identifier);
vLoRaToGateSenIdPkt(xLoRaSensorID.ucIdDht11);
/* 检测接收队列是否成功 */
if (xQueueTempRetval == pdTRUE && xQueueHumiRetval == pdTRUE)
{
/* code */
vUsart3SendArray(&ucRecTempBuffer[1], 1);
vUsart3SendArray(&ucRecHumiBuffer[1], 1);
}
vTaskDelay(1500);
}
}
void vTasksList(void)
{
/* 进入临界区 */
taskENTER_CRITICAL();
/* 创建任务,参数分别为任务函数名称、任务名字、栈大小、返回参数值、优先级、任务句柄。 */
xTaskCreate(
(TaskFunction_t ) vStateLedTask,
(char * ) "TaskName_StateLed",
(configSTACK_DEPTH_TYPE) 512,
(void * ) NULL,
(UBaseType_t ) 2,
(TaskHandle_t * ) &xStateLedTaskHdlr);
xTaskCreate(
(TaskFunction_t ) vDht11Task,
(char * ) "TaskName_DHT11",
(configSTACK_DEPTH_TYPE) 1024,
(void * ) NULL,
(UBaseType_t ) 2,
(TaskHandle_t * ) &xDht11TaskHdlr);
xTaskCreate(
(TaskFunction_t ) vLoRaToGatePktTask,
(char * ) "TaskName_LoRaSendToGateway",
(configSTACK_DEPTH_TYPE) 1024,
(void * ) NULL,
(UBaseType_t ) 2,
(TaskHandle_t * ) &xLoRaToGateTskHdlr);
xTaskCreate(
(TaskFunction_t ) vLoRaRecMsgTask,
(char * ) "TaskName_LoRaReceivedMessage",
(configSTACK_DEPTH_TYPE) 1024,
(void * ) NULL,
(UBaseType_t ) 2,
(TaskHandle_t * ) &xLoRaRecMsgTskHdlr);
/* 退出临界区 */
taskEXIT_CRITICAL();
}
void vMainQueuesList(void)
{
/* 创建队列有两个参数,第一个是队列的长度,也就是这个队列能存放多少个数据;
* 第二个参数就是每个数据的大小单位为字节在stm32中uint8_t指针的长度一般是4字节。
* 原函数的返回值就是队列句柄的结构体,所以需要在上面定义一个变量接收队列句柄。 */
xQueueTempHdlr = xQueueCreate(
(UBaseType_t) 5,
(UBaseType_t) sizeof(uint8_t *));
xQueueHumiHdlr = xQueueCreate(
(UBaseType_t) 5,
(UBaseType_t) sizeof(uint8_t *));
xQueueUsart3ReHdlr = xQueueCreate(
(UBaseType_t) 128,
(UBaseType_t) sizeof(uint8_t *));
if (xQueueTempHdlr == NULL || xQueueHumiHdlr == NULL || xQueueUsart3ReHdlr == NULL)
{
/* code */
vUsart3Printf("Queue Init Failed.\r\n");
}
}
int main(void)
{
vFanRelayInit();
vDelayInit();
vPc13LedInit();
vUsart3Init(115200);
vMainQueuesList();
vTasksList();
vTaskStartScheduler();
while(1)
{
}
}