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
|
|