关于Qt上位机与下位机stm32数据传输的解析问题(一)

        在制作上位机中,我们常常要把单片机上的数据,比如曲线图、电机速度、信号频率幅值等显示在上位机软件中,那么就需要下位机方将数据不断传给上位机以在Qt的QLCDNumber或者Qchart不断刷新,这是上位机对下位机的数据传输。

       另外我们有时候需要在上位机里修改单片机的参数,比如设置当前速度需要将速度设置为100、设置模式时等场景,都需要上位机发送数据至下位机,然后下位机通过解析到的数据调用对应的函数以设置参数。

        那么如何将让数据实现上、下位机间的传输呢,我分享一下上一篇关于电机控制我的做法。

上位机(QT)传输数据至下位机(STM32)

我用的通讯方式是串口通信,stm32用串口连接至电脑后,当点击套用参数时,调用槽函数。在槽函数里将数据发送给stm32,由于还有其他按钮要发送不同的数据,所以我在发送这串数据时,我加了一个报头:PID。

PID:0.3p0.015i0.2d20s

将所要发送的数据整理成这种形式,四个数据分别是 KP、KI、KD、和目标速度。即在调用槽函数时,在槽函数中调用串口类的write函数,将数据打包发给stm32

//套用按钮
void SerialPort::on_setButton_clicked()
{
    QString s = "PID:";
    QString str1 = ui->KPEdit->text();
    float str1f = str1.toFloat();
    QString s1 = QString::number(str1f);
    s.append(s1);

    QString str2 = ui->KIEdit->text();
    float str2f = str2.toFloat();
    QString s2 = QString::number(str2f);
    s.append("p");
    s.append(s2);

    QString str3 = ui->KDEdit->text();
    float str3f = str3.toFloat();
    QString s3 = QString::number(str3f);
    s.append("i");
    s.append(s3);

    QString str4 = ui->setSpeed->text();
    int str4f = str4.toInt();
    QString s4 = QString::number(str4f);
    s.append("d");
    s.append(s4);
    s.append("s");
    s.append("\r\n");

    char *temp=s.toLocal8Bit().data();
    port->write(temp);
    qDebug()<<temp;

    ui->setSpeed->setEnabled(false);
    ui->KPEdit->setEnabled(false);
    ui->KIEdit->setEnabled(false);
    ui->KDEdit->setEnabled(false);
}

通过 QString类下的append和各种类型转换函数将所发数据拼接成一条字符串打包通过串口发送给stm32。然后stm32串口接收到数据触发串口中断来处理数据。

 

#define GetChPos(thisBuf,ch) (int)strchr(thisBuf, ch) - (int)thisBuf

if(USART_ReceiveString[0] == 'P' && USART_ReceiveString[1] == 'I' && USART_ReceiveString[2] == 'D')
{
					//PID:0.2p0.015i0.2d50s
					float p,i,d,s;
					
					int a = GetChPos(USART_ReceiveString,':');
					int b = GetChPos(USART_ReceiveString,'p');
					int c = GetChPos(USART_ReceiveString,'i');
					int e = GetChPos(USART_ReceiveString,'d');	
					int f = GetChPos(USART_ReceiveString,'s');						
					
					// KP
					memcpy(USART_ReceiveString1, USART_ReceiveString1+a+1, sizeof(USART_ReceiveString1)-(a+1));
					memset(USART_ReceiveString1+b-(a+1), 0, sizeof(USART_ReceiveString1)+b-(a+1));
					float dval1;
					dval1 = atof(USART_ReceiveString1);
					printf("%1f\r\n",dval1);
					p=dval1;
					
					// KI
					memcpy(USART_ReceiveString2, USART_ReceiveString2+b+1, sizeof(USART_ReceiveString2)-(b+1));
					memset(USART_ReceiveString2+c-(b+1), 0, sizeof(USART_ReceiveString2)+c-(b+1));
					float dval2;
					dval2 = atof(USART_ReceiveString2);
					printf("%1f\r\n",dval2);
					i=dval2;
					
					// KD
					memcpy(USART_ReceiveString3, USART_ReceiveString3+c+1, sizeof(USART_ReceiveString3)-(c+1));
					memset(USART_ReceiveString3+e-(c+1), 0, sizeof(USART_ReceiveString3)+e-(c+1));
					float dval3;
					dval3 = atof(USART_ReceiveString3);
					printf("%1f\r\n",dval3);
					d=dval3;
								
					// Targetspeed
					memcpy(USART_ReceiveString4, USART_ReceiveString4+e+1, sizeof(USART_ReceiveString4)-(e+1));					
					memset(USART_ReceiveString4+f-(e+1), 0, sizeof(USART_ReceiveString4)+f-(e+1));			
					int dval4;
					dval4 = atoi(USART_ReceiveString4);
					printf("%d\r\n",dval4);
					s=dval4;
					
					pid_set(p,i,d);
					INPUT=s;
}

先确实是以 PID 开始的报头,然后开始接收数据,将数据利用memset和memcpy分隔解析出来,然后传入pid_set这个函数实现pid的调参,这一套流程就实现了上位机改变参数,然后下位机响应调整pid。

下一篇将说明下位机(stm32)传数据给上位机(Qt)的数据解析。如果觉得这篇文章对您有帮助,可以点赞、收藏,有疑问可以私信我,看到都会回。

  • 26
    点赞
  • 102
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值