Просмотр исходного кода

[增加]增加串口DMA接收模式使用示例代码

misonyo 6 лет назад
Родитель
Сommit
dc67980f45
4 измененных файлов с 144 добавлено и 15 удалено
  1. 12 12
      README.md
  2. 3 2
      SConscript
  3. 1 1
      i2c_aht10_sample.c
  4. 128 0
      uart_dma_sample.c

+ 12 - 12
README.md

@@ -8,17 +8,18 @@
 
 | 文件             | 说明                            |
 | ---------------- | ------------------------------- |
-| adc_vol_sample.c       | 使用 ADC 设备转换电压数据  |
-| hwtimer_sample.c       | 使用 硬件定时器定时  |
-| i2c_aht10_sample.c       | 使用 i2c 设备获取 aht10 温湿度传感器数据  |
-| iwdg_sample.c       | 看门狗设备使用示例  |
-| led_blink_sample.c       |  使用 pin 设备控制 LED 闪烁  |
-| pin_beep_sample.c        | 使用 pin 设备控制蜂鸣器			|
-| pwm_led_sample.c       | 使用 pwm 设备控制 LED 的亮度  |
-| rtc_sample.c       | 使用 rtc 设备设置年月日时分秒信息  |
-| sd_sample.c       | 块设备 SD 卡使用示例  |
-| spi_w25q_sample.c        | 使用 spi 设备读取 W25Q ID       |
-| uart_sample.c            | 使用 serial 设备收发数据         |
+| adc_vol_sample.c       | 使用 ADC 设备转换电压数据 |
+| hwtimer_sample.c       | 使用 硬件定时器定时 |
+| i2c_aht10_sample.c     | 使用 i2c 设备获取 aht10 温湿度传感器数据 |
+| iwdg_sample.c          | 看门狗设备使用示例 |
+| led_blink_sample.c     |  使用 pin 设备控制 LED 闪烁 |
+| pin_beep_sample.c      | 使用 pin 设备控制蜂鸣器 |
+| pwm_led_sample.c       | 使用 pwm 设备控制 LED 的亮度 |
+| rtc_sample.c           | 使用 rtc 设备设置年月日时分秒信息 |
+| sd_sample.c            | 块设备 SD 卡使用示例  |
+| spi_w25q_sample.c      | 使用 spi 设备读取 W25Q ID |
+| uart_sample.c          | 使用 serial 设备中断接收及轮询发送模式收发数据 |
+| uart_dma_sample.c      | 使用 serial 设备 DMA 接收及轮询发送模式收发数据 |
 
 ### 1.2 许可证
 
@@ -37,7 +38,6 @@ RT-Thread online packages
     miscellaneous packages --->
         samples: kernel and components samples --->
             a peripheral_samples package for rt-thread --->
-
 ```
 
 然后让 RT-Thread 的包管理器自动更新,或者使用 `pkgs --update` 命令更新包到 BSP 中。

+ 3 - 2
SConscript

@@ -4,8 +4,6 @@ src   = []
 cwd   = GetCurrentDir()
 include_path = [cwd]
 
-# add kernel samples.
-
 if GetDepend('PERIPHERAL_SAMPLES_USING_ADC'):
     src += ['adc_vol_sample.c']
 
@@ -36,6 +34,9 @@ if GetDepend('PERIPHERAL_SAMPLES_USING_SD'):
 if GetDepend('PERIPHERAL_SAMPLES_USING_SERIAL'):
     src += Glob('uart_sample.c')
 
+if GetDepend('PERIPHERAL_SAMPLES_USING_SERIAL_DMA'):
+    src += Glob('uart_dma_sample.c')
+
 if GetDepend('PERIPHERAL_SAMPLES_USING_SPI'):
     src += Glob('spi_w25q_sample.c')
 

+ 1 - 1
i2c_aht10_sample.c

@@ -80,7 +80,7 @@ static void read_temp_humi(float *cur_temp, float *cur_humi)
 
     write_reg(i2c_bus, AHT10_GET_DATA, 0);      /* 发送命令 */
     rt_thread_mdelay(400);
-	read_regs(i2c_bus, 6, temp);                /* 获取传感器数据 */
+    read_regs(i2c_bus, 6, temp);                /* 获取传感器数据 */
 
     /* 湿度数据转换 */
     *cur_humi = (temp[1] << 12 | temp[2] << 4 | (temp[3] & 0xf0) >> 4) * 100.0 / (1 << 20);

+ 128 - 0
uart_dma_sample.c

@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-04-16     misonyo      first implementation.
+ */
+/*
+ * 程序清单:这是一个串口设备 DMA 接收使用例程
+ * 例程导出了 uart_dma_sample 命令到控制终端
+ * 命令调用格式:uart_dma_sample uart3
+ * 命令解释:命令第二个参数是要使用的串口设备名称,为空则使用默认的串口设备
+ * 程序功能:通过串口输出字符串"hello RT-Thread!",并通过串口输出接收到的数据,然后打印接收到的数据。
+*/
+
+#include <rtthread.h>
+
+#define SAMPLE_UART_NAME       "uart3"      /* 串口设备名称 */
+
+/* 串口接收消息结构*/
+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[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);
+            /* 打印数据 */
+            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_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;
+}
+/* 导出到 msh 命令列表中 */
+MSH_CMD_EXPORT(uart_dma_sample, uart device dma sample);