Index
In FreeRTOS, managing peripherals such as GPIO, UART, I2C, and SPI within tasks allows you to perform input/output operations asynchronously, letting different tasks handle different peripherals. Each task can handle a specific peripheral independently, making the code more modular and allowing you to handle events like sensor data acquisition or communication with external devices.
Example: Working with GPIO, UART, I2C, and SPI in FreeRTOS Tasks
This example sets up:
- GPIO: Toggles an LED at a regular interval.
- UART: Sends a message periodically.
- I2C: Reads a sensor value (simulated here) using the I2C bus.
- SPI: Sends data to an SPI device (simulated here).
Each peripheral is managed by its own FreeRTOS task, allowing each to run independently.
Example Code
In FreeRTOS, managing peripherals such as GPIO, UART, I2C, and SPI within tasks allows you to perform input/output operations asynchronously, letting different tasks handle different peripherals. Each task can handle a specific peripheral independently, making the code more modular and allowing you to handle events like sensor data acquisition or communication with external devices.
Example: Working with GPIO, UART, I2C, and SPI in FreeRTOS Tasks
This example sets up:
- GPIO: Toggles an LED at a regular interval.
- UART: Sends a message periodically.
- I2C: Reads a sensor value (simulated here) using the I2C bus.
- SPI: Sends data to an SPI device (simulated here).
Each peripheral is managed by its own FreeRTOS task, allowing each to run independently.
Example Code:
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/uart.h"
#include "driver/i2c.h"
#include "driver/spi_master.h"
// GPIO Definitions
#define LED_PIN GPIO_NUM_2
// UART Definitions
#define UART_PORT_NUM UART_NUM_1
#define UART_BAUD_RATE 115200
// I2C Definitions
#define I2C_MASTER_SCL_IO 22
#define I2C_MASTER_SDA_IO 21
#define I2C_MASTER_FREQ_HZ 100000
// SPI Definitions
#define SPI_HOST HSPI_HOST
#define SPI_CLK_SPEED 1000000 // 1 MHz
// GPIO Task: Toggle LED
void vGpioTask(void *pvParameters) {
gpio_pad_select_gpio(LED_PIN);
gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);
while (1) {
gpio_set_level(LED_PIN, 1);
vTaskDelay(pdMS_TO_TICKS(500)); // Delay 500ms
gpio_set_level(LED_PIN, 0);
vTaskDelay(pdMS_TO_TICKS(500)); // Delay 500ms
}
}
// UART Task: Send message periodically
void vUartTask(void *pvParameters) {
const char *message = "Hello from UART!\n";
uart_config_t uart_config = {
.baud_rate = UART_BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_driver_install(UART_PORT_NUM, 1024, 0, 0, NULL, 0);
uart_param_config(UART_PORT_NUM, &uart_config);
uart_set_pin(UART_PORT_NUM, 17, 16, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
while (1) {
uart_write_bytes(UART_PORT_NUM, message, strlen(message));
vTaskDelay(pdMS_TO_TICKS(1000)); // Send every 1 second
}
}
// I2C Task: Read data from a simulated I2C sensor
void vI2CTask(void *pvParameters) {
i2c_config_t i2c_config = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ
};
i2c_param_config(I2C_NUM_0, &i2c_config);
i2c_driver_install(I2C_NUM_0, i2c_config.mode, 0, 0, 0);
while (1) {
// Simulated read from sensor address 0x40
uint8_t sensor_addr = 0x40;
uint8_t data = 0;
i2c_master_write_read_device(I2C_NUM_0, sensor_addr, NULL, 0, &data, 1, 1000 / portTICK_PERIOD_MS);
printf("I2C Sensor Data: %d\n", data);
vTaskDelay(pdMS_TO_TICKS(2000)); // Read every 2 seconds
}
}
// SPI Task: Send data periodically
void vSPITask(void *pvParameters) {
spi_bus_config_t buscfg = {
.mosi_io_num = 23,
.miso_io_num = 19,
.sclk_io_num = 18,
.quadwp_io_num = -1,
.quadhd_io_num = -1
};
spi_device_interface_config_t devcfg = {
.clock_speed_hz = SPI_CLK_SPEED,
.mode = 0,
.spics_io_num = 5,
.queue_size = 1
};
spi_bus_initialize(SPI_HOST, &buscfg, SPI_DMA_CH_AUTO);
spi_device_handle_t spi;
spi_bus_add_device(SPI_HOST, &devcfg, &spi);
while (1) {
uint8_t data = 0xAA; // Example data to send
spi_transaction_t transaction = {
.length = 8, // Data length in bits
.tx_buffer = &data,
.rx_buffer = NULL
};
spi_device_transmit(spi, &transaction);
printf("SPI Data Sent: 0x%X\n", data);
vTaskDelay(pdMS_TO_TICKS(1500)); // Send every 1.5 seconds
}
}
void app_main() {
// Create GPIO Task
xTaskCreate(vGpioTask, "GPIO Task", 1024, NULL, 1, NULL);
// Create UART Task
xTaskCreate(vUartTask, "UART Task", 2048, NULL, 1, NULL);
// Create I2C Task
xTaskCreate(vI2CTask, "I2C Task", 2048, NULL, 1, NULL);
// Create SPI Task
xTaskCreate(vSPITask, "SPI Task", 2048, NULL, 1, NULL);
}
Explanation of the Code
- GPIO Task (vGpioTask):
- Configures
LED_PIN
as an output. - Toggles the LED on and off every 500 ms.
- Configures
- UART Task (vUartTask):
- Configures UART with the specified baud rate and pins.
- Sends a message (
"Hello from UART!\n"
) every 1 second.
- I2C Task (vI2CTask):
- Configures the I2C bus and enables pull-up resistors on
SDA
andSCL
lines. - Simulates reading a byte of data from an I2C device at address
0x40
. - Prints the data every 2 seconds.
- Configures the I2C bus and enables pull-up resistors on
- SPI Task (vSPITask):
- Sets up the SPI bus with a clock speed of 1 MHz.
- Transmits
0xAA
to an SPI device every 1.5 seconds and prints confirmation to the console.
app_main()
:- Initializes the FreeRTOS tasks for GPIO, UART, I2C, and SPI, allowing each peripheral to operate independently within its task.
Summary
- GPIO Task: Handles toggling an LED periodically.
- UART Task: Sends data over UART periodically.
- I2C Task: Reads data from an I2C device periodically.
- SPI Task: Sends data to an SPI device periodically.
This example demonstrates how you can manage multiple peripherals in an organized way using FreeRTOS tasks, with each peripheral operating asynchronously without blocking others. This approach is useful in complex embedded applications where various components must operate simultaneously.