打印
[应用相关]

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

[复制链接]
623|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-1-21 18:29 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
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);
            }
            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的话,把那行注释掉即可。
————————————————
版权声明:本文为CSDN博主「lg28870983」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lg28870983/article/details/135351372

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2028

主题

15903

帖子

14

粉丝