当前位置:   article > 正文

PC端Qt通过QSerialPort-USB转RS232串口与STC89C52单片机开发板,开发板上数码管显示PC端界面的数字内容_qt怎么和硬件通信

qt怎么和硬件通信


1 前言

  最近有项目需求要做PC端Qt与某嵌入式设备的通信的任务,初步确定需要通过一根USB转RS232串口线与该嵌入式设备连接,在PC端任意输入0~255,这256个十进制数字,在该嵌入式设备上也能显示相应的数字内容。
  本篇博客主要记录一下相关操作的实现过程。

  涉及到带RS232接口的嵌入式设备,我这边用了一个很久之前买的STC89C52单片机开发板做模拟。

  主要思路:
  (1)硬件:PC机,USB转RS232串口线,STC89C52单片机开发板
  (2)软件:PC端通过Qt的serialport模块相关操作,单片机端通过keil uversion5进行51C语言编程、STC-ISP烧写软件实现软件烧写编程;


2 效果

  PC端的Widget界面内有个QlineEdit输入窗口,可以修改输入数据,输入数据为0~255共256个数据,按回车键后,单片机开发版上的Led数码管显示相应的数据内容。

请添加图片描述

3 核心代码

3.1 PC端

3.1.1 USB转RS232串口线

  需要购买一根USB转RS232串口线,下载好相应的串口驱动,通过“计算机”的设备管理器界面的COM端口查看该串口的串口号,可以在此处修改串口号。
  我此处为COM8口,此处有个USB-SERIAL CH340(COM7)是用于单片机的烧写,也可做串口通信,需要将Qt上位机的端口号修改,即可实现通信。
在这里插入图片描述

3.1.2 Qt上位机软件

通过Qt的serialport模块进行串口通信实现相关功能。

  这里面主要逻辑是当lineEdit实例的editingFinished()信号产生的时候,调用send_data()槽函数,对lineEdit内的数据进行采集后传输,需要将lineEdit内的数据转化为QByteArray型的数据,从而通过m_serialPort->write(ba);进行数据传输。
  这里的QByteArray数据转化需要稍微注意一下,举个例子,如果需要将QString类型的‘ff’直接转化为QByteArray类型,它QByteArray产生的是一个2字节的数组,即每个字母占一个字节,即QByteArray[0] = f,QByteArray[1] = f,而不是想当然的只占一个字节,不是0xff。
  具体怎么转化可以参照代码,代码也是找的网上相关博客里,涉及到十进制如何转化为QByteArray的十六进制存储。代码内容不展开记录了。

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    m_serialPort = new QSerialPort();
    m_serialPort->setPortName("COM8");
    m_serialPort->setBaudRate(QSerialPort::Baud9600);
    m_serialPort->setDataBits(QSerialPort::Data8);
    m_serialPort->setParity(QSerialPort::NoParity);
    m_serialPort->setStopBits(QSerialPort::OneStop);
    m_serialPort->setFlowControl(QSerialPort::NoFlowControl);
    m_serialPort->setReadBufferSize(40960);

    m_serialPort->open(QIODevice::ReadWrite);

    connect(ui->lineEdit, SIGNAL(editingFinished()), this, SLOT(send_data()));

}

Widget::~Widget()
{
    m_serialPort->clear();
    m_serialPort->close();
    delete ui;
}

char ConvertHexChar(char ch)
{
    if((ch >= '0') && (ch <= '9'))
        return ch-0x30;
    else if((ch >= 'A') && (ch <= 'F'))
        return ch-'A'+10;
    else if((ch >= 'a') && (ch <= 'f'))
        return ch-'a'+10;
    else return (-1);
}

void Widget::send_data()
{
    uint8_t data_10 = ui->lineEdit->text().toInt();
    qDebug() << "data_10" << data_10;

    QString s = QString::number(data_10, 16);
    if(s.length() == 1)
    {
        s = '0' + s;
    }
    qDebug() << "s" <<s;

    QByteArray ba = QString2Hex(s);
    qDebug() << "ba" <<ba;
    m_serialPort->write(ba);
}

QByteArray Widget::QString2Hex(QString str)
{
    QByteArray senddata;
    int hexdata,lowhexdata;
    int hexdatalen = 0;
    int len = str.length();
    senddata.resize(len/2);
    char lstr,hstr;

    for(int i=0; i<len; )
    {
        hstr=str[i].toLatin1();
        if(hstr == ' ')
        {
            i++;
            continue;
        }
        i++;
        if(i >= len)
            break;
        lstr = str[i].toLatin1();
        hexdata = ConvertHexChar(hstr);
        lowhexdata = ConvertHexChar(lstr);
        if((hexdata == 16) || (lowhexdata == 16))
            break;
        else
            hexdata = hexdata*16+lowhexdata;
        i++;
        senddata[hexdatalen] = (char)hexdata;
        hexdatalen++;
    }
    senddata.resize(hexdatalen);
    return senddata;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

3.2 单片机开发板端

3.2.1 开发环境

keil uVersion5。

STC-isp

3.2.2 main.c代码

通过Qt的serialport模块进行串口通信实现相关功能。

注意点:(1)如果在开发板的RS232串口处如果有选择开关帽,需要将开关帽打开。如下图所示,此时已经打开。

在这里插入图片描述

#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula=P2^6;
sbit wela=P2^7;
sbit d1=P1^0;             //led0

unsigned char dat;
int num = 0;
uchar code tabel[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

uchar led[]={0x7e,0x7d,0x7b,0x4f,0x66,0x6d};

void display(uint data_input);
void delay(uint z);

void Uart_Init()  //初始化串口uart
{
    TMOD=0x20;
    SCON=0x50;
    PCON&=0x7F;
    TH1=0xfd;   //9600波特率下的初值
    TL1=0xfd;   // TL1= TH1
    ET1=0;   //禁止定时器1被中断
    TR1=1;   //开启定时器1
    ES=1;   //开启串口中断
    EA=1;   //开启总中断
}

void Uart_Send_Byte(unsigned char uartData)  //发送一个字节Byte
 
{ //SBUF此时为发送寄存器,需要将要发送的数据uartData存储在SBUF中
    SBUF=uartData;     //作为发送时的SBUF将自动发出存储在其中的数据(uartData)至接收区缓存
    while(!TI);     //发送完成时TI将置1,需要软件清0
    TI=0;     //软件清0
}

void main()
{	
	Uart_Init(); //串口初始化
	wela=1;
	P0=0x00;   //位选信号,决定亮的数码管的位置
	wela=0;
	while(1)
	{
//		for(num=0;num<256;num++)
//			{
//				display(num);
//			}
		display(dat);
	}
}

void delay(uint z)
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=110;y>0;y--);	
}

void display(uint data_input)
{	
	uint baiwei = (data_input/100) % 10;
	uint shiwei = (data_input/10) % 10;
	uint gewei = (data_input/1) % 10;

	dula = 1;
	P0 = tabel[baiwei];
	dula = 0;
	P0 = 0xff;      //消影
	wela = 1;
	P0 = led[0];
	wela = 0;
	delay(1);

	wela = 1;
	P0 = 0xff;
	wela = 0;

	dula = 1;
	P0 = tabel[shiwei];
	dula = 0;
	P0 = 0xff;
	wela = 1;
	P0 = led[1];
	wela = 0;
	delay(1);

	wela = 1;
	P0 = 0xff;
	wela = 0;

	dula = 1;
	P0 = tabel[gewei];
	dula = 0;
	P0 = 0xff;
	wela = 1;
	P0 = led[2];
	wela = 0;
	delay(1);

	wela = 1;
	P0 = 0xff;
	wela = 0;

}


void Uart_Service() interrupt 4  //开启串口通信中断(由RI TI触发)
{
		/*数据存在SBUF,使用"Uart_Send_Byte(dat)-发送寄存器SBUF"将会自动发出SBUF(SBUF=dat)*/
		while(!RI);    //当接收到发送缓存器的一个字节的数据后时,RI置1
		dat= SBUF;      //此时可将SBUF存储到dat中(dat为一个字节,相当于dat读取接收区SBUF)

//		P1=dat;        //再将dat值赋给P2-有8个led灯的特殊寄存器,即可实现控制LED
		Uart_Send_Byte(dat);     //这里是发送一个字节dat
		RI=0;     //手动将RI置0
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118

4 代码下载

https://download.csdn.net/download/wang_chao118/87545106

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/133053
推荐阅读
相关标签
  

闽ICP备14008679号