基于STM32F407VET6芯片搭载FreeRTOS物联网操作系统消息队列,实现串口发送命令:openled \ closeled ,打开或者关闭板载的led实验结果
时间: 2024-05-19 20:13:33 浏览: 87
首先,需要在STM32F407VET6上搭载FreeRTOS操作系统,并且实现串口通信功能。接下来,我们可以通过消息队列来实现控制板载LED的开关。
在主函数中,我们创建一个消息队列,然后创建一个任务来接收串口命令并将命令发送到消息队列中。另外,我们还需要创建一个任务来读取消息队列中的数据,并根据命令来控制LED的开关。
下面是一个简单的示例代码:
```c
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "stm32f4xx.h"
#include "stm32f4xx_hal.h"
#define LED_PIN GPIO_PIN_13
#define LED_PORT GPIOC
TaskHandle_t xTask1Handle;
TaskHandle_t xTask2Handle;
QueueHandle_t xQueue;
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = LED_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
}
void USART1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
USART_InitTypeDef USART_InitStruct = {0};
NVIC_InitTypeDef NVIC_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
USART_InitStruct.BaudRate = 115200;
USART_InitStruct.WordLength = USART_WORDLENGTH_8B;
USART_InitStruct.StopBits = USART_STOPBITS_1;
USART_InitStruct.Parity = USART_PARITY_NONE;
USART_InitStruct.Mode = USART_MODE_TX_RX;
USART_InitStruct.CLKPolarity = USART_POLARITY_LOW;
USART_InitStruct.CLKPhase = USART_PHASE_1EDGE;
USART_InitStruct.CLKLastBit = USART_LASTBIT_DISABLE;
HAL_USART_Init(&USART_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
HAL_NVIC_Init(&NVIC_InitStruct);
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
void USART1_IRQHandler(void)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
char cReceivedChar = 0;
if (__HAL_USART_GET_FLAG(&huart1, USART_FLAG_RXNE) != RESET)
{
__HAL_USART_CLEAR_FLAG(&huart1, USART_FLAG_RXNE);
cReceivedChar = (char)(huart1.Instance->DR & 0xFF);
xQueueSendFromISR(xQueue, &cReceivedChar, &xHigherPriorityTaskWoken);
}
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void vTask1(void *pvParameters)
{
char cCommand = 0;
while (1)
{
if (HAL_USART_Receive(&huart1, (uint8_t *)&cCommand, 1, 1000) == HAL_OK)
{
xQueueSend(xQueue, &cCommand, 0);
}
}
}
void vTask2(void *pvParameters)
{
char cReceivedChar = 0;
while (1)
{
if (xQueueReceive(xQueue, &cReceivedChar, portMAX_DELAY) == pdTRUE)
{
switch (cReceivedChar)
{
case 'o':
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_SET);
break;
case 'c':
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_RESET);
break;
default:
break;
}
}
}
}
int main(void)
{
HAL_Init();
LED_Init();
USART1_Init();
xQueue = xQueueCreate(10, sizeof(char));
xTaskCreate(vTask1, "Task 1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &xTask1Handle);
xTaskCreate(vTask2, "Task 2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &xTask2Handle);
vTaskStartScheduler();
while (1)
{
}
}
```
在该示例中,我们使用消息队列来实现串口命令的传递和控制LED的开关。当接收到字符'o'时,我们将板载LED打开,当接收到字符'c'时,我们将板载LED关闭。通过这种方式,我们可以通过串口来控制板载LED的开关。
阅读全文