历史上的今天
返回首页

历史上的今天

今天是:2025年01月23日(星期四)

正在发生

2020年01月23日 | 基于RS232串口实现PIC单片机下位机与QT上位机通信

2020-01-23 来源:eefocus

简介:上位机通过RS232串口发送消息给下位机,下位机收到消息并做出2个动作:


(1)LED灯变化。


(2)将消息通过RS232串口返回给上位机;


上位机收到消息后将内容显示在UI界面上。


windows7 64位环境完整源码及源程序打包下载:   https://download.csdn.net/download/robin_xx/10791050


主要代码粘贴如下:


PIC单片机下位机源程序:


#include

__CONFIG(HS&WDTDIS&LVPDIS);

unsigned char i=0;

//void interrupt ISR(void);

void interrupt usart(void);

void Init(void); //初始化

unsigned char* sendData="";

 

const unsigned char led10[]=//8个led流水灯码表

    {

        0B00000000,

        0B00000001,

        0B00000010,

        0B00000100,

        0B00001000,

        0B00010000,

        0B00100000,

        0B01000000,

        0B10000000,

        0B11111111

    };

void main(void)

{

 

    Init();

    while(1)

    {

        if (i==10)

            i=0;

        PORTB=led10[i];

    }

}

 

 

/*void interrupt ISR(void)//

{

    if(INTF==1)//按键中断

    {

        INTF=0;//清中断标志位

        i+=1;//每次产生中断时流水灯从头开始点亮

    }

}*/

 

void interrupt usart(void)

{

    if(RCIE&&RCIF) //判断是否为串口接收中断

    {

        i+=1;

        while(!TRMT);//等待接受完毕

        sendData=RCREG; 

        //i=sendData;

    }

    if(sendData!="")

    {    

        RCIE=0;//发送前关闭接受中断使能位

        TXREG = sendData; //把接收到的数据发送回去

        while(!TXIF);//等待发送完成

        RCIE = 1;//发送完成开启接收中断使能位

        sendData="";

    }

}

 

void Init(void)

{

    TRISB=0B00000000;//控制8个LED,输出口

    PORTB=0B00000000;//

 

    //初始化端口程序

    TRISC7 = 1; //RX端口设为输入有效

    TRISC6 = 0; //TX端口设为输出有效

 

    //SPBRG = 0X19;   //设置波特率为9600BPS

    SPBRG = 0XC;    //设置波特率为19200BPS

 

    //TXSTA = 0x04;   //异步通讯-禁止发送数据-高速模式

    TXSTA = 0X24;  //使能串口发送,选择高速波特率

 

    //RCSTA = 0xA0;   //串口使能-接收单字符-禁止连续接受

    RCSTA = 0X90; //使能串口工作,连续接收

 

    RCIE=0X1; //使能接收中断

    GIE=0X1; //开放全局中断

    PEIE=0X1; //使能外部中断

}

QT上位机源程序:


mainwindow.h


#ifndef MAINWINDOW_H

#define MAINWINDOW_H

 

#include

#include

#include

 

namespace Ui {

class MainWindow;

}

 

class MainWindow : public QMainWindow

{

    Q_OBJECT

 

public:

    QSerialPort *serial;

    explicit MainWindow(QWidget *parent = 0);

    ~MainWindow();

 

 

private slots:

 

    void on_pushButton_send_clicked();

 

    void on_pushButton_openPort_clicked();

 

    void read_Com();

 

    void on_pushButton_ClearRec_clicked();

 

 

private:

    Ui::MainWindow *ui;

};

 

#endif // MAINWINDOW_H

 


mainwindow.cpp

 


#include "mainwindow.h"

#include "ui_mainwindow.h"

 

MainWindow::MainWindow(QWidget *parent) :

    QMainWindow(parent),

    ui(new Ui::MainWindow)

{

    ui->setupUi(this);

 

    foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts())

    {

        QSerialPort serial;

        serial.setPort(info);

        //判断串口能否打开

        if(serial.open(QIODevice::ReadWrite))

        {

            QString portStr = info.portName();

            ui->comboBox_portList->addItem(portStr);

            serial.close();

        }

     }

 

    ui->comboBox_portList->setCurrentIndex(0);

    ui->comboBox_BPS->addItem("7200");

    ui->comboBox_BPS->addItem("9600");

    ui->comboBox_BPS->addItem("14400");

    ui->comboBox_BPS->addItem("19200");

    ui->comboBox_BPS->addItem("38400");

    ui->comboBox_BPS->addItem("57600");

 

    ui->comboBox_BPS->setCurrentIndex(3);

 

    on_pushButton_openPort_clicked();

    on_pushButton_openPort_clicked();

 

}

 

MainWindow::~MainWindow()

{

    delete ui;

}

 

 

//读取接收到的信息

 void MainWindow::read_Com()

 {

     QByteArray temp=serial->readAll();

     if(!temp.isEmpty())//如果读到的数据不为空

     {

         ui->textBrowser_RecList->insertPlainText(temp);

     }

 }

 

 

//发送按钮槽函数

void MainWindow::on_pushButton_send_clicked()

{

    QString str=ui->lineEdit_sendText->text();//从LineEdit得到字符串

    if(str!="")

    {

        ui->textBrowser_RecList->insertPlainText("n");

        serial->write(str.toLatin1());//以ASCII码形式将数据写入串口

        //ui->lineEdit_sendText->clear();

    }

}

 

void MainWindow::on_pushButton_openPort_clicked()

{

    if(ui->comboBox_portList->isEnabled())

     {

        ui->pushButton_openPort->setText("ClosePort"); //按下“OpenPort”后,按键显示为“ClosePort”

        ui->comboBox_portList->setDisabled(true); //按下“OpenPort”后,禁止再修改COM口

 

        serial = new QSerialPort;

        //设置串口名

        serial->setPortName(ui->comboBox_portList->currentText());

 

        ui->textBrowser_RecList->insertPlainText("nNowPort:"+ui->comboBox_portList->currentText());

        //自动寻找可用串口的方法

 

        //先关串口,再打开,可以保证串口不被其它函数占用。

        //serial->close();

 

        //打开串口

        serial->open(QIODevice::ReadWrite);

 

        //设置波特率

        serial->setBaudRate(ui->comboBox_BPS->currentText().toInt());

        ui->comboBox_BPS->setDisabled(true);

 

         //设置数据位数 (8)

         serial->setDataBits(QSerialPort::Data8);

 

        //设置校验位(如0)

         serial->setParity(QSerialPort::NoParity);

 

        //设置停止位(如1)

         serial->setStopBits(QSerialPort::OneStop);

 

        //设置流控制(无)

         serial->setFlowControl(QSerialPort::NoFlowControl);

 

         //把串口的readyRead()信号绑定到read_Com()这个槽函数上

         connect(serial,SIGNAL(readyRead()),this,SLOT(read_Com()));

    }

    else

    {

        ui->pushButton_openPort->setText("OpenPort"); //按下“ClosePort”后,按键显示为“OpenPort”

        ui->comboBox_portList->setEnabled(true);      //按下“ClosePort”后,COM口可被修改

        ui->comboBox_BPS->setEnabled(true);

        serial->close(); //关串口

    }

}

 

 

void MainWindow::on_pushButton_ClearRec_clicked()

{

    ui->textBrowser_RecList->clear();

}

main.cpp


#include "mainwindow.h"

#include

 

int main(int argc, char *argv[])

{

    QApplication a(argc, argv);

    MainWindow w;

    w.show();

 

    return a.exec();

}

UI界面:

windows7 64位环境完整源码及源程序打包下载:   https://download.csdn.net/download/robin_xx/10791050

推荐阅读

史海拾趣

Ampire Co Ltd公司的发展小趣事

Ampire Co., Ltd. 是一家总部位于中国深圳的汽车电子产品制造商,专注于汽车安全、娱乐和舒适性电子产品的研发、生产和销售。以下是关于 Ampire 公司发展的五个相关故事:

  1. 成立与初创阶段:Ampire 公司成立于 2002 年,起初主要从事汽车电子产品的贸易业务。公司的创始人致力于在汽车行业提供高品质的电子产品,以提升驾驶体验和车辆安全性。在公司初期,他们主要进口和销售一些汽车音响和影音产品。

  2. 技术创新与产品升级:随着市场需求的不断变化和技术的进步,Ampire 公司开始注重技术创新和产品升级。公司加大了对汽车安全和行车辅助系统的研发投入,推出了一系列高品质的后视摄像头、倒车雷达、行车记录仪等产品,以提高车辆的安全性和驾驶便利性。

  3. 品牌建设与市场拓展:Ampire 公司通过不断提升产品质量和服务水平,逐渐树立起了良好的品牌形象,并在国内外市场上获得了良好的口碑和知名度。公司积极参加国内外汽车电子展会和行业活动,拓展了国际市场,产品出口至欧美、东南亚等多个国家和地区。

  4. 生产基地建设与产能提升:为满足不断增长的市场需求,Ampire 公司逐步扩大了生产基地,并引进了先进的生产设备和技术。公司建立了完善的生产制造体系,实现了规模化生产和产能提升,保障了产品质量和交货期。

  5. 持续发展与未来规划:Ampire 公司持续致力于技术创新和产品升级,不断推出符合市场需求的新品。未来,公司计划进一步加大在汽车安全、智能驾驶和车载娱乐等领域的研发投入,积极探索人工智能、互联网车联网等新技术的应用,为客户提供更加智能、安全和便捷的汽车电子产品。

这些故事展示了 Ampire 公司从创立初期到如今在技术创新、产品升级、品牌建设、生产基地建设以及未来规划等方面取得的重要进展。

Crystal Semiconductor Corp公司的发展小趣事

随着产品质量的提升和技术创新的积累,Crystal Semiconductor Corp开始积极拓展国内外市场。公司加强了与全球知名企业的合作,通过参加国际展会、举办技术研讨会等方式提升品牌知名度。同时,公司还注重客户服务,积极解决客户在使用过程中遇到的问题,赢得了良好的口碑。

GHI Electronics公司的发展小趣事

随着业务的不断拓展,GHI Electronics开始实施全球化战略。公司积极寻求与全球合作伙伴的合作机会,共同开拓新市场。同时,GHI Electronics还在多个国家和地区设立了分支机构或研发中心,以便更好地服务当地客户并快速响应市场需求。这种全球化战略布局不仅增强了GHI Electronics的市场竞争力,也为其带来了更多的商业机会和发展空间。

Cavium Networks公司的发展小趣事

随着通信网络的不断升级和转型,Cavium Networks 看到了市场的巨大潜力。在2008年,尽管全球经济风暴肆虐,但 Cavium Networks 依然保持着强劲的增长势头。同年11月,公司宣布收购 W&W Communications 公司,这一举措进一步拓展了 Cavium Networks 的业务范围,增强了其在网络通信领域的竞争力。通过收购,Cavium Networks 获得了更多的技术资源和市场份额,为其后续的发展提供了有力的支持。

客益(Guestgood)公司的发展小趣事

作为一家在电子行业具有影响力的公司,Cavium Networks 始终保持着持续创新的精神。公司不断投入研发资源,推出了一系列具有创新性和领先性的产品和技术。同时,Cavium Networks 也积极参与国际标准和行业规范的制定工作,为电子行业的健康发展贡献了自己的力量。正是这种不断创新和追求卓越的精神,使得 Cavium Networks 在电子行业中保持了领先地位,并引领着行业的未来发展。

以上五个故事虽然基于虚构,但它们都紧密围绕 Cavium Networks 在电子行业中的发展历程和关键事件展开,展示了公司在技术创新、市场拓展和合作发展等方面的努力和成就。这些故事旨在展现 Cavium Networks 的发展轨迹和行业影响力,同时也反映了电子行业的快速发展和变革。

FTDI [Future Technology Devices International Ltd.]公司的发展小趣事

FTDI的创立可以追溯到1992年3月13日,由弗雷德·达特(Fred Dart)领导创建。初期,公司专注于为个人电脑市场提供服务,特别是针对主板芯片组的解决方案。FTDI的首发产品就得到了IBM等知名企业的青睐,这些芯片被成功应用于AMBRA和PS/2系列个人电脑中,为当时快速发展的计算机技术贡献了重要力量。这一早期成功奠定了FTDI在电子行业中稳固的基础。

问答坊 | AI 解惑

LPC单片机关于ISP与硬狗的共存

玩LPC1个月了,关于ISP与硬狗的共存,不错的方法,共享一下: 前提: 硬狗周期>=1.6S,如MAX706. 用两个1N4148将喂狗线和TXD0接成\"或逻辑\"低有效的复位. 这样在P0.14拉低的条件下,上电复位LPC会进入ISP,由于ISP程序不会喂狗,所以会重复复位过程. ...…

查看全部问答>

std::map根本没有任何办法去释放内存,何解?

很简单的代码,如下:      {         std::map mpTmp;         for(int i = 0; i < 1024 * 100; i ++)         {           &nb ...…

查看全部问答>

矩阵二极管问题2

8*8矩阵上,是不是要在每行上反接一个二极管就可以了? 要不要每个按键上都反接一个二极管? 列上要不要加二极管?…

查看全部问答>

WINCE6/VS2005 环境下,WINCE6下面的范例目录如何查找?(范例在什么目录下)

WINCE6/VS2005 环境下,WINCE6下面的范例目录如何查找?(范例在什么目录下) 有人说在WINCE600\\...\\CellCore\\目录下面有电话 和短信的范例.…

查看全部问答>

BIOS的诞生?

BIOS是一直都有的吗?有介绍BIOS发展的网页资料吗?如果刚开始没有BIOS那么远古的计算机是怎么启动的呢?…

查看全部问答>

大家,帮帮我呀!

我加了一个.NET 2.0后,需要SYSGEN才生效吗?PB什么时候需要SYSGEN?谢谢呀!…

查看全部问答>

项目外包,深圳

项目外包,寻深圳 wince 兼职开发人员 条件:1、有wince项目开发经验,精通 wince 平台下的应用程序开发。       2、工作内容:windows PC软件向wince移植。       3、开发人员必须在深圳。 详细工作 ...…

查看全部问答>

想请教下,可以用什么型号替代IRF3710PBF

如题,现在IRF3710PBF货料短缺,大家伙帮我看看哪个型号可以替代他,谢谢…

查看全部问答>

基于51单片机的太阳能自动跟踪系统(毕设)

在下正纠结于基于51单片机的毕设,此跟踪系统只需要仿真出来即可。 我已经完成了4个方向的电压采集与比较,选出最大的方向。下面就是如何使单片机与步进电机相结合,是的步进电机向电压大的方向旋转。 要求角度:水平0~360;垂直10~80.角度精度 ...…

查看全部问答>

bootloader和系统的启动代码是一回事吗

如题,看资料上讲把flash分块,第一块放启动代码,后边的块放核心,在后边放跟文件系统。    bootloader不也是放在flash的最开始的位置吗?所以问系统的启动代码和bootloader是不是一个东西,多谢啦…

查看全部问答>