历史上的今天
今天是: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 
史海拾趣
|
玩LPC1个月了,关于ISP与硬狗的共存,不错的方法,共享一下: 前提: 硬狗周期>=1.6S,如MAX706. 用两个1N4148将喂狗线和TXD0接成\"或逻辑\"低有效的复位. 这样在P0.14拉低的条件下,上电复位LPC会进入ISP,由于ISP程序不会喂狗,所以会重复复位过程. ...… 查看全部问答> |
|
很简单的代码,如下: { std::map mpTmp; for(int i = 0; i < 1024 * 100; i ++) { &nb ...… 查看全部问答> |
|
WINCE6/VS2005 环境下,WINCE6下面的范例目录如何查找?(范例在什么目录下) WINCE6/VS2005 环境下,WINCE6下面的范例目录如何查找?(范例在什么目录下) 有人说在WINCE600\\...\\CellCore\\目录下面有电话 和短信的范例.… 查看全部问答> |
|
在下正纠结于基于51单片机的毕设,此跟踪系统只需要仿真出来即可。 我已经完成了4个方向的电压采集与比较,选出最大的方向。下面就是如何使单片机与步进电机相结合,是的步进电机向电压大的方向旋转。 要求角度:水平0~360;垂直10~80.角度精度 ...… 查看全部问答> |
|
如题,看资料上讲把flash分块,第一块放启动代码,后边的块放核心,在后边放跟文件系统。 bootloader不也是放在flash的最开始的位置吗?所以问系统的启动代码和bootloader是不是一个东西,多谢啦… 查看全部问答> |




