[讨论] STM32H7S3L8+RTOS

king86   2026-4-13 21:29 楼主

 

在STM32H7S3L8上运行实时操作系统

 

一、配置STM32CubeMX

打开STM32CubeMX,新建项目并选择STM32H7S3L8芯片。

在 Middleware 中选择 FREERTOS,启用 CMSIS-V1 或 CMSIS-V2 接口。

配置RTOS参数任务数量、堆栈大小等,默认即可。

启用SPI接口

选择 SPI1,配置为 Full-Duplex Master 模式。

设置时钟极性和相位,通常为 CPOL=0, CPHA=0。

分配引脚:

SPI1_SCK → PA5

SPI1_MOSI → PA7

 

配置GPIO

配置 RES(复位)引脚为 GPIO_Output PB0。

配置 DC(数据/命令选择)引脚为 GPIO_Output(PB1)。

可选:配置 BL(背光控制)引脚为 GPIO_Output(PB2)。

生成代码

点击 GENERATE CODE,生成带有RTOS和硬件初始化的项目代码。

编写RTOS任务

在 main() 函数中,使用RTOS API创建LCD任务:

 

二、代码

#include "FreeRTOS.h"

#include "task.h"

#include "stm32h7xx_hal.h"  // 根据芯片型号选择

 

// 任务句柄

TaskHandle_t LCD_Task_Handle = NULL;

 

// 函数声明

void LCD_Task(void *argument);

void ST7789_Init(void);

void ST7789_WriteCommand(uint8_t cmd);

void ST7789_WriteData(uint8_t *data, uint16_t size);

void ST7789_FillScreen(uint16_t color);

 

// SPI句柄(由CubeMX生成)

extern SPI_HandleTypeDef hspi1;

 

// GPIO句柄(由CubeMX生成)

extern GPIO_TypeDef* RES_GPIO_Port;

extern uint16_t RES_Pin;

extern GPIO_TypeDef* DC_GPIO_Port;

extern uint16_t DC_Pin;

 

int main(void) {

    HAL_Init();

    SystemClock_Config();

 

    // 初始化硬件(由CubeMX生成的代码)

    MX_GPIO_Init();

    MX_SPI1_Init();

 

    // 创建LCD任务

    xTaskCreate(LCD_Task, "LCD Task", 256, NULL, 2, &LCD_Task_Handle);

 

    // 启动RTOS调度器

    vTaskStartScheduler();

 

    while (1) {}

}

 

 

#include "stm32h7xx_hal_spi.h"  // 用于SPI传输

 

// 初始化ST7789

void ST7789_Init(void) {

    // 复位LCD

    HAL_GPIO_WritePin(RES_GPIO_Port, RES_Pin, GPIO_PIN_RESET);

    HAL_Delay(100);

    HAL_GPIO_WritePin(RES_GPIO_Port, RES_Pin, GPIO_PIN_SET);

    HAL_Delay(100);

 

    // 发送初始化命令序列(根据ST7789数据手册)

    ST7789_WriteCommand(0x01); // Software reset

    HAL_Delay(150);

 

    // 其他初始化命令...

    // 例如设置显示方向、像素格式等

}

 

// 发送命令到ST7789

void ST7789_WriteCommand(uint8_t cmd) {

    HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, GPIO_PIN_RESET); // DC=0表示命令

    HAL_SPI_Transmit(&hspi1, &cmd, 1, HAL_MAX_DELAY);

}

 

// 发送数据到ST7789

void ST7789_WriteData(uint8_t *data, uint16_t size) {

    HAL_GPIO_WritePin(DC_GPIO_Port, DC_Pin, GPIO_PIN_SET); // DC=1表示数据

    HAL_SPI_Transmit(&hspi1, data, size, HAL_MAX_DELAY);

}

 

// 填充屏幕为单一颜色

void ST7789_FillScreen(uint16_t color) {

    // 设置写内存地址(根据屏幕分辨率调整)

    ST7789_WriteCommand(0x2A); // Column Address Set

    uint8_t col_data[] = {0x00, 0x00, 0x01, 0x3F}; // 假设屏幕宽度为320像素

    ST7789_WriteData(col_data, 4);

 

    ST7789_WriteCommand(0x2B); // Row Address Set

    uint8_t row_data[] = {0x00, 0x00, 0x01, 0xDF}; // 假设屏幕高度为240像素

    ST7789_WriteData(row_data, 4);

 

    ST7789_WriteCommand(0x2C); // Memory Write

 

    // 发送颜色数据(每个像素2字节,共320*240=76800像素)

    uint8_t buffer[2];

    for (int i = 0; i < 320 * 240; i++) {

        buffer[0] = color >> 8; // 高字节

        buffer[1] = color & 0xFF; // 低字节

        ST7789_WriteData(buffer, 2);

    }

}

 

// LCD任务函数

void LCD_Task(void *argument) {

    ST7789_Init(); // 初始化LCD

 

    while (1) {

        ST7789_FillScreen(0xF800); // 填充红色(RGB565格式)

        vTaskDelay(pdMS_TO_TICKS(1000)); // 延时1秒

 

        ST7789_FillScreen(0x07E0); // 填充绿色

        vTaskDelay(pdMS_TO_TICKS(1000));

 

        ST7789_FillScreen(0x001F); // 填充蓝色

        vTaskDelay(pdMS_TO_TICKS(1000));

    }

}

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复