我在单片机上写了一个程序,通过sprintf函数向端口发送数据(4个int类型的常量值),sprintf将int数转换为字符串。该字符串由 usart 发送的 ascii 字符的字节组成。
printf("+------- Pakage sending --------+");
sprintf(altitude,"alt: %d", ALT);
/* Send data to USART; */
timerDelayMs(300);
send_Uart_str(altitude);
send_Uart(NEW_LINE);
/* и тд. */
我打开终端并得到以下图片:
NEW_LINE 是 ASCII = 13 中的插入符号;
在 PC 端,我需要将每一行写入单独的缓冲区或变量。在这里我无法理解如何按马车划分。绘制了一个原始控制台应用程序。虽然我正在按事件从端口读取所有内容,但是在控制台中渲染时,同样的问题:
虽然在监视器中调试时,数据正常,没有损坏。实际的端口类:
public class CustomSerialPort : SerialPort
{
public event DataRecievedEventHandler DataChanged;
public delegate void DataRecievedEventHandler(object sender, string package);
public CustomSerialPort(string port)
: base()
{
//base.PortName = COM1;
base.BaudRate = 38400;
base.DataBits = 8;
base.StopBits = StopBits.One;
base.Parity = Parity.None;
base.ReadTimeout = 300;
base.DataReceived += CustomSerialPort_DataReceived; ;
}
public void Open(string portName)
{
if (base.IsOpen)
{
base.Close();
}
base.PortName = portName;
base.Open();
}
private void CustomSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var port = (SerialPort) sender;
try
{
DataChanged?.Invoke(sender, port.ReadExisting());
}
catch (Exception exception)
{
Debug.WriteLine(exception);
}
}
}
主程序:
class Program
{
static void Main(string[] args)
{
var port = new CustomSerialPort("COM3");
port.Open("COM3");
port.DataChanged += Port_DataChanged;
Console.ReadKey();
}
private static void Port_DataChanged(object sender, string package)
{
Console.WriteLine(package);
}
}
可能是什么问题呢?
接收到的数据必须添加到一行 - 缓冲区。
当 CR (NEW_LINE) 出现在缓冲区中时,复制它之前的所有内容并以所需的格式输出。
删除缓冲区的开头,包括 CR
PS
DataChanged?.Invoke(
确保事件处理程序的同步,该处理程序在单独的线程中执行,并且Port_DataChanged
?在这种情况下,奇怪输出的问题与符号有关,该符号
'\r'
也在NEWLINE
所讨论的代码中(顺便说一句,这令人困惑,因为通常换行符毕竟是10
,而不是13
)。当
'\r'
输出到控制台时,这会将光标移动到当前行的开头。因此,在程序输出的某些行中,我们观察到包中的几行重叠,它们看起来很奇怪,像?888d: 1337
.解决问题的步骤是将其替换
Console.WriteLine(package)
为Console.WriteLine(package.Replace("\r", "\n"))
. 更好的是Console.Write(package.Replace("\r", "\n"))
,这样数据包有时会停止在一条线的中间被切割。