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

[复制链接]
3722|22
 楼主| medety 发表于 2023-10-12 16:31 | 显示全部楼层 |阅读模式
STM32 _HAL库的,RS485 收发怎么控制?
我看很多人做的是延时控制的,感觉不是很合理。

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

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

评论

DMA Idle 中断 RS485 自动切换pin 脚了解一下  发表于 2023-10-13 16:01
 楼主| medety 发表于 2023-10-12 16:40 | 显示全部楼层
找到一个,这种的,发送后,靠硬等数据发送完的办法,是不是有点浪费时间?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
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控制脚。
zchong 发表于 2023-10-13 09:00 | 显示全部楼层
不管用啥库,原理是一样的,就是要等移位寄存器完全移出后控制收发方向为接收状态。用新型号的器件吧,一般有个自动方向控制的硬件管脚。
 楼主| medety 发表于 2023-10-13 13:52 | 显示全部楼层
elife 发表于 2023-10-12 17:57
HAL也有用中断或DMA发送的处理。发送和接收都可以用中断。HAL_UART_Transmit_IT,HAL_UART_Receive_IT。不 ...

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

DMA的话又是如何操作?
 楼主| medety 发表于 2023-10-13 13:53 | 显示全部楼层
hjl2832 发表于 2023-10-13 08:26
用芯片内部自带的485控制不就好了,STM32标准的UART口都带硬件485控制脚。

这个老器件不带呢。。。
 楼主| medety 发表于 2023-10-13 13:54 | 显示全部楼层
zchong 发表于 2023-10-13 09:00
不管用啥库,原理是一样的,就是要等移位寄存器完全移出后控制收发方向为接收状态。用新型号的器件吧,一般 ...

能给个范例呢,真的不懂呢
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库中的代码仔细看一下,就明白了。
luwei8881 发表于 2023-10-13 15:20 | 显示全部楼层
xiaofei558008 发表于 2023-10-13 16:01 | 显示全部楼层
DMA
Idle 中断
RS485 自动切换pin 脚

了解一下
handlike 发表于 2023-10-13 16:45 | 显示全部楼层
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
        if (huart == &huart3)
        {
                USART3_485_RX;
        }
}
一路向北lm 发表于 2023-10-14 11:29 | 显示全部楼层
用寄存器更方便
 楼主| medety 发表于 2023-10-15 18:19 | 显示全部楼层
elife 发表于 2023-10-13 14:45
开始发送:HAL_UART_Transmit_IT(&huart3,u3SendBuff,length);
中断默认函数:void HAL_UART_TxCpltCallba ...

怎么知道这个回调函数,就是发送完了就会进到这里?
 楼主| medety 发表于 2023-10-15 18:20 | 显示全部楼层
handlike 发表于 2023-10-13 16:45
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
        if (huart == &huart3)

哪里有解释说,发送完了,才进到这里来的?
elife 发表于 2023-10-16 10:06 | 显示全部楼层
medety 发表于 2023-10-15 18:19
怎么知道这个回调函数,就是发送完了就会进到这里?

一般网上查,或看HAL库的头文件里有什么函数,最好的就是看HAL库里发送的函数源程序,都做了什么,里面会有注册这个回调函数到中断处理。
dalarang 发表于 2023-10-16 10:11 | 显示全部楼层
485的话涉及到使能脚的开启和关闭,HAL库提供的方法其实都不是很适合。
我的方式是RS485的发送和接收都采用中断的方式,每个字节的发送和接收都产生中断,自己去维护整个收发序列,这样做到收发不丢字节。
 楼主| medety 发表于 2023-10-18 21:10 | 显示全部楼层
dalarang 发表于 2023-10-16 10:11
485的话涉及到使能脚的开启和关闭,HAL库提供的方法其实都不是很适合。
我的方式是RS485的发送和接收都采用 ...

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

能给的样例学习一下么?
kissdb 发表于 2023-10-19 09:04 | 显示全部楼层
感觉你这要求有点难,如果很容易达到的话,很多协议还要crc校验做什么,还要超时重传干啥         
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使能脚并且关闭中断。这样整个数据帧即可发送完毕。
具体思路就是用状态机的机制,中断内自行判断是否还有数据要发送,维护该结构体的内容。
接收也是类似思路,接收中断只收数据,将数据填充到接收结构体内,数据的校验和处理由主循环来完成。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

120

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部