RT-Thread论坛
直播中

华仔stm32

3年用户 2899经验值
擅长:嵌入式技术
私信 关注
[作品]

【Vision Board创客营连载体验】UART模版评测

1、下载源码

https://gitee.com/rtthread/rt-thread

2、下载env:rt-thread.org/download.html#download-rt-thread-env-tool

官网有详细的安装教程

3、下载源码并安装好env工具后,进入rt-thread-master\bsp\renesas目录下面把ra8d1-vision-board文件夹复制一份,重命名为ra8d1-vision-board_uart。

4、安装RSCA工程。该工具可以去瑞萨的官网下载,也可以到RTT活动提供的网盘进行下载。开发板资料链接:https://pan.baidu.com/s/1O38xjFGV2K1RP7tP1WlcvA?pwd=ra8v

下载好后,有详细的安装教程,此处不做详述。

【确定使用的串口号】

在vision-board中,有40pin的兼容树莓派的接口,经查看原理图与接口,决定此次使用UART2来做实验。

原理图中,确实了uart2的接口如下,即第8、10分别为TX与RX。
image.png

5、进入工程目录,右键打开env,输入menuconfig,进入→ Hardware Drivers Config → On-chip Peripheral Drivers → Enable UART。按空格键开启UART2
image.png

退出后保存。

6、保存后输入scons --target=mdk5来生成mdk5工程。

image.png

7、使用mdk5打开工程。这里配置好uart2,编译工程会报错的,还需要使用RASC工具来配置UART2。在工程中按下图所示打开RASC:
image.png

进入RASC中我们选择stack->new stack->Connectivity->UART(r_sci_b_uart)。创建好进和这个stact修改属性为uart2,如下图所示:
image.png

还需要打开中断,填写中断回调函数为user_uart2_callback

image.png

配置好生保存配置,并按Generate Project Content重新生成一下工程。

image.png

生成工程后编译,并下载,打开串口终端,使用list device查看,有uart2初始化成功了。

image.png

【编写测试代码】

1、新建一个my_uart_test.c,把它存放在src目录下面,添加一个UART/test分组,把my_uart_test.c添回进分组中。

2、引入头文件、debug、以及定义串口uart2

/*
 * 程序清单:这是一个 串口 设备使用例程
 * 例程导出了 uart_sample 命令到控制终端
 * 命令调用格式:uart_sample uart2
 * 命令解释:命令第二个参数是要使用的串口设备名称,为空则使用默认的串口设备
 * 程序功能:通过串口输出字符串"hello RT-Thread!",然后错位输出输入的字符
*/

#include <rtthread.h>

#define TEST_UART_NAME       "uart2"

/* 用于接收消息的信号量 */
static struct rt_semaphore rx_sem;
static rt_device_t serial;

/* 接收数据回调函数 */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
    /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */
    rt_sem_release(&rx_sem);

    return RT_EOK;
}

static void serial_thread_entry(void *parameter)
{
    char ch;

    while (1)
    {
        /* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */
        while (rt_device_read(serial, -1, &ch, 1) != 1)
        {
            /* 阻塞等待接收信号量,等到信号量后再次读取数据 */
            rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
        }
        /* 读取到的数据通过串口错位输出 */
        ch = ch + 1;
        rt_device_write(serial, 0, &ch, 1);
    }
}

static int uart_test(int argc, char *argv[])
{
    rt_err_t ret = RT_EOK;
    char uart_name[RT_NAME_MAX];
    char str[] = "hello RT-Thread!\r\n";

    if (argc == 2)
    {
        rt_strncpy(uart_name, argv[1], RT_NAME_MAX);
    }
    else
    {
        rt_strncpy(uart_name, TEST_UART_NAME, RT_NAME_MAX);
    }

    /* 查找系统中的串口设备 */
    serial = rt_device_find(uart_name);
    if (!serial)
    {
        rt_kprintf("find %s failed!\n", uart_name);
        return RT_ERROR;
    }

    /* 初始化信号量 */
    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
    /* 以中断接收及轮询发送模式打开串口设备 */
    rt_device_open(serial, RT_DEVICE_FLAG_INT_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;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(uart_test, uart device test);


【测试】

编译后下载到开发板,使用USB转TTL工具接入树莓派接口的8、10脚,打开串口助手。

在串口终端中输入uart_test的命令,在串口组手中接收到了hello RT-Thread!

同时向开发板发送字符串,开发板交替字符串后向助手发送,效果如下:
image.png

以上是中断接收的例子,下面使用dma进行接收,使用阻塞式进行发送。

1、打开env工具,打开UART配置,使能DMA接收。

image.png

然后退出设置,重新生成mkd5工程。

2、修改原来的uart_tes.c函数。

代码如下:

/*
 * 程序清单:这是一个串口设备 开启 DMA 模式后使用例程
 * 例程导出了 uart_dma_sample 命令到控制终端
 * 命令调用格式:uart_dma_sample uart1
 * 命令解释:命令第二个参数是要使用的串口设备名称,为空则使用默认的串口设备
 * 程序功能:通过串口输出字符串 "hello RT-Thread!",并通过串口输出接收到的数据,然后打印接收到的数据。
*/

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

#define SAMPLE_UART_NAME       "uart2"      /* 串口设备名称 */

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

/* 接收数据回调函数 */
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[BSP_UART2_RX_BUFSIZE + 1];

    while (1)
    {
        rt_memset(&msg, 0, sizeof(msg));
        /* 从消息队列中读取消息 */
        result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER);
        if (result > 0)
        {
            /* 从串口读取数据 */
            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);
            /* 打印数据 */
            rt_kprintf("%s\n",rx_buffer);
        }
    }
}

static int uart_dma_sample(int argc, char *argv[])
{
    rt_err_t ret = RT_EOK;
    char uart_name[RT_NAME_MAX];
    static char msg_pool[256];
    char str[] = "hello RT-Thread!\r\n";

    if (argc == 2)
    {
        rt_strncpy(uart_name, argv[1], RT_NAME_MAX);
    }
    else
    {
        rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);
    }

    /* 查找串口设备 */
    serial = rt_device_find(uart_name);
    if (!serial)
    {
        rt_kprintf("find %s failed!\n", 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_SERIAL_EVENT_RX_DMADONE | RT_DEVICE_FLAG_TX_BLOCKING);
    /* 设置接收回调函数 */
    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;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(uart_dma_sample, uart device dma sample);

下载到开发板后,打开串口终端,输入命令:

image.png

这样在msh与串口终端中都可以看到有输出了,说明串口配置为dma也是正常的。

更多回帖

发帖
×
20
完善资料,
赚取积分