Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
DMA
串口
RS485
10
串口三种发送方式下485收发引脚控制,轮询发送,中断发送,DMA发送
发布于 2020-11-06 14:34:24 浏览:2629
订阅该版
基于STM32F429硬件的使用情况, 串口三种发送方式下485收发引脚控制 **轮询发送**,我可以直接在发送前发送后设置收发引脚,但是这样子浪费CPU时间 ``` int uart_write(uint8_t *data,uint16_t length) { if(config->rts_set)config->rts_set(1); rt_device_write(config->dev, 0, data, length); if(config->rts_set)config->rts_set(0); return 0; } ``` **中断发送**,代码和流程跟轮询发送一样的, ``` int uart_write(uint8_t *data,uint16_t length) { if(config->rts_set)config->rts_set(1); rt_device_write(config->dev, 0, data, length); if(config->rts_set)config->rts_set(0); return 0; } ``` 通过写数据触发中断,然后等待rt_completion_wait,这时候写线程被挂起 硬件发送完一个字节后中断触发rt_completion_done释放了写线程,接着发下一个字节,如此反复 但是这里我有一个问题,我并没有看到stm32驱动库中哪个函数去调用 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);中de rt_completion_done(&(tx_fifo->completion));去释放写线程。 检查了void uart_isr(struct rt_serial_device *serial)并没有找到,只有有关DMA的接收完成函数 ``` void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { struct stm32_uart *uart; RT_ASSERT(huart != NULL); uart = (struct stm32_uart *)huart; _dma_tx_complete(&uart->serial); } ``` 后面调用了 rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DMADONE); 这个是中断发送的问题,我现在暂时不敢确定这个到底会不会被调用释放 **DMA发送** 然后是DMA的发送方法比较复杂,我只能开始前切换到发送模式,通过发送完成回调去关闭发送引脚 ``` int uart_write(uint8_t *data,uint16_t length) { if(config->rts_set)config->rts_set(1); rt_device_write(config->dev, 0, data, length); return 0; } //设置发送回调函数 static rt_err_t uart_tx_complete(rt_device_t dev, void *buffer) { if(config->rts_set)config->rts_set(0); } rt_device_set_tx_complete(uart_config->dev, uart_tx_complete); ``` 但是这又一个新的问题,如果rt_data_queue_pop中还有数据,在DMA发送上一帧数据完后执行到rt_hw_serial_isr函数中下面这段时,从rt_data_queue_pop中拿出数据通过serial->ops->dma_transmit发送出去,在下面接着运行了tx_complete函数,我的RS485收发引脚已经被关了,处于接收状态,这个时候DMA中发的数据肯定发送不出去 ``` case RT_SERIAL_EVENT_TX_DMADONE: { const void *data_ptr; rt_size_t data_size; const void *last_data_ptr; struct rt_serial_tx_dma *tx_dma; tx_dma = (struct rt_serial_tx_dma*) serial->serial_tx; rt_data_queue_pop(&(tx_dma->data_queue), &last_data_ptr, &data_size, 0); if (rt_data_queue_peak(&(tx_dma->data_queue), &data_ptr, &data_size) == RT_EOK) { /* transmit next data node */ tx_dma->activated = RT_TRUE; serial->ops->dma_transmit(serial, (rt_uint8_t *)data_ptr, data_size, RT_SERIAL_DMA_TX); } else { tx_dma->activated = RT_FALSE; } /* invoke callback */ if (serial->parent.tx_complete != RT_NULL) { serial->parent.tx_complete(&serial->parent, (void*)last_data_ptr); } break; } ``` 请问大家有什么办法不?
查看更多
3
个回答
默认排序
按发布时间排序
2pw
2020-11-10
这家伙很懒,什么也没写!
使用DMA发送数据到485的正确姿势: 1. 新建一个线程专门管理数据发送 2. 使用发送双缓冲,当然不是必须的 3. 做一个发送数据接口,需要发数据就push到发送线程 4. 发送线程每次有数据前设置OE,串口完成中断自动拉回OE 5. 发送线程在oe被拉回前不能再次发送,因此你需要缓存数据。或者使用上面的双缓冲可以是性能最大化 不管你什么协议都可以这样用。modbus极速收发,一晚上都不会错误一包
Acuity
2020-11-08
这家伙很懒,什么也没写!
1、中断发送不是这样使用的。中断发送是,线程将待发送数据塞入一个ringbuf里面,使能发送中断,然线程不用管,也不会阻塞;cpu会通过中断从ringbuf取数据,一字节一字节往外发数据。不高于115200波特率,建议用中断发送。 2、DMA发送,与中断发送类似,线程将发送数据塞入ringbuf,另一线程(或者中断)从ringbuf取出数据放入DMA发送buf,开启dma发送。高于115200波特率建议用DMA发送。 3、中断发送和DMA发送都可以通过判断ringbuf是否有数据来判断是否发送完成;中断发送,还可以开启“发送完成”中断,在发送完成中断里设置485方向引脚。 参考:[串口DMA收&发](https://acuity.blog.csdn.net/article/details/108367512)
文武斌
2020-11-12
这家伙很懒,什么也没写!
中断发送的问题我修改了代码,实现了中断发送,效果并不理想,发送的时候有时候被高优先级的线程抢占了cpu,下一个字节没有写到寄存器去,发生断帧现象 https://club.rt-thread.org/ask/question/427309.html 所以并不是很看好中断发送,还是用轮询发送或者DMA好一些 而且由于中断优先级和线程优先级的问题,轮询发送时最好关闭调度器 ``` rt_enter_critical(); if(config->rts_set)config->rts_set(1); rt_device_write(config->dev, 0, data, length); if(config->rts_set)config->rts_set(0); rt_exit_critical(); ``` DMA发送还没有测试,因为不好处理收发引脚的问题, **但是接收是用DMA接收并且屏蔽了DMNA半满和全满中断只用IDLE空闲中断**
撰写答案
登录
注册新账号
关注者
3
被浏览
2.6k
关于作者
文武斌
这家伙很懒,什么也没写!
提问
27
回答
74
被采纳
2
关注TA
发私信
相关问题
1
串口DMA发送数据时,数据被覆盖
2
关于串口DMA模式下rt_device_close问题
3
利用stm32f427实现usb转串口,电脑端什么也没有识别到
4
finsh 控制台 适配 RS 485请大神指点????
5
uart_sample.c 中,读串口设备时偏移量pos要设置为-1而不是0?
6
【结贴】at_device软件包中对串口接收数据缺少判断导致数据接收异常
7
串口无法接受数据,但可以发送
8
串口如何有效的清除掉接收缓冲,而不必一个一个的去读取
9
串口接收使用方式问题
10
雅特力FINSH问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
【24嵌入式设计大赛】基于RT-Thread星火一号的智慧家居系统
2
RT-Thread EtherKit开源以太网硬件正式发布
3
如何在master上的BSP中添加配置yml文件
4
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
5
RT-Thread 发布 EtherKit开源以太网硬件!
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
MicroPython
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
15
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
RTT_逍遥
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部