medety 发表于 2023-10-12 16:31

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

STM32 _HAL库的,RS485 收发怎么控制?
我看很多人做的是延时控制的,感觉不是很合理。

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

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

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
不管用啥库,原理是一样的,就是要等移位寄存器完全移出后控制收发方向为接收状态。用新型号的器件吧,一般 ...

能给个范例呢,真的不懂呢{:lol:}

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

{:handshake:}

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使能脚并且关闭中断。这样整个数据帧即可发送完毕。
具体思路就是用状态机的机制,中断内自行判断是否还有数据要发送,维护该结构体的内容。
接收也是类似思路,接收中断只收数据,将数据填充到接收结构体内,数据的校验和处理由主循环来完成。
页: [1] 2
查看完整版本: STM32 _HAL库的,RS485 收发怎么控制? 保证做到不漏一个发送的字节,也不遗漏一个接收的字节。