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

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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应用开发(二)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值