This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
我正在将标准 UART 接口转换为 RS485。
下面的流程图中介绍了该计划的流程。 传感器正在等待命令、接收到命令后、传感器会连续发送数据、直至发出停止命令
在传感器和 RS485至 USB 接口中、DE 引脚都连接到收发器的 RE 引脚。 在传感器中、两个引脚连接到芯片 FT232RL 的 CBUS2引脚(该引脚配置为 RXLED)。 在传感器中、两个引脚连接到 TM4C123微控制器的 PORTF.3。
测试中使用的 RS485链路长度为几厘米、传感器和接口都具有120欧姆的端接电阻器。 ISL83485用作收发器。 仅在接口中、A 引脚与560 Ω 上拉 电阻器连接、B 引脚与560 Ω 下拉电阻器连接。
波特率为230400、但在最终配置中将提升至500k 波特
关于固件方面、我进行了两项测试
1) 1)当程序启动时、DE 和 RE*为低电平。 发出命令后,DE 和 RE*在例程 UARTSEND()的开头被驱动为高电平,在该例程的末尾被驱动为低电平。 在该配置中、正确发出 START 命令、但 在传感器传输时接收到垃圾数据。 另一种意外行为是传感器无法正确接收 STOP 命令
2) 2) DE 和 RE*在程序启动时处于低电平。 发出命令后,DE 和 RE*在例程 UARTSEND()的开头被驱动为高电平,然后在例程的末尾不被驱动为低电平。 在该配置中、数据被正确接收
从通信的角度而言、我附加了代码中最相关的部分?
我缺少什么? 从固件的角度来看、驱动 RS485方向控制信号的合适方法是什么?
提前感谢
空 UART1 IntHandler (空) { uint32_t ui32StatusRX; RingBufFlush (&rxRingBuf); // //获取中断状态。 // ui32StatusRX = ROM_UARTIntStatus (UART1_BASE、TRUE); // //清除已发出的中断。 // ROM_UARTIntClear (UART1_BASE、ui32StatusRX); //接收超时中断在 FIFO 中接收到字节但尚未接收到字节时触发 //已足够触发您的 Rx 中断。 这是因为 FIFO 级别选择决定了何时进行 // T_RT) { // FIFO 中有要读取的字节和空间。 while (UARTCharsAvail (UART1_base)&& RingBufFull (&rxRingBuf)== false) { uint32_t ch =(uint8_t) ROM_UARTCharGet (UART1_base); //将一个字节从硬件 FIFO 直接写入到我们的 Rx FIFO 中以供以后处理。 RingBufWriteOne (&rxRingBuf、ch); } } if (((ui32StatusRX 和 UART_INT_RX)== UART_INT_RX) { // //在接收 FIFO 中有字符时循环。 // while (ROM_UARTCharsAvail (UART1_base)&& BufFull (&rxRingBuf)== false) { // //从 UART 读取下一个字符 // uint32_t ch =(uint8_t) ROM_UARTCharGet (UART1_base); RingBufWriteOne (&rxRingBuf、ch); } } 空 UARTSend (const uint8_t * pui8Buffer、uint32_t ui32Count) { GPIO_PORTF_DATA_R |= TX_EN_RS485; while (ui32Count---) { ROM_UARTCharPut (UART1_base、* pui8Buffer++); } GPIO_PORTF_DATA_R &=~ TX_EN_RS485; } void ADXL357_SendAllAccData (void) { 字符串[10]; //从传感器收集数据;变量 sample_in.z 包含传感器数据 sprintf (string、"%+.6F"、sample_in.z); UARTSend ((uint8_t *) string、strlen (string)); UARTSend ("\n",1); } int main (void){ uint8_t ret = false; uint8_t acc_Continuous_scan = 0x00; uint8_t MODULE_Continuous_scan = 0x00; ROM_IntMasterDisable(); ConfigureMicroProcessor(); LEDsTest(); ROM_IntMasterEnable(); GPIO_PORTF_DATA_R &=~ TX_EN_RS485; while (1) { if (RingBufEmpty (&rxRingBuf)=false) { //我们是否收到足够的字节,使其成为消息? if (RingBufUsed (&rxRingBuf)=sizeof (uint8_t[8])) { uint8_t rec[8]; //将字节读入我们收到的消息结构。 RingBufRead (&rxRingBuf、(uint8_t*)&rec、sizeof (receivedMsg)); //附加地址 如果(rec[2]='0'& rec[3]='1') { ADXL357_SendAllAccData(); } } }
我认为您过早切换 RS485收发器。 仅仅因为 ROM_UARTCharPUT()函数已经返回、并不意味着串行传输完成。 使用函数 UARTBusy()确定所有字符的传输时间。
void UARTSend (const uint8_t * pui8Buffer、uint32_t ui32Count) { GPIO_PORTF_DATA_R |= TX_EN_RS485; while (ui32Count---) { ROM_UARTCharPut (UART1_base、* pui8Buffer++); } while (ROM_UARTBusy (UART1_base)) { //在传输完成之前延迟此处 } GPIO_PORTF_DATA_R &=~ TX_EN_RS485; }
感谢您的回复。 现在、传输也与例程 ADXL357_SendAllAccData (void)一起工作。
我面临的唯一问题是、当传感器处于连续模式时、我必须多次发出相关的停止命令。
我已按以下方式修改了代码
1) 1)在中断处理程序开始时、我禁用了 RS485发送器
2) 2)在例程 UARTSend 和 ADXL357_SendAllAccData 中、我使用了指令 ROM_UARTCharsAvail (UART1_base)
3) 3)在 UARTSend()例程结束时 ,我已设置了一个较小的延迟
但是,随着这些变化,停止运输的问题仍然存在
空 UART1 IntHandler (空) { GPIO_PORTF_DATA_R &=~ TX_EN_RS485; uint32_t ui32StatusRX; RingBufFlush (&rxRingBuf); // //获取中断状态。 // ui32StatusRX = ROM_UARTIntStatus (UART1_BASE、TRUE); // //清除已发出的中断。 // ROM_UARTIntClear (UART1_BASE、ui32StatusRX); //接收超时中断在 FIFO 中接收到字节但尚未接收到字节时触发 //已足够触发您的 Rx 中断。 这是因为 FIFO 级别选择决定了何时进行 // T_RT) { // FIFO 中有要读取的字节和空间。 while (UARTCharsAvail (UART1_base)&& RingBufFull (&rxRingBuf)== false) { uint32_t ch =(uint8_t) ROM_UARTCharGet (UART1_base); if (ch='?') { JumpToBootLoader(); } //将一个字节从硬件 FIFO 直接写入到我们的 Rx FIFO 中以供以后处理。 RingBufWriteOne (&rxRingBuf、ch); } } if (((ui32StatusRX 和 UART_INT_RX)== UART_INT_RX) { // //在接收 FIFO 中有字符时循环。 // while (ROM_UARTCharsAvail (UART1_base)&& BufFull (&rxRingBuf)== false) { // //从 UART 读取下一个字符 // uint32_t ch =(uint8_t) ROM_UARTCharGet (UART1_base); RingBufWriteOne (&rxRingBuf、ch); } } 空 UARTSend (const uint8_t * pui8Buffer、uint32_t ui32Count) { if (!ROM_UARTCharsAvail (UART1_BASE)) { GPIO_PORTF_DATA_R |= TX_EN_RS485; while (ui32Count---) { ROM_UARTCharPut (UART1_base、* pui8Buffer++); } } while (ROM_UARTBusy (UART1_base)); GPIO_PORTF_DATA_R &=~ TX_EN_RS485; ROM_SysCtlDelay (200); } void ADXL357_SendAllAccData (void) { 字符串[10]; sprintf (string、"%+.6F"、sample_in.z); if (!ROM_UARTCharsAvail (UART1_BASE)) { UARTSend ((uint8_t *) string、strlen (string)); UARTSend ("\n",1); }