-
2021-03-05 21:12:01
Java使用javax.comm库接收串口数据,使用单独的线程,实时处理接收数据
1.[代码][Java]代码
import java.io.*;
import java.util.*;
import javax.comm.*;
public class SerialBean implements Runnable,SerialPortEventListener
{
String PortName;
int baud;
CommPortIdentifier portId;
SerialPort serialPort;
static OutputStream out;
static InputStream in;
String Buf=null;// 缓存一条最新信息
boolean hasData=false;// 标志有无新数据
StringBuilder buf=new StringBuilder(128);
Thread readThread;
public SerialBean(int PortID,int baud)
{
PortName="COM"+PortID;
this.baud=baud;
}
public int Initialize()
{
int InitSuccess=1;
int InitFail=-1;
try
{
portId=CommPortIdentifier.getPortIdentifier(PortName);
try
{
serialPort=(SerialPort)portId.open("Serial_Communication",2000);
serialPort.setSerialPortParams(this.baud,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
}
catch(PortInUseException e)
{
return InitFail;
}
catch(TooManyListenersException e)
{
return InitFail;
}
catch(UnsupportedCommOperationException e)
{
return InitFail;
}
try
{
in=serialPort.getInputStream();
out=serialPort.getOutputStream();
}
catch(IOException e)
{
return InitFail;
}
}
catch(NoSuchPortException e)
{
return InitFail;
}
readThread=new Thread(this);
readThread.start();
return InitSuccess;
}
public boolean hasData()
{
return hasData;
}
public String ReadPort()
{
if(hasData)
{
this.hasData=false;
return this.Buf;
}
else
return null;
}
@SuppressWarnings("deprecation")
public void ClosePort()
{
if(readThread!=null)
readThread.stop();
if(serialPort!=null)
serialPort.close();
}
@Override
public void serialEvent(SerialPortEvent event)
{
/**
* 事件类型:
*
* BI -通讯中断. CD -载波检测. CTS -清除发送. DATA_AVAILABLE -有数据到达.
* DSR-数据设备准备好. FE -帧错误. OE -溢位错误. OUTPUT_BUFFER_EMPTY
* -输出缓冲区已清空. PE -奇偶校验错. RI - 振铃指示.
*/
switch(event.getEventType())
{
case SerialPortEvent.BI:
case SerialPortEvent.OE:
case SerialPortEvent.FE:
case SerialPortEvent.PE:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
try
{
char b;
while(in.available()>0)
{
b=(char)in.read();
buf.append(b);
}
int beg=0,end=0;
for(int i=0;;i++)
{
if(buf.length()<2)
{
return;
}
if(buf.charAt(0)=='\r'&&buf.charAt(1)=='\n')// 以回车换行开头
{
beg=2;
}
else
// 不以换行开头
{
beg=0;
}
end=buf.indexOf("\r\n",beg);
if(end==-1)// 未接受完一整条信息
break;
Buf=buf.substring(beg,end);// 截取数据
buf.delete(0,end+2);// 删除已用数据
System.out.printf("--%s--\n",Buf);
this.hasData=true;
}
// System.out.println(con);
}
catch(IOException e)
{
}
break;
}
}
public void run()
{
try
{
Thread.sleep(2000);
}
catch(InterruptedException e)
{
}
}
}
更多相关内容 -
UART串口数据接收器课程设计报告.doc
2021-09-28 19:13:18UART串口数据接收器课程设计报告.doc -
UART串口数据接收器课程设计汇本报告.doc
2021-10-10 20:58:28UART串口数据接收器课程设计汇本报告.doc -
串口数据收发器
2020-07-17 22:14:12串口数据收发器 -
netty接收串口数据代码,测试串口工具
2022-05-30 17:47:24java netty接收串口数据 开启windows串口工具 发送串口数据调试助手 -
QT串口,重点解决了串口接收数据分包或者不完整的问题
2019-08-14 10:53:59QT开发的串口代码,解决了串口接收数据分包或者不完整的问题 -
串口接收打印软件sscom
2020-11-11 18:58:39串口接收打印软件,设置对应波特率即可接收数据。 -
基于Linux平台的串口数据接收程序
2019-01-17 10:35:25基于Linux平台的串口数据接收源程序,可以直接在Linxu平台下进行功能测试。 -
Labview串口接收数据
2020-07-07 16:59:48用NI Labview实现串口接收数据,可供大家参考,可以作为子程序来开发。本程序有数据接收和数据处理两部分构成,PC通过RS232接收下位机的数据通过校验和检验后和软件滤波后,最终显示。 -
C#串口收发数据,很简单!
2021-07-06 16:51:54实现串口收发,详细注释,通俗易懂,,看了代码就发现,就这?就这么简单?是的!不会亏! -
STM32-串口超时判断方式接收未知长度数据
2020-07-25 19:29:01本文给大家介绍了STM32-串口超时判断方式接收未知长度数据。 -
c#双路串口数据接收
2018-05-17 12:57:27用c#语言serialport控件编写的双路串口数据发送接收软件exe -
串口数据采集并自动写入MySQL数据软件
2017-03-10 08:25:42“串口数据采集入MySQL数据库”软件是传感器网络记录数据的一般工具。最主要核心功能是把串口上接收到的数据,以字符串数据形式直接写入MySQL数据库中的数据表的某一个字符型字段中。当计算机的某个COM口有字符串... -
C#编写的串口数据接收保存
2014-12-08 15:19:50本压缩文件是一个完整的C#编写的串口采集软件,可以实时接收串口数据并显示在文本框内,以Excel表格的形式实时记录储存数据,含有全部代码和界面设计等,也可直接使用.本人采用的是vs2010,若有下载后不能使用的请给我... -
串口数据实时处理:定时器+串口 判断串口数据接收完成
2020-03-31 10:58:29之前在做项目的时候,串口接收的数据要及时进行处理,虽然采用了自定义的串口协议,但是协议的包尾只有一个字节,经常判断不准数据是否接受完毕,所以就采用计时器+串口的方式来判定串口是否接受完成。 核心思想 ...使用背景:
之前在做项目的时候,串口接收的数据要及时进行处理,虽然采用了自定义的串口协议,但是协议的包尾只有一个字节,经常判断不准数据是否接受完毕,所以就采用计时器+串口的方式来判定串口是否接受完成。
核心思想
根据波特率来计算接收一个字节所需要的时间,当超过这个时间没有收到数据,则表明这一帧数据已经接受完毕
实现方法
串口中断函数接收第一个字节之后,开启定时器计数。接受下一个字节的时候清空定时器计数。如此,当没有数据接收后,计时器无法清零,当计时器计数超过设定的数值之后,触发定时器溢出中断,此时数据即接收完毕
下面是代码:
- 1、为了方便,定义一个结构体,主要内容如下所示:
typedef struct _UART_FLAG_STRUCT { uint8_t UART1Flag;//数据接受完成标志 uint8_t UART1String[160];//最大长度,自定义 uint8_t UART1Counter;//收到的数据长度,计数作用 uint8_t usart1_start;//接收开始,定时器计时启动 uint8_t usart1_counter;//定时器计时次数 } UartFlagSt; UartFlagSt UartFlagStC;
- 串口配置:
/************************************************ | 关键词 |USARTInit(u32 band) | - - - - - - - - - - - - - - - - - - - - - - - - | 入参 |u32 band,配置波特率 - - - - - - - - - - - - - - - - - - - - - - - - | 返回值 |None - - - - - - - - - - - - - - - - - - - - - - - - | 功能 |初始化串口1,使能中断 **************************************************/ void USARTInit(u32 band) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin =GPIO_Pin_9;//send GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//receive GPIO_Init(GPIOA,&GPIO_InitStructure); USART_InitStructure.USART_BaudRate = band; USART_InitStructure.USART_HardwareFlowControl = 0; USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_StopBits =USART_StopBits_1; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_Init(USART1,&USART_InitStructure); //初始化串口1 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启串口接受中断 USART_Cmd(USART1,ENABLE); //使能串口1 } /************************************************ | 关键词 |UART1_SendString(uint8_t* str,uint8_t counter) | - - - - - - - - - - - - - - - - - - - - - - - - | 入参 |uint8_t* str 发送的数据 | |uint8_t counter 发送数据的长度 - - - - - - - - - - - - - - - - - - - - - - - - | 返回值 |无 - - - - - - - - - - - - - - - - - - - - - - - - | 功能 |串口1发送函数 **************************************************/ void UART1_SendString(uint8_t* str,uint8_t counter) { for(int i = 0;i<counter;i++) { USART_SendData(USART1,*str); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); str++; } }
- 定时器配置:
/************************************************ | 关键词 |TIM2_Init(u16 arr,u16 psc) | - - - - - - - - - - - - - - - - - - - - - - - - | 入参 |u16 arr 周期,u16 psc 预分频 | - - - - - - - - - - - - - - - - - - - - - - - - | 返回值 |无 | - - - - - - - - - - - - - - - - - - - - - - - - | 功能 |定时器初始化 **************************************************/ void TIM2_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period = arr; // 周期 72-1 max TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM2, ENABLE); }
- 串口中断函数:
/************************************************ | 关键词 |USART1_IRQHandler | - - - - - - - - - - - - - - - - - - - - - - - - | 入参 |None - - - - - - - - - - - - - - - - - - - - - - - - | 返回值 |None - - - - - - - - - - - - - - - - - - - - - - - - | 功能 |1、消除错误; | |2、将数据接受至结构体中的数, | |并启动UartFlagStC.usart1_start = 1;UartFlagStC | |.usart1_counter = 0;定时/刷新功能。 **************************************************/ void USART1_IRQHandler(void) { /*****此段注释代码为消除各种串口错误,在串口环境很差的情况下可以直接将此段代码取消注释,基本可以保证串口代码正常工作****** if((USART_GetITStatus(USART1,USART_IT_ORE) == SET)||(USART_GetFlagStatus(USART1,USART_FLAG_ORE) == SET)) { USART_ReceiveData(USART1); USART_ClearITPendingBit(USART1,USART_IT_ORE); USART_ClearFlag(USART1,USART_IT_ORE); } if((USART_GetITStatus(USART1,USART_IT_NE) == SET)||USART_GetFlagStatus(USART1, USART_FLAG_NE) != RESET) { USART_ClearITPendingBit(USART1,USART_IT_NE); USART_ClearFlag(USART1, USART_FLAG_NE); } if((USART_GetITStatus(USART1,USART_IT_FE) == SET)||USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET) { USART_ClearITPendingBit(USART1,USART_IT_FE); USART_ClearFlag(USART1, USART_FLAG_FE); } if((USART_GetITStatus(USART1,USART_IT_PE) == SET)||USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET) { USART_ClearITPendingBit(USART1,USART_IT_PE); USART_ClearFlag(USART1, USART_FLAG_PE); } ****************************************************************************************************/ if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { if(UartFlagStC.UART1Counter<160)//设定的数组最大为160,要小于这个数,防止溢出 { UartFlagStC.UART1String[UartFlagStC.UART1Counter] = USART_ReceiveData(USART1);//将数据存到数组里面 UartFlagStC.UART1Counter++;//收到的数据个数+1 UartFlagStC.usart1_start = 1;//定时器开始工作 UartFlagStC.usart1_counter = 0;//清空定时器计数 }else UartFlagStC.UART1Counter = 0;//如果接受的数据超过设定值,则清空接收值,防止数据溢出 USART_ClearITPendingBit(USART1,USART_IT_RXNE); } }
可以看到,当有数据进来的时候,
UartFlagStC.UART1Counter
不断自增,数据将会依次存入UartFlagStC.UART1String[]
数组中。
同时,UartFlagStC.usart1_start
计时器开始计数标志位置一(让在定时器中断函数里面自增的UartFlagStC.usart1_counter
得以正常增加),同时也将UartFlagStC.usart1_counter
清零,以表示有数据接收,防止超过设定值,使得UartFlagStC.UART1Flag
置一,错误的提示数据提前接收完成。- 定时器中断函数:
在下面代码提示插入任务的地方插入我们想执行的任务/代码,即可正常使用
/************************************************ | 关键词 |TIM2_IRQHandler | - - - - - - - - - - - - - - - - - - - - - - - - | 入参 |无 | - - - - - - - - - - - - - - - - - - - - - - - - | 返回值 |无 | - - - - - - - - - - - - - - - - - - - - - - - - | 功能 |定时器中断函数 **************************************************/ void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); /**********************/ 在此处插入执行的任务。 /**********************/ } }
- 关键代码:
这个代码是我们任务重最重要的部分,主要实现了我们上述流程图的计时/完成任务,之所以将这部分功能单独拆解写成一个函数的形式,主要是为了移植方便,并且在定时器多任务的时候让定时器中断函数看起来更整洁一点。
使用方法:将此函数插入定时器中断函数。
/************************************************ | 关键词 |USART1InsetTimer | - - - - - - - - - - - - - - - - - - - - - - - - | 入参 |None - - - - - - - - - - - - - - - - - - - - - - - - | 返回值 |无 - - - - - - - - - - - - - - - - - - - - - - - - | 功能 |嵌入定时器中断函数中,串口数据接收完毕后 | |立刻执行,适用于延时性小、数据量密的场景。 **************************************************/ void USART1InsetTimer(void) { if(UartFlagStC.usart1_start == 1)//此标志位是在串口接收数据时候会置1 { UartFlagStC.usart1_counter++;//定时器计数标志位 if(UartFlagStC.usart1_counter >USART_COUNTER_9600)//如果超过波特率为9600时一个字节的所需要的时间,时间计算方法下面有讲解 { UartFlagStC.UART1Flag = 1;//接收完成标志位置1 UartFlagStC.usart1_counter = 0;//计数值清零 UartFlagStC.usart1_start = 0;//计数器启动标志位置0 } } }
在这里,当
(UartFlagStC.usart1_start
置一后,UartFlagStC.usart1_counter
会不断自增(串口中断中会清零此计数位),而一旦超过设定值USART_COUNTER_9600
,就会将接收完成标志位UartFlagStC.UART1Flag
置一,同时清空定时器技术位UartFlagStC.usart1_counter
,并清零计数允许标志位UartFlagStC.usart1_start
。- 处理数据:
如果处理数据很快的话可以直接放在定时器中断函数里面执行,如果还有比较长的延时函数,或者在执行过程中花费时间太久则可以放入主函数循环中进行处理:
老规矩,先进行封装一层:
/************************************************ | 关键词 |USART1Hanndle | - - - - - - - - - - - - - - - - - - - - - - - - | 入参 |None - - - - - - - - - - - - - - - - - - - - - - - - | 返回值 |无 - - - - - - - - - - - - - - - - - - - - - - - - | 功能 |串口1接收数据处理函数,任务若花费时间较长, | |可放置于while()循环中,由定时器确定是否执行。 **************************************************/ void USART1Hanndle(void) { if(!UartFlagStC.UART1Flag) return; /*********执行任务*************/ printf("%s\r\n",UartFlagStC.UART1String); /****************************/ memset(UartFlagStC.UART1String,0,160); UartFlagStC.UART1Counter = 0; UartFlagStC.UART1Flag = 0; }
主函数实现:
/************************************************ | 关键词 |main | - - - - - - - - - - - - - - - - - - - - - - - - | 入参 |None | - - - - - - - - - - - - - - - - - - - - - - - - | 返回值 |无 | - - - - - - - - - - - - - - - - - - - - - - - - | 功能 |主函数入口,配置文件,设置时钟,滴答定时器 | |周期,并开启看门狗 **************************************************/ int main() { SystemInit(); //系统时钟72MHz SysTick_Config(SystemCoreClock/1000); /* SysTick 1 msec interrupts */ TIM2_Init(71,999);//1ms中断一次 USARTInit(9600);//波特率为9600 while(1) { USART1Hanndle(); } }
流程/细节讲解
可能会有人对
void USART1InsetTimer(void)
中的溢出时间USART_COUNTER_9600
有疑问,不知道如何计算,计算方法如下:首先,1个字符串口包含起始位,数据位,校验位,停止位,其中有些位长度可以自己设定,
这里我们按一个字节传输有1+8+1+1共10位长度来计算。
波特率表示的意思是在1sec内可以传输的位数,
接下来就是一元一次方程
设1个字节所用时间为X,波特率为9600,则:
( 1 ∗ 10 ) / X = 9600 / 1000 ( m s ) (1 * 10) / X = 9600 / 1000(ms) (1∗10)/X=9600/1000(ms)
解得X ≈ 1.04167 ms = 2(X为整型,必须向上取整!)X代表的意思是一帧数据传输的时间,意思就是每过X单位时间,即有一个数据接受完毕,同时下一个数据也即将接受。
将USART_COUNTER_9600
的数值设定为X1
UartFlagStC.usart1_counter
则只要在串口中断函数内清空,那么UartFlagStC.usart1_counter
就不会超过X,
那么也就不会将接受完成标志位UartFlagStC.UART1Flag
置1;
一旦没有数据继续接收,那么UartFlagStC.usart1_counter
在中断函数里面将不断自增,直至超过X,此时接受完成标志位UartFlagStC.UART1Flag
将会置1。
同时,时间设定要根据波特率的不同要计算不同的数值。下载地址 :https://download.csdn.net/download/qq_31431301/12287318
实际使用过程中,一定要将
USART_COUNTER_9600
的设定值大于X,因为在此方法中,串口中断函数不仅要判断数据接收标志位,还有清零置一的操作,实际工作时间肯定要大于X!,一般取3~5倍X的时间。 ↩︎
-
串口数据的波形显示软件,串口波形图,C#
2021-09-10 22:04:14串口接收单片机数据,按照波形将数据显示出来 -
QT串口数据发送接收以及UDP发送功能.zip
2019-11-07 21:54:14软件能够实现,串口设置串口号、波特率、奇偶校验位、停止位、流控制,以及发送数据格式转换等问题。同时具备网络传输协议,能够通过网络发送数据,自己若能够进行改进能够实现串口网络数据接口的互联互通。 -
树莓派、linux串口数据接收发送调试软件
2022-01-20 23:13:26树莓派、linux串口数据接收发送调试软件 -
串口数据的波形显示软件_串口波形_串口数据波形显示_串口显示波形_显示波形
2021-09-10 22:04:14串口接收单片机数据,按照波形将数据显示出来 -
QT串口数据接收上位机
2021-07-10 13:37:48QT串口数据接收上位机1.界面设计2.串口配置3.文件读写4.使用QT遇到的一些问题5.上位机程序 1.界面设计 设计的上位机界面如下图所示,包括显示接收数据的文本框和串口的配置区域,以及向采集系统发送开始采集数据和...1.界面设计
设计的上位机界面如下图所示,包括显示接收数据的文本框和串口的配置区域,以及向采集系统发送开始采集数据和停止的Button按钮。
其中,端口和波特率使用的是Input Widgets中的Combo Box
使用时双击,点加号添加元素即可。调用如下函数获取选择的值:ui->comboBox_2->currentIndex()
文本输入框Line Edit获取输入的函数如下:
ui->lineEdit->text()
如果输入的是数字,可以转换为int方便处理
ui->lineEdit->text().toUInt()
文本显示框textBrowser的显示调用如下函数,buff为Qstring类型
ui->textBrowser->setText(buff);
2.串口配置
首先,在.pro文件中加入串口模块,并在头文件中包含串口头文件
QT += serialport
#include <QtSerialPort>
然后,定义一个串口global_port,配置串口的端口号、波特率等参数。还需要将串口接收信号与槽函数进行绑定,在槽函数中对接收到的数据进行处理。最后打开串口:
QSerialPort global_port; //串口 global_port.setPortName("COM1"); global_port.setBaudRate(QSerialPort::Baud9600); global_port.setParity(QSerialPort::NoParity); global_port.setDataBits(QSerialPort::Data8); global_port.setStopBits(QSerialPort::OneStop); connect(&global_port ,SIGNAL(readyRead()) , this ,SLOT(on_readyRead())); global_port.open(QSerialPort::ReadWrite);
串口的读写函数如下,读取时要定义一个QByteArray类型的变量来存储串口接收到的数据。
QByteArray array = global_port.readAll(); //测试发现每次最多读512个 global_port.write(buff,3);
关闭串口的函数:
global_port.close();
3.文件读写
首先包含QT文件操作的头文件:
#include <QFile>
定义一个文件变量,并给定文件的路径(这里我是基于当前时间自己生成一个文件名和路径,方法有点笨但能用0_0):
/*利用当前时间命名文件名*/ QDateTime curDateTime=QDateTime::currentDateTime(); QString times = curDateTime.time().toString(); QString tem; tem = times.left(5); times = times.left(2)+tem.right(2)+times.right(2); //文件名不能有: 将其去掉 f_name = "./DATE/" + times + ".txt"; QFile f(f_name);
然后就对文件流进行读写操作:
if(!f.open(QIODevice::WriteOnly | QIODevice::Append)) { qDebug() << "Open failed."; return -1; } QTextStream txtOutput(&f); txtOutput << buff;
读取文件函数类似读取串口:
QByteArray t = file.readAll();
打开文件的方式:
模式 Value 描述 QIODevice::NotOpen 0x0000 不打开 QIODevice::ReadOnly 0x0001 只读方式 QIODevice::WriteOnly 0x0002 只写方式,如果文件不存在则会自动创建文件 QIODevice::ReadWrite 0x0003 读写方式 QIODevice::Append 0x0004 此模式表明所有数据写入到文件尾 QIODevice::Truncate 0x0008 打开文件之前,此文件被截断,原来文件的所有数据会丢失 QIODevice::Text 0x0010 读的时候,文件结束标志位会被转为’\n’;写的时候,文件结束标志位会被转为本地编码的结束为,例如win32的结束位’\r\n’ QIODevice::UnBuffered 0x0020 不缓存 4.使用QT遇到的一些问题
没有系统的学习过QT这个软件,只是需要用什么功能的时候就找找代码学习一下,所以遇到了些问题,记录一下。
1.构建路径
用别人的project时要修改构建路径,不然会出一些奇怪的问题。
2.ui里添加了块但是ui->不出来
一个原因可能是没保存ui文件,其他原因暂时不知道是怎么回事,我的解决办法是重新打开project或者在添加一个相同的块,这时可能能够ui->出之前那个,但是新添加的还是没有。希望大佬能解答下这个问题。5.excle保存数据
excle有导入数据的功能,可以将规整的数据文件直接导入导表格中
我在数据发送端将数据处理为用逗号隔开的形式并按行发送,上位机接收到数据后便不需要处理直接写入文件中即可。
6.上位机程序
上位机程序下载链接:
-
串口转发工具配合虚拟串口即可实现一串口数据转发到另外几个串口
2019-04-10 13:48:42串口转发工具~~把串口1的数据,实时转发到另外3个串口。。。配合虚拟串口工具,即可实现用软件实现把一个串口的数据转发到另外串口提供给各个软件使用~ -
winform串口数据实时绘图和静态绘图软件
2018-07-11 17:31:24为实验室项目做的小软件,串口通信模式能够接收数据采集卡的数据进行动态显示,U盘数据处理模式能够读取文件进行静态图形显示。 -
接收串口数据工具
2012-03-25 11:58:52一般串口工具接收速度高时容易死掉,这个不会。 需先在超级终端中设置好波特率,然后关掉超级终端,打开ComR可接收 -
serial_带帧头校验_c#串口接收处理_
2021-09-29 05:14:57必须要两个软件同时对方才有效,软件自带帧头 长度 -
Python接收串口数据 程序
2021-05-19 16:20:05这几天在弄的项目需要使用电脑即当下位机也要当上位机,也就是数据需要在电脑上的两个虚拟串口之间进行数据传输,这里推荐一个创建虚拟串口的软件,VSPD,如图: 软件打开之后是这样的,点击添加端口,就可以创建的...这几天在弄的项目需要使用电脑即当下位机也要当上位机,也就是数据需要在电脑上的两个虚拟串口之间进行数据传输,这里推荐一个创建虚拟串口的软件,VSPD,如图:
软件打开之后是这样的,点击添加端口,就可以创建的一对虚拟串口。
有一些串口软件助手是无法检测到虚拟串口的,这样就需要多换几个软件试一试,或者自己编一个串口软件助手,像我在测试的时候,发现现成的串口软件检测不到,用自己编写的C#程序就可进行数据传输。
现在需要编写一个com16接收数据的程序(所有数据都以字符串形式接收):import serial from time import sleep def recv(serial): while True: data = serial.read_all().decode() # str if data == '': continue else: break sleep(0.02) return data if __name__ == '__main__': serial = serial.Serial('COM16', 115200, timeout=0.5) if serial.isOpen(): print("serial open success") else: print("serial open failed") while True: data = recv(serial) print(data) # str
代码如上,可否点个赞支持一下^ ^
-
STM32串口数据接收 --环形缓冲区
2021-02-01 11:35:57STM32串口数据接收 --环形缓冲区 环形缓冲区简介 在单片机中串口通信是我们使用最频繁的,使用串口通信就会用到串口的数据接收与发送,环形缓冲区方式接收数据可以更好的保证数据丢帧率第。 在通信程序中,... -
demo_ZigBee协调器向串口发送数据_
2021-09-30 04:11:33ZigBee网络协调器 串口发送数据,采用光敏传感器采集数据 -
C# 串口收发测试 软件创建串口组件,实现独立线程接收和数据处理。
2022-05-23 15:20:04C# 串口收发测试 软件创建串口组件,实现独立线程接收和数据处理。 -
QT多线程接收串口数据
2021-06-17 22:16:14QT多线程接收串口数据 ** 1.前言 QT多线程的使用,和绝大数人一样,犯了错误(请查阅Qt开发人员( Bradley T. Hughes)Blog中的文章 you are-doing-it-wrong介绍)。为了解决问题,网上查阅学习了几十篇文章,基本都是... -
串口示波器软件,串口助手,8条曲线实时显示串口示波软件
2020-03-22 09:46:56在设备的连接汇总,通过示波器判断设备的连接方式,检测设备的兼容性等都是非常重要的,这款ComDigitalScopeV100串口示波器软件功能丰富,是一款集硬件设备的检测与串口的连接,查看各种示波器的变化数据,...