RT-Thread基于AT32单片机的485应用开发(一)

本文详细介绍了如何在AT32单片机上使用RT-Thread进行串口配置,包括移除或注释特定驱动文件,以及对UART1、UART3和UART4的DMA设置。还提供了RS485通信示例和注意事项,以及针对AT32BSP中可能遇到的DMA相关问题的解决方案。
摘要由CSDN通过智能技术生成

1 硬件电路

2 RT-Thread及相关BSP配置

本例采用RT-Thread串口驱动v2,需要从项目中移除drivers/common目录下的drv_usart.h和drv_usart.c,或者将这两个文件中的内容全部注释。否则相关结构定义会产生冲突。

3 driver/board.h中串口配置

#define BSP_USING_UART1
#define BSP_UART1_TX_PIN       "PA9"
#define BSP_UART1_RX_PIN       "PA10"
#define BSP_UART1_RX_USING_DMA
#define BSP_UART1_TX_USING_DMA
#define BSP_UART1_RX_BUFSIZE    256
#define BSP_UART1_TX_BUFSIZE    256

#define BSP_USING_UART3
#define BSP_UART3_TX_PIN       "PB10"
#define BSP_UART3_RX_PIN       "PB11"
#define BSP_UART3_RX_USING_DMA
#define BSP_UART3_TX_USING_DMA
#define BSP_UART3_RX_BUFSIZE    256
#define BSP_UART3_TX_BUFSIZE    256

#define BSP_USING_UART4
#define BSP_UART4_TX_PIN       "PC10"
#define BSP_UART4_RX_PIN       "PC11"
#define BSP_UART4_RX_USING_DMA
#define BSP_UART4_TX_USING_DMA
#define BSP_UART4_RX_BUFSIZE    256
#define BSP_UART4_TX_BUFSIZE    256

4 RS485测试程序

uart收到一帧数据后,返回发送方,需注意RS485控制引脚切换时间。全部代码如下。

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

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

/* 串口设备句柄 */
static rt_device_t serial;

/* 485控制引脚 */
rt_base_t rs485_ctrl_pin = -1;

static void serial_thread_entry(void *parameter)
{
    rt_uint32_t rx_length, ret;
    static char rx_buffer[256];

    rx_length = 0;
    while (1)
    {
        ret = rt_device_read(serial, rx_length, rx_buffer, 256-rx_length);
        if(ret==0 && rx_length>0){
            rt_pin_write(rs485_ctrl_pin,1);
            rt_thread_mdelay(2);
            rt_device_write(serial, 0, rx_buffer, rx_length);
            rt_thread_mdelay(5);
            rt_pin_write(rs485_ctrl_pin,0);
            /* 打印数据 */
            for(int i=0;i<rx_length;i++){
                rt_kprintf("%02x ",rx_buffer[i]);
            }
            rt_kprintf("\n");
            rx_length = 0;
        }else{
            rx_length += ret;
        }
        rt_thread_mdelay(5);
    }
}

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);
    }
    rt_kprintf("uart_name = %s\n",uart_name);
    if(rt_strcmp(uart_name,"uart3")==0){
        rs485_ctrl_pin = rt_pin_get("PE.15");
        rt_pin_mode(rs485_ctrl_pin, PIN_MODE_OUTPUT);
        rt_pin_write(rs485_ctrl_pin,0 );
    }else if(rt_strcmp(uart_name,"uart4")==0){
        rs485_ctrl_pin = rt_pin_get("PA.15");
        rt_pin_mode(rs485_ctrl_pin, PIN_MODE_OUTPUT);
        rt_pin_write(rs485_ctrl_pin,0);
    }else{
        return RT_ERROR;
    }

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


    /* 以 DMA 接收及轮询发送方式打开串口设备 */
    rt_device_open(serial, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);

    /* 发送字符串 */
    rt_pin_write(rs485_ctrl_pin,1);
    rt_device_write(serial, 0, str, (sizeof(str) - 1));
    rt_pin_write(rs485_ctrl_pin,0);

    /* 创建 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);

终端中输入 uart_dma_sample uart4执行示例程序。测试结果

5 避坑

PA15缺省配置为JTAG引脚,AT32的BSP中并为对该引脚进行配置,这里增加相关代码。drivers/board.c中作如下修改

rt_weak void rt_hw_board_init()
{
    extern void hw_board_init(char *clock_src, int32_t clock_src_freq, int32_t clock_target_freq);

    /* jtag-dp disabled and sw-dp enabled */
    crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
    gpio_pin_remap_config(SWJTAG_GMUX_010, TRUE);

    /* Heap initialization */
#if defined(RT_USING_HEAP)
    rt_system_heap_init((void *) HEAP_BEGIN, (void *) HEAP_END);
#endif

    hw_board_init(BSP_CLOCK_SOURCE, BSP_CLOCK_SOURCE_FREQ_MHZ, BSP_CLOCK_SYSTEM_FREQ_MHZ);

    /* Set the shell console output device */
#if defined(RT_USING_DEVICE) && defined(RT_USING_CONSOLE)
    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif

    /* Board underlying hardware initialization */
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif

}

另外,AT32BSP中如果串口驱动不用DMA,会有一个编译错误,BSP调用了一个DMA函数,如果没有配置DMA的话,把那行注释掉即可。

改进版本见

RT-Thread基于AT32单片机的485应用开发(二)

《CSDN RT-Thread应用开发实战-基于STM32智能小车》是一本针对使用RT-Thread操作系统进行STM32智能小车开发的实践教程。本书的目的是帮助读者了解RT-Thread应用开发流程以及如何借助该操作系统开发智能小车。 首先,本书介绍了RT-Thread的基本概念和原理,在此基础上详细讲解了如何在STM32上搭建RT-Thread开发环境。读者将学到如何下载、安装以及配置RT-Thread的开发工具链和库文件。 接下来,本书逐步引导读者完成基于STM32智能小车的应用开发。其中,读者将学习到如何通过GPIO控制智能小车的驱动器,如何使用PWM控制电机的转速,以及如何通过UART与传感器进行通信。 本书还特别强调了实战与实验的重要性。通过一系列的实例,读者将学习到如何使用RT-Thread进行任务管理、内存管理和外设驱动。同时,本书也提供了丰富的实验代码和实验指导,读者可以亲自动手实践,加深理解。 最后,本书还介绍了一些智能小车应用的扩展方向。例如,读者可以学习到如何通过使用传感器实现自动避障功能,如何利用无线通信模块进行远程控制等。 通过阅读《CSDN RT-Thread应用开发实战-基于STM32智能小车》,读者可以系统地学习到RT-Thread操作系统的开发流程和应用方法,了解如何使用STM32开发智能小车,并且能够自己进行实践、实验和创新。对于对嵌入式开发和智能小车有兴趣的读者来说,这本书是一本非常实用的指南。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值