RT-Thread(RTT)串口设备使用(附源码)


前言

RTT的串口设备使用记录,这里我使用的是串口2

一、创建RTT工程

在这里插入图片描述

二、选择你所使用的芯片以及调试器

三、创建好的工程

在这里插入图片描述

四、打开board.h头文件

在这里插入图片描述

五、添加如下宏定义,使用串口2,打开串口2的DMA接收

在这里插入图片描述

六、打开RT-Thread Settings

在这里插入图片描述

七、点小箭头

在这里插入图片描述

八、打开串口DMA模式

在这里插入图片描述

九、点击删除再点击保存

在这里插入图片描述

十、删除不必要代码

在这里插入图片描述

十一、代码如下

该代码跟官方的略微有些区别,原因是本人在用官方的代码时收发有点问题 ,进行了些许修改,读者可跟官方例程进行对比尝试

/*
 * Copyright (c) 2006-2024, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-02-03     RT-Thread    first version
 */

#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>


#define SAMPLE_UART_NAME       "uart6"      /* 串口设备名称 */
/* 串口设备句柄 */
static rt_device_t serial;
/* 消息队列控制块 */
static struct rt_messagequeue rx_mq;
/* 串口接收消息结构*/
struct rx_msg
{
    rt_device_t dev;
    rt_size_t size;
};



/* 接收数据回调函数 */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
    struct rx_msg msg;
    rt_err_t result;
    msg.dev = dev;
    msg.size = size;

    result = rt_mq_send(&rx_mq, &msg, sizeof(msg));
    if ( result == -RT_EFULL)
    {
        /* 消息队列满 */
        rt_kprintf("message queue full!\n");
    }
    return result;
}

static void serial_thread_entry(void *parameter)
{
    struct rx_msg msg;
    rt_err_t result;
    rt_uint32_t rx_length;
    static char rx_buffer[RT_SERIAL_RB_BUFSZ + 1];

    while (1)
    {


        rt_memset(&msg, 0, sizeof(msg));
        /* 从消息队列中读取消息*/
        result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER);   //接收不到消息一直等

        if (result == RT_EOK)
        {


            /* 从串口读取数据*/
            rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size);
            rx_buffer[rx_length] = '\0';
            /* 通过串口设备 serial 输出读取到的消息 */
            rt_device_write(serial, 0, rx_buffer, rx_length);
        }

    }
}



int main(void)
{

    rt_err_t ret = RT_EOK;

    char str[] = "hello RT-Thread!\r\n";
    static char msg_pool[256];
    /* 查找串口设备 */
      serial = rt_device_find(SAMPLE_UART_NAME);
      if (!serial)
      {
          rt_kprintf("find %s failed!\n", SAMPLE_UART_NAME);
          return RT_ERROR;
      }

      /* 初始化消息队列 */
       rt_mq_init(&rx_mq, "rx_mq", msg_pool, /* 存放消息的缓冲区 */
       sizeof(struct rx_msg), /* 一条消息的最大长度 */
       sizeof(msg_pool), /* 存放消息的缓冲区大小 */
       RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */


       /* 以 DMA 接收及轮询发送方式打开串口设备 */
        rt_device_open(serial, RT_DEVICE_FLAG_DMA_RX);
        /* 设置接收回调函数 */
        rt_device_set_rx_indicate(serial, uart_input);
        /* 发送字符串 */
        rt_device_write(serial, 0, str, (sizeof(str) - 1));



        /* 创建 serial 线程 */
         rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);


         /* 创建成功则启动线程 */
         if (thread != RT_NULL)
         {
             rt_thread_startup(thread);
         }
         else
         {
             ret = RT_ERROR;
         }



    return ret;
}

十二、编译报错

在这里插入图片描述

十三、跳转注释掉即可

在这里插入图片描述

十四、再编译无报错

在这里插入图片描述

十五、能收能发

在这里插入图片描述

以下是一个基于RT-Thread邮箱通讯的STM32多机串口通讯的例程: ```c #include <rtthread.h> #include "stm32f4xx.h" #define USARTx USART1 /* 定义邮箱 */ static rt_mailbox_t mb; /* 定义一个缓冲区 */ static char buf[32]; /* 定义串口接收中断服务函数 */ void USART1_IRQHandler(void) { /* 判断是否接收到数据 */ if (USART_GetITStatus(USARTx, USART_IT_RXNE) != RESET) { char ch = USART_ReceiveData(USARTx); /* 向邮箱发送数据 */ rt_mb_send(&mb, ch); } } /* 定义线程函数 */ static void recv_thread_entry(void *param) { char ch; while (1) { /* 从邮箱接收数据 */ rt_mb_recv(&mb, (rt_uint32_t *)&ch, RT_WAITING_FOREVER); /* 将接收到的数据存入缓冲区 */ buf[strlen(buf)] = ch; /* 如果接收到了回车换行符,则处理接收到的数据 */ if (ch == '\r') { buf[strlen(buf) - 1] = '\0'; /* 处理接收到的数据 */ rt_kprintf("Received: %s\n", buf); /* 清空缓冲区 */ memset(buf, 0, sizeof(buf)); } } } int main(void) { /* 初始化邮箱 */ rt_mb_init(&mb, "mb", buf, sizeof(char), sizeof(buf) / sizeof(char), RT_IPC_FLAG_FIFO); /* 配置GPIO */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* 配置USART */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USARTx, &USART_InitStructure); USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); USART_Cmd(USARTx, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* 创建线程 */ rt_thread_t recv_thread = rt_thread_create("recv", recv_thread_entry, RT_NULL, 1024, 10, 10); if (recv_thread != RT_NULL) { rt_thread_startup(recv_thread); } while (1); } ``` 在主函数中,我们首先初始化了一个邮箱。然后配置了串口和GPIO,并且开启了串口接收中断,并在中断服务函数中向邮箱发送数据。 我们创建了一个接收线程,在其中从邮箱中接收数据,并将接收到的数据存入缓冲区。当接收到回车换行符时,就可以处理接收到的数据了。 在这个例程中,我们使用RT-Thread的邮箱通讯机制来实现多机串口通讯。在实际应用中,我们可以将这个例程改为适合自己项目的形式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

先睡个好觉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值