完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
最近在对h750板子上的485串口进行收发功能测试的时候,遇到的一个问题,特地记录一下。
由于对板子上的485引脚做了特殊处理,在通过Tx引脚发送报文的时候,Rx也会收到Tx发送出去的报文,触发接收中断,所以我的报文发送逻辑是:发送N个字节时,只主动发送第一个字节,然后在接收中断中判断接收到的字节和我发送的字节是否一致,如果一致则继续发送下一个字节,不一致则发送失败,退出发送。 一开始使用的是野火的485例程,使用hal库的接口进行字节的收发和接收中断处理 中断使能 /* 配置抢占优先级的分组 */ HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0); /*中断设置,抢占优先级0,子优先级为0*/ HAL_NVIC_SetPriority(USART6_IRQn, 0,0); HAL_NVIC_EnableIRQ(USART6_IRQn); /*配置串口接收中断 */ __HAL_UART_ENABLE_IT(&Uart6_Handle,UART_IT_RXNE); __HAL_UART_ENABLE_IT(&Uart6_Handle,USART_IT_ERR); __HAL_UART_ENABLE_IT(&Uart6_Handle,UART_IT_PE); 发送 if(BSP_RS485_TxState != RS485_TX_ING) { BSP_RS485_BusFreeCount = 0; Enter_485Tx(); p = RS485_Tx_Buf; for(i=0; i pTx = RS485_Tx_Buf; TxLen = DatLen; Tx_Last = *pTx++; HAL_UART_Transmit(&Uart6_Handle, (uint8_t *)&Tx_Last, 1, 10); return TRUE; } 接收中断 if(__HAL_UART_GET_IT(&Uart6_Handle,USART_IT_ORE)!=RESET) { __HAL_UART_CLEAR_OREFLAG(&Uart6_Handle); } if((__HAL_UART_GET_FLAG(&Uart6_Handle,UART_FLAG_RXNE)!=RESET)) { HAL_UART_Receive(&Uart6_Handle, (uint8_t *)(&temp),1, 1000); BSP_RS485_BusFreeCount = 0; USART_RX_vect(temp); } else if(__HAL_UART_GET_FLAG(&Uart6_Handle,USART_IT_TC)!=RESET) { __HAL_UART_CLEAR_IT( &Uart6_Handle, USART_IT_TC ); } else { HAL_UART_Receive(&Uart6_Handle, (uint8_t *)(&temp),1, 1000); } __HAL_UART_CLEAR_OREFLAG(&Uart6_Handle); if(__HAL_UART_GET_FLAG(&Uart6_Handle, USART_FLAG_NE) != RESET) { __HAL_UART_CLEAR_NEFLAG(&Uart6_Handle); } if(__HAL_UART_GET_FLAG(&Uart6_Handle, USART_FLAG_FE) != RESET) { __HAL_UART_CLEAR_FEFLAG(&Uart6_Handle); } if(__HAL_UART_GET_FLAG(&Uart6_Handle, USART_FLAG_PE) != RESET) { __HAL_UART_CLEAR_PEFLAG(&Uart6_Handle); } 接收中断中发送处理 if(c != Tx_Last) { //发送的同接收的不一致,退出发送 _485_RX_EN(); BSP_RS485_TxState = RS485_TX_FAIL; } else { //发送下一个 if(--TxLen>0) { Tx_Last = *pTx; ch=*pTx++; RS485_UART->TDR=ch; } else { Enter_485Rx(); BSP_RS485_TxState = RS485_TX_SUCCESS; } } 在实际使用过程中,发现虽然也能正常的进行收发,但是时不时会在接收中断的发送处理函数出现问题,经常出现发送的字节和接收中断收到的字节不一致的问题,导致报文发送失败,并且一旦出现这种情况,接收中断就会失效,再也无法触发。后来想的办法是在发生错误时重新初始化串口,这样又能继续收发了,但是这种方式治标不治本,还是无法解决报文频繁发送失败的问题。 if(c != Tx_Last) { //发送的同接收的不一致,退出发送 BSP_RS485_Init(19200); BSP_RS485_TxState = RS485_TX_FAIL; } 最后,参考了安富莱的485例程,不调用hal库接口,而是直接对寄存器进行操作。 中断使能 SET_BIT(RS485_UART->ICR, USART_ICR_TCCF); /* 清除TC发送完成标志 */ SET_BIT(RS485_UART->RQR, USART_RQR_RXFRQ); /* 清除RXNE接收标志 */ SET_BIT(RS485_UART->CR1, USART_CR1_RXNEIE); /* 使能PE. RX接受中断 */ 发送接收 RS485_UART->TDR=Tx_Last;//发送 temp = READ_REG(RS485_UART->RDR);//接收 接收中断 volatile UNS8 temp; uint32_t isrflags = READ_REG(RS485_UART->ISR); uint32_t cr1its = READ_REG(RS485_UART->CR1); uint32_t cr3its = READ_REG(RS485_UART->CR3); /* 处理接收中断 */ if ((isrflags & USART_ISR_RXNE_RXFNE) != RESET) { temp = READ_REG(RS485_UART->RDR); BSP_RS485_BusFreeCount = 0; USART_RX_vect(temp); } if ( ((isrflags & USART_ISR_TXE_TXFNF) != RESET) && (cr1its & USART_CR1_TXEIE) != RESET) { CLEAR_BIT(RS485_UART->CR1, USART_CR1_TXEIE); } if (((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) { CLEAR_BIT(RS485_UART->CR1, USART_CR1_TCIE); } /* 清除中断标志 */ SET_BIT(RS485_UART->ICR, UART_CLEAR_PEF); SET_BIT(RS485_UART->ICR, UART_CLEAR_FEF); SET_BIT(RS485_UART->ICR, UART_CLEAR_NEF); SET_BIT(RS485_UART->ICR, UART_CLEAR_OREF); SET_BIT(RS485_UART->ICR, UART_CLEAR_IDLEF); SET_BIT(RS485_UART->ICR, UART_CLEAR_TCF); SET_BIT(RS485_UART->ICR, UART_CLEAR_LBDF); SET_BIT(RS485_UART->ICR, UART_CLEAR_CTSF); SET_BIT(RS485_UART->ICR, UART_CLEAR_CMF); SET_BIT(RS485_UART->ICR, UART_CLEAR_WUF); SET_BIT(RS485_UART->ICR, UART_CLEAR_TXFECF); 改成寄存器版后,错误基本不再出现,两个版本的差异在于接收中断中对于中断信号的处理,野火基本只处理了接收中断,其他中断都没怎么处理,一开始直接hal库的HAL_UART_IRQHandler(&Uart6_Handle);接口让其自行处理,发现没啥用后我才按照网上其他人的说法多加了几个中断处理。不过仍然无法彻底解决问题。另外就是收发接口的不同,HAL_UART_Receive和HAL_UART_Transmit接口会进行不少操作,不知道会不会出现问题。而安富莱的例程是直接操作寄存器,且对中断信号做了不少处理。 至于到底是和原因导致的错误,时间有限,没空去进行验证了,反正先用第二种方法进行485的收发完成项目再说。 |
|
|
|
|
只有小组成员才能发言,加入小组>>
1599 浏览 0 评论
imx6ull 和 lan8742 工作起来不正常, ping 老是丢包
4738 浏览 0 评论
4229 浏览 9 评论
3822 浏览 16 评论
4398 浏览 1 评论
4210浏览 3评论
2379浏览 0评论
3393浏览 0评论
1158浏览 0评论
2843浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-1 21:55 , Processed in 0.908379 second(s), Total 76, Slave 56 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
2591