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 接收数据、 通过 UART1发送命令(波特率115200)以及接收响应的问题。 命令 SEND 和来自另一个系统的响应数据是正确的(使用 com 端口分析响应),但在将数据字节接收到阵列时,第一个字节将作为零接收。 一些帮助是非常有利的。 下面是相同的代码。
谢谢
UART1_Send ((uint8_t *) Receiver_Command、5); //发送命令
///----------------------------------------------
DELAY_Milli_Sec (6);//接收接收接收器响应的延迟6ms //等待收集数据和其他器件响应的时间
____________________________________________________________________________________________________________________________________________________________
void delay_Milli_Sec (uint32_t delay_value)
{
uint32_t Timer_Count;
Timer_Count =(120000 * DELAY_VALUE);//以毫秒为单位计算值
ROM_IntEnable (INT_TIMER3A);
ROM_TimerIntEnable (TIMER3_base、TIMER_TINA_TIMEOUT);
ROM_TimerLoadSet (TIMER3_base、INT_TIMER3A、Timer_Count);
ROM_TimerEnable (TIMER3_base、TIMER_A);
while (DelaySet_Flag = 0)
{
//等待延迟
}
DelaySet_FLAG = 0;
ROM_TimerIntDisable (TIMER3_base、TIMER_A);//禁用 Timer3中断
ROM_TimerDisable (TIMER3_base、TIMER_A);//禁用 Timer3
}
____________________________________________________________________________________________________________________________________________________________
无效
UART1_IntHandler (空)
{
Interrupt_Flag =(Interrupt_Flag | uart1_interrupt);//全局变量
Receive_Wait_Flag =(Receive_Wait_Flag | uart1_interrupt);//全局变量>> uart1中断>>接收等待标志置1
静态 uint32_t ui32Status;//局部变量>>中断状态
静态 uint8_t uart1_data;
静态 uint32_t Max_Byte=34;//最初设置为34字节
静态 uint32_t CURRENT_Char = 0;//数组中的第一个数据位置
ui32Status = ROM_UARTIntStatus (UART1_base、true);//获取中断状态。
ROM_UARTIntClear (UART1_base、ui32Status);//清除已发出的中断。
while (ROM_UARTCharsAvail (UART1_base))//循环、此时接收 FIFO 中有字符。
{
uart1_data = ROM_UARTCharGetNonBlocking (UART1_base);//从 UART1读取下一个字符
if (Current_If_If <Max_byte)
{
uart1_data_packet[curry_Char++]= uart1_data;//将每个字节读取到 uart1_data_packet 数组
if ((uart1_data_packet[0]= 0xf0)&&(uart1_data_packet[1]= 0xf0)//检查 Receiver_Command 消息 ID 以设置响应数据的字节计数
{
max_Byte=34;//根据命令消息 ID 更新计数值
if (Current_Char==33)
{
CURRENT_CHAR = 0;//将数组清除为0位置
Receive_Wait_Flag &= 0xFD;
}
}
否则、如果((uart1_data_packet[0]= 0xAA)&&(uart1_data_packet[1]= 0x79))
{
max_Byte=4;//根据命令消息 ID 更新计数值
if (Current_Char==3)
{
CURRENT_CHAR = 0;//将数组清除为0位置
Receive_Wait_Flag &= 0xFD;
}
}
其他
{
CURRENT_CHAR=0;
}
}
}
}
收到命令/字符串后、将其复制到另一个缓冲区、以便在主代码中进行评估。 不要使用中断接收缓冲区。
否则、在您检查缓冲区内容时、您将通过 UART 中断例程覆盖缓冲区内容。 其影响将介于"奇怪"和"严重破坏"之间。
谢谢 Bruno 和 F.m,
我对 ISR 进行了如下修改、即使结果相同。
____________________________________________________________________________________________
无效
UART1_IntHandler (空)
{
Interrupt_Flag =(Interrupt_Flag | uart1_interrupt);//全局变量
静态 uint32_t ui32Status;//局部变量>>中断状态
静态 uint8_t uart1_data;
静态 uint8_t CURRENT_Char = 0;
ui32Status = ROM_UARTIntStatus (UART1_base、true);//获取中断状态。
ROM_UARTIntClear (UART1_base、ui32Status);//清除已发出的中断。
while (ROM_UARTCharsAvail (UART1_base))//循环、此时接收 FIFO 中有字符。
{
uart1_data = ROM_UARTCharGetNonBlocking (UART1_base);//从 UART1读取下一个字符
uart1_data_packet[curry_Char++]= uart1_data;
}
}
____________________________________________________________________________________________
您好!
请告诉我们您是如何配置 UART 中断的。 通常、在 UART 中断中、您必须检查发生的具体中断类型-接收中断或发送中断类型或其他类型中断、并在中断例程中采用相应的路径。
这里还有其他一些没有报告的东西、也没有执行(IMHO)。
[报价]我正在通过 UART1 (波特率115200)发送命令并接收响应。[/报价]
这些命令的外观如何,即它们的长度如何,起始字符和终止字符的外观如何?
在(最后一个) UART 接收处理程序代码中、您无条件地将接收到的字节写入接收缓冲区、并使索引递增。 这不是很好的防御性编码。
[引用用户="KurianThomas"]... 以下代码可解决此问题。
实际上、我认为不是。
[引用 user="KurianThomas"]if (Current_Char = 34)||(Current_Char = 4)
{
CURRENT_CHAR = 0;//数组中的第一个数据位置
}[/报价]
这会将索引重置为第5个字符之后的数组开头(在假定的结束字符之后)、从而有效清理最后接收到的命令。 这是问题的第一个,不是吗?
如果您的命令始终为4字节或34字节、则永远不会以这种方式收到34字节命令。
我看不到您是如何将收到的命令传递给主代码的。 直接处理由异步事件(中断)修改的数据(数组)肯定会失败。
库里安
这可能听起来很累、但请稍等片刻:
完全分隔您的代码:
1) 1)一个部分负责接收来自 UART 端口的任何内容(在生命周期的后期、您将希望它通过任何类型的串行 COMM 层接收任何内容、但这是一个更复杂的情况)。 该部分将接收到的字节存储到循环缓冲区中、并将最后一个填充位置递增。
2) 2)一个不同的段对缓冲区的内容进行解析、并确定是否接收到一些有效的命令或消息。
硬编码解决方案、如"期望固定消息长度"、"期望特定字节序列"、而是在您的协议级别(在解析器内部)实施、而不是在通信级别实施。
保持持久、毫不犹豫地回声!
布鲁诺
[引用用户="Bruno Saraiva"]
这可能听起来很累、但请稍等片刻:
(笑声)
保持持久、毫不犹豫地回声!
[/报价]
您可以在您的老板的雷达下面免费查看代码... ;-)
谢谢、我就是这样。 我有一组定义的通信协议和一个由计时器控制的硬实时系统。
希望您已经注意到在前一个案例中、"Current_Char"是静态的。
请在下面找到工作代码:
//
//
// UART1中断处理程序。
//
//
无效
UART1_IntHandler (空)
{
Interrupt_Flag =(Interrupt_Flag | uart1_interrupt);//全局变量
静态 uint32_t ui32Status;//局部变量>>中断状态
如果((Current_Char == 34)||(Current_Char == 4))
{
CURRENT_CHAR = 0;//数组中的第一个数据位置
}
ui32Status = ROM_UARTIntStatus (UART1_base、true);//获取中断状态。
ROM_UARTIntClear (UART1_base、ui32Status);//清除已发出的中断。
while (ROM_UARTCharsAvail (UART1_base))//循环、此时接收 FIFO 中有字符。
{
uart1_DATA_packet[CURRENT_CHAR++]= ROM_UARTCharGetNonBlocking (UART1_base);//从 UART1读取下一个字符
}
____________________________________________________________________________________________
IF (Interrupt_Flag 和 uart1_interrupt)
{
INTERRUPT_Flag &= 0xFD;//清除 UART1中断标志
///----------------------------------------------
//
//在发送命令后收集接收器响应状态
//
接收器状态响应.Header1 = uart1_DATA_packet[0];
接收器状态响应.Header2 = uart1_data_packet[1];
接收器状态响应代码= uart1_data_packet[2];
接收器状态响应。模拟增益磅= uart1_data_packet[3];
接收器状态响应。模拟增益 HB = uart1_DATA_PACKE[4];
接收器状态响应时间磅= uart1_data_packet[5];
RECEIVER_Status_RESPONSE.TIME_HB = uart1_DATA_PACKE[6];
接收器状态响应状态= uart1_data_packet[7];
接收器状态响应。Angle _X_LB = uart1_DATA_PACKE[8];
RECEIVER_Status_RESPONSE.Angle_X_HB = uart1_DATA_PACKE[9];
接收器状态响应。角度 Y 磅= uart1_data_packet[10];
RECEIVER_Status_RESPONSE.Angle_Y_HB = uart1_DATA_PACKE[11];
RECEIVER_Status_RESPONSE.Quad_A_LB = uart1_DATA_PACKE[12];
接收器状态响应。Quad_A_MidB = uart1_data_packet[13];
接收器状态响应1 = uart1_data_packet[14];
接收器状态响应保留2 = uart1_data_packet[15];
接收器状态响应。Quad_B_LB = uart1_DATA_PACKE[16];
接收器状态响应。Quad_B_MidB = uart1_data_packet[17];
接收器状态响应保留3 = uart1_data_packet[18];
接收器状态响应保留4 = uart1_data_packet[19];
RECEIVER_Status_RESPONSE.Quad_C_LB = uart1_DATA_PACKET[20];
接收器状态响应。Quad_C_MidB = uart1_data_packet[21];
接收器状态响应.Temp_lb = uart1_data_packet[22];
RECEIVER_Status_RESPONSE.Temp_HB = uart1_DATA_PACKE[23];
接收器状态响应。Quad_D_LB = uart1_DATA_PACKE[24];
接收器状态响应。Quad_D_MidB = uart1_DATA_PACKE[25];
接收器状态响应 HV_LB = uart1_DATA_PACKE[26];
接收器状态响应 HV_HB = uart1_DATA_PACKE[27];
接收器状态响应。Switch_1_2_positions = uart1_data_packet[28];
接收器状态响应。Switch_3_4_POSITIONS = uart1_data_packet[29];
接收器状态响应。Switch_5_Position = uart1_data_packet[30];
接收器状态响应校验和= uart1_data_packet[31];
接收器状态响应页脚1 = uart1_data_packet[32];
接收器状态响应页脚2 = uart1_data_packet[33];
}
不知怎么说、我期待的是这样的东西。
[引用 user="KurianThomas">希望您注意到在前一个案例中、"curry_Char"是静态的。 [/报价]
它与索引无关、而与数据(数组)本身有关。 当您处理上一个数据包时,如果新数据包到达,会发生什么情况? 我怀疑这种情况会经常发生、因为另一个错误:
[引用 user="KurianThomas"] if (current_Char == 34)||(...
我将使用以下方法:
但是、如前所述、使用来自主代码和中断代码的相同数据数组将最终在您的脸上熔断。 请使用副本。