完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
基于STM32F429硬件的使用情况, 串口三种发送方式下485收发引脚控制 int uart_write(uint8_t *data,uint16_t length) int uart_write(uint8_t *data,uint16_t length) void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) DMA发送 int uart_write(uint8_t *data,uint16_t length) 但是这又一个新的问题,如果rt_data_queue_pop中还有数据,在DMA发送上一帧数据完后执行到rt_hw_serial_isr函数中下面这段时,从rt_data_queue_pop中拿出数据通过serial->ops->dma_transmit发送出去,在下面接着运行了tx_complete函数,我的RS485收发引脚已经被关了,处于接收状态,这个时候DMA中发的数据肯定发送不出去
请问大家有什么办法不? |
|
相关推荐
2个回答
|
|
1、中断发送不是这样使用的。中断发送是,线程将待发送数据塞入一个ringbuf里面,使能发送中断,然线程不用管,也不会阻塞;cpu会通过中断从ringbuf取数据,一字节一字节往外发数据。不高于115200波特率,建议用中断发送。
2、DMA发送,与中断发送类似,线程将发送数据塞入ringbuf,另一线程(或者中断)从ringbuf取出数据放入DMA发送buf,开启dma发送。高于115200波特率建议用DMA发送。 3、中断发送和DMA发送都可以通过判断ringbuf是否有数据来判断是否发送完成;中断发送,还可以开启“发送完成”中断,在发送完成中断里设置485方向引脚。 |
|
|
|
但是在实际应用中,我调用了发送函数,调用返回时我是期望数据已经发送出去了,这样我好做接下来的收发引脚切换和接收应答数据,如果发送完成就不知道这个数据的情况了,这样程序就不可控了。
理想状态下我调用写或者发送函数,驱动将数据传到低层, 1.如果是轮询发送就会一直占用cpu去查询发送状态, 2.如果是中断发送就会发送一个数据挂起线程,然后等待发送完成中断触发恢复线程,如此循环将数据全部发送出去之后就恢复线程继续运行下面逻辑(这样可能适合低波特率使用,太频繁的中断和线程切换), 3.如果是DMA发送就会先将数据存在数据队列data_quque,然后再把数据转移到DMA的buff中发送,同样我也希望这个时候能先挂起我的线程,等待发送完再恢复,然后继续运行下面的逻辑 也就是说无论哪种方式,调用的发送函数是一样的,只是低层处理流程不一样,这样我便可以在发送函数之前设置485发,发送完后设置485收。 但是看到这个代码我觉得在中断发送完成的回调函数里面设置485收发可能不可靠 ,我看了rtt串口中现实的中断发送方式就是这样,但是不知道是受dma的代码影响还是怎么回事,中断发送好像跟中断联系不起来 static void uart_isr(struct rt_serial_device *serial) { struct stm32_uart *uart; #ifdef RT_SERIAL_USING_DMA rt_size_t recv_total_index, recv_len; rt_base_t level; #endif RT_ASSERT(serial != RT_NULL); uart = rt_container_of(serial, struct stm32_uart, serial); /* UART in mode Receiver -------------------------------------------------*/ if ((__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_RXNE) != RESET)) { rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } #ifdef RT_SERIAL_USING_DMA else if ((uart->uart_dma_flag) && (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_IDLE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_IDLE) != RESET)) { level = rt_hw_interrupt_disable(); recv_total_index = serial->config.bufsz - __HAL_DMA_GET_COUNTER(&(uart->dma_rx.handle)); recv_len = recv_total_index - uart->dma_rx.last_index; uart->dma_rx.last_index = recv_total_index; rt_hw_interrupt_enable(level); if (recv_len) { rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8)); } __HAL_UART_CLEAR_IDLEFLAG(&uart->handle); } else if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) && (__HAL_UART_GET_IT_SOURCE(&(uart->handle), UART_IT_TC) != RESET)) { if ((serial->parent.open_flag & RT_DEVICE_FLAG_DMA_TX) != 0) { HAL_UART_IRQHandler(&(uart->handle)); } UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TC); } #endif else { if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_ORE) != RESET) { __HAL_UART_CLEAR_OREFLAG(&uart->handle); } if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_NE) != RESET) { __HAL_UART_CLEAR_NEFLAG(&uart->handle); } if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_FE) != RESET) { __HAL_UART_CLEAR_FEFLAG(&uart->handle); } if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_PE) != RESET) { __HAL_UART_CLEAR_PEFLAG(&uart->handle); } #if !defined(SOC_SERIES_STM32L4) && !defined(SOC_SERIES_STM32F7) && !defined(SOC_SERIES_STM32F0) && !defined(SOC_SERIES_STM32L0) && !defined(SOC_SERIES_STM32G0) && !defined(SOC_SERIES_STM32H7) && !defined(SOC_SERIES_STM32G4) && !defined(SOC_SERIES_STM32MP1) && !defined(SOC_SERIES_STM32WB) if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_LBD) != RESET) { UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_LBD); } #endif if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_CTS) != RESET) { UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_CTS); } if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TXE) != RESET) { UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TXE); } if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_TC) != RESET) { UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_TC); } if (__HAL_UART_GET_FLAG(&(uart->handle), UART_FLAG_RXNE) != RESET) { UART_INSTANCE_CLEAR_FUNCTION(&(uart->handle), UART_FLAG_RXNE); } } } #ifdef RT_SERIAL_USING_DMA static void dma_isr(struct rt_serial_device *serial) { struct stm32_uart *uart; rt_size_t recv_total_index, recv_len; rt_base_t level; RT_ASSERT(serial != RT_NULL); uart = rt_container_of(serial, struct stm32_uart, serial); if ((__HAL_DMA_GET_IT_SOURCE(&(uart->dma_rx.handle), DMA_IT_TC) != RESET) || (__HAL_DMA_GET_IT_SOURCE(&(uart->dma_rx.handle), DMA_IT_HT) != RESET)) { level = rt_hw_interrupt_disable(); recv_total_index = serial->config.bufsz - __HAL_DMA_GET_COUNTER(&(uart->dma_rx.handle)); if (recv_total_index == 0) { recv_len = serial->config.bufsz - uart->dma_rx.last_index; } else { recv_len = recv_total_index - uart->dma_rx.last_index; } uart->dma_rx.last_index = recv_total_index; rt_hw_interrupt_enable(level); if (recv_len) { rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8)); } } } #endif |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1004 浏览 0 评论
AI模型部署边缘设备的奇妙之旅:如何在边缘端部署OpenCV
3272 浏览 0 评论
tms320280021 adc采样波形,为什么adc采样频率上来波形就不好了?
1443 浏览 0 评论
2102 浏览 0 评论
1614 浏览 0 评论
75283 浏览 21 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-28 00:45 , Processed in 1.290271 second(s), Total 74, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号