打印

STM32 _HAL库的,RS485 收发怎么控制? 保证做到不漏一个发送的字节,也不遗漏一个接收的字节。

[复制链接]
2797|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
medety|  楼主 | 2023-10-12 16:31 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
STM32 _HAL库的,RS485 收发怎么控制?
我看很多人做的是延时控制的,感觉不是很合理。

保证做到不漏一个发送的字节,也不遗漏一个接收的字节。

谁能分享一个这种例程?
谢谢

使用特权

评论回复
评论
xiaofei558008 2023-10-13 16:01 回复TA
DMA Idle 中断 RS485 自动切换pin 脚了解一下 
沙发
medety|  楼主 | 2023-10-12 16:40 | 只看该作者
找到一个,这种的,发送后,靠硬等数据发送完的办法,是不是有点浪费时间?

RE_.png (38.1 KB )

RE_.png

使用特权

评论回复
板凳
elife| | 2023-10-12 17:57 | 只看该作者
HAL也有用中断或DMA发送的处理。发送和接收都可以用中断。HAL_UART_Transmit_IT,HAL_UART_Receive_IT。不用等待结束。

使用特权

评论回复
地板
hjl2832| | 2023-10-13 08:26 | 只看该作者
用芯片内部自带的485控制不就好了,STM32标准的UART口都带硬件485控制脚。

使用特权

评论回复
5
zchong| | 2023-10-13 09:00 | 只看该作者
不管用啥库,原理是一样的,就是要等移位寄存器完全移出后控制收发方向为接收状态。用新型号的器件吧,一般有个自动方向控制的硬件管脚。

使用特权

评论回复
6
medety|  楼主 | 2023-10-13 13:52 | 只看该作者
elife 发表于 2023-10-12 17:57
HAL也有用中断或DMA发送的处理。发送和接收都可以用中断。HAL_UART_Transmit_IT,HAL_UART_Receive_IT。不 ...

如果是中断发送的话,是不是在中断判断?
怎么个判断发么?

DMA的话又是如何操作?

使用特权

评论回复
7
medety|  楼主 | 2023-10-13 13:53 | 只看该作者
hjl2832 发表于 2023-10-13 08:26
用芯片内部自带的485控制不就好了,STM32标准的UART口都带硬件485控制脚。

这个老器件不带呢。。。

使用特权

评论回复
8
medety|  楼主 | 2023-10-13 13:54 | 只看该作者
zchong 发表于 2023-10-13 09:00
不管用啥库,原理是一样的,就是要等移位寄存器完全移出后控制收发方向为接收状态。用新型号的器件吧,一般 ...

能给个范例呢,真的不懂呢

使用特权

评论回复
9
elife| | 2023-10-13 14:45 | 只看该作者
开始发送:HAL_UART_Transmit_IT(&huart3,u3SendBuff,length);
中断默认函数:void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
          if(huart==&huart3)
         {
                //添加发送结束处理。               
        }       
}

开启接收:HAL_UART_Receive_IT(&huart3,u3RxBuf,LEN);   
中断默认函数:HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
          if(huart==&huart3)
         {
                //添加接收结束处理。               
        }
}       
最好把这几个函数在HAL库中的代码仔细看一下,就明白了。

使用特权

评论回复
10
luwei8881| | 2023-10-13 15:20 | 只看该作者

使用特权

评论回复
11
xiaofei558008| | 2023-10-13 16:01 | 只看该作者
DMA
Idle 中断
RS485 自动切换pin 脚

了解一下

使用特权

评论回复
12
handlike| | 2023-10-13 16:45 | 只看该作者
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
        if (huart == &huart3)
        {
                USART3_485_RX;
        }
}

使用特权

评论回复
13
一路向北lm| | 2023-10-14 11:29 | 只看该作者
用寄存器更方便

使用特权

评论回复
14
medety|  楼主 | 2023-10-15 18:19 | 只看该作者
elife 发表于 2023-10-13 14:45
开始发送:HAL_UART_Transmit_IT(&huart3,u3SendBuff,length);
中断默认函数:void HAL_UART_TxCpltCallba ...

怎么知道这个回调函数,就是发送完了就会进到这里?

使用特权

评论回复
15
medety|  楼主 | 2023-10-15 18:20 | 只看该作者
handlike 发表于 2023-10-13 16:45
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
        if (huart == &huart3)

哪里有解释说,发送完了,才进到这里来的?

使用特权

评论回复
16
elife| | 2023-10-16 10:06 | 只看该作者
medety 发表于 2023-10-15 18:19
怎么知道这个回调函数,就是发送完了就会进到这里?

一般网上查,或看HAL库的头文件里有什么函数,最好的就是看HAL库里发送的函数源程序,都做了什么,里面会有注册这个回调函数到中断处理。

使用特权

评论回复
17
dalarang| | 2023-10-16 10:11 | 只看该作者
485的话涉及到使能脚的开启和关闭,HAL库提供的方法其实都不是很适合。
我的方式是RS485的发送和接收都采用中断的方式,每个字节的发送和接收都产生中断,自己去维护整个收发序列,这样做到收发不丢字节。

使用特权

评论回复
18
medety|  楼主 | 2023-10-18 21:10 | 只看该作者
dalarang 发表于 2023-10-16 10:11
485的话涉及到使能脚的开启和关闭,HAL库提供的方法其实都不是很适合。
我的方式是RS485的发送和接收都采用 ...

1.  比如发送的长度是N,进入中断的次数凑够了N,就算发完了?通过比较跟N是否相等来决定是否要切换了,对么?
2.  收发序列是啥?不懂哎。

能给的样例学习一下么?

使用特权

评论回复
19
kissdb| | 2023-10-19 09:04 | 只看该作者
感觉你这要求有点难,如果很容易达到的话,很多协议还要crc校验做什么,还要超时重传干啥         

使用特权

评论回复
20
dalarang| | 2023-10-19 16:54 | 只看该作者
本帖最后由 dalarang 于 2023-10-19 16:56 编辑
medety 发表于 2023-10-18 21:10
1.  比如发送的长度是N,进入中断的次数凑够了N,就算发完了?通过比较跟N是否相等来决定是否要切换了, ...

不给代码,只给思路。
预先定义一个结构体,包含要发送数据帧的字节数、已发送的字节数、发送的帧内容。比如说现在要发送20个字节,发送前把数据复制到结构体中,并且设置要发送的字节数为20,已发送的字节数为1,然后开启TXE中断并且开启485使能脚,写入第一个要发送的数据给UART->DR。
这样就会进入串口的TXE中断,在中断里判断结构体中是否还有未发完的数据,是的话继续发下一个。如果中断里判断数据都已经填充入串口缓存,则开启TC中断,待TC中断激活后关闭485使能脚并且关闭中断。这样整个数据帧即可发送完毕。
具体思路就是用状态机的机制,中断内自行判断是否还有数据要发送,维护该结构体的内容。
接收也是类似思路,接收中断只收数据,将数据填充到接收结构体内,数据的校验和处理由主循环来完成。

使用特权

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

本版积分规则

11

主题

69

帖子

0

粉丝