QT串口通信是上位機和下位機通信常用的通信方式,也是學習QT必須學會的基礎知識, 這篇就簡單介紹一下QT串口通信的簡單使用.
| 創建項目
1: 創建新項目
2: 配置相關信息
3: 設計界面
4:編寫代碼
目的: 通過簡單實驗驗證串口通信.
4.1: 配置項目
4.2: 編寫上位機代碼
widget.h文件
#ifndefWIDGET_H #defineWIDGET_H #include//引入頭文件 #include #include namespaceUi{ classWidget; } classWidget:publicQWidget { Q_OBJECT public: explicitWidget(QWidget*parent=0); ~Widget(); //定義曹函數 privateslots: voidon_pushButton_clicked(); voidreceiveInfo(); voidsendInfo(); private: Ui::Widget*ui; //串口對象指針 QSerialPort*m_serialPort; }; #endif//WIDGET_H
widget.cpp文件
#include"widget.h" #include"ui_widget.h" //調試輸出頭文件 #includeWidget::Widget(QWidget*parent): QWidget(parent), ui(newUi::Widget) { ui->setupUi(this); //實例化一個串口對象 m_serialPort=newQSerialPort(); //獲取可用的串口號 foreach(constQSerialPortInfoinfo,QSerialPortInfo::availablePorts()) { qDebug()<"Port?name:"?<comboBox->addItem(info.portName()); } } Widget::~Widget() { deleteui; } //pushButton點擊觸發的槽函數 voidWidget::on_pushButton_clicked() { if(m_serialPort->isOpen())//如果串口已經打開了先給他關閉了 { m_serialPort->clear(); m_serialPort->close(); } m_serialPort->setPortName(ui->comboBox->currentText());//當前選擇的串口名字 if(!m_serialPort->open(QIODevice::ReadWrite))//用ReadWrite的模式嘗試打開串口 { qDebug()<<"打開失敗!"; ????????return; ????} ????qDebug()<<"串口打開成功!"; ????m_serialPort->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);//設置波特率和讀寫方向 m_serialPort->setDataBits(QSerialPort::Data8);//數據位為8位 m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//無流控制 m_serialPort->setParity(QSerialPort::NoParity);//無校驗位 m_serialPort->setStopBits(QSerialPort::OneStop);//一位停止位 //手動綁定槽函數 connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo())); connect(ui->pushButton_2,SIGNAL(clicked()),this,SLOT(sendInfo())); } //接收到單片機發送的數據進行解析 voidWidget::receiveInfo() { qDebug()<<"接收"; ????QByteArray?info?=?m_serialPort->readAll(); qDebug()<<"receive?info:"< write("0x55"); m_serialPort->write("0xaa"); }
4.3: 編寫下位機代碼
main.c文件
#include"stm32f10x.h" #include"stdio.h" voidled_init(void); voidusart_init(uint32_tbound); intmain(void) { uint32_ti=0; led_init(); usart_init(115200); printf("ok "); while(1) { GPIO_ResetBits(GPIOE,GPIO_Pin_5); for(i=0;i0xfffff;?i++); ????????GPIO_SetBits(GPIOE,GPIO_Pin_5); ????????for(i?=?0;?i0xfffff;?i++); ????} } void?led_init(void) { ????GPIO_InitTypeDef?GPIO_InitStructure;//定義結構體變量 ????RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); ????GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;??//選擇你要設置的IO口 ????GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;???//設置推挽輸出模式 ????GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;???//設置傳輸速率 ????GPIO_Init(GPIOE,&GPIO_InitStructure);??????/*?初始化GPIO?*/ ????GPIO_SetBits(GPIOE,GPIO_Pin_5);???//將LED端口拉高,熄滅所有LED } void?usart_init(uint32_t?bound) { ????//GPIO端口設置 ????GPIO_InitTypeDef?GPIO_InitStructure; ????USART_InitTypeDef?USART_InitStructure; ????NVIC_InitTypeDef?NVIC_InitStructure; ????RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); ????RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); ????/*??配置GPIO的模式和IO口?*/ ????GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX?????????//串口輸出PA9 ????GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; ????GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;??????//復用推挽輸出 ????GPIO_Init(GPIOA,&GPIO_InitStructure);??/*?初始化串口輸入IO?*/ ????GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX???????//串口輸入PA10 ????GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;??????//模擬輸入 ????GPIO_Init(GPIOA,&GPIO_InitStructure);?/*?初始化GPIO?*/ ????//USART1?初始化設置 ????USART_InitStructure.USART_BaudRate?=?bound;//波特率設置 ????USART_InitStructure.USART_WordLength?=?USART_WordLength_8b;//字長為8位數據格式 ????USART_InitStructure.USART_StopBits?=?USART_StopBits_1;//一個停止位 ????USART_InitStructure.USART_Parity?=?USART_Parity_No;//無奇偶校驗位 ????USART_InitStructure.USART_HardwareFlowControl?=?USART_HardwareFlowControl_None;//無硬件數據流控制 ????USART_InitStructure.USART_Mode?=?USART_Mode_Rx?|?USART_Mode_Tx;??//收發模式 ????USART_Init(USART1,?&USART_InitStructure);?//初始化串口1 ????USART_Cmd(USART1,?ENABLE);??//使能串口1? ????USART_ClearFlag(USART1,?USART_FLAG_TC); ????USART_ITConfig(USART1,?USART_IT_RXNE,?ENABLE);//開啟相關中斷 ????//Usart1?NVIC?配置 ????NVIC_InitStructure.NVIC_IRQChannel?=?USART1_IRQn;//串口1中斷通道 ????NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//搶占優先級3 ????NVIC_InitStructure.NVIC_IRQChannelSubPriority?=3;????//子優先級3 ????NVIC_InitStructure.NVIC_IRQChannelCmd?=?ENABLE;??????//IRQ通道使能 ????NVIC_Init(&NVIC_InitStructure);??//根據指定的參數初始化VIC寄存器 } int?fputc(int?ch,FILE?*f)???//printf重定向函數 { ????USART_SendData(USART1,(uint8_t)ch);???//發送一字節數據 ????while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)?==?RESET);???//等待發送完成 ????return?ch; } void?USART1_IRQHandler(void) { ????if(USART_GetITStatus(USART1,?USART_IT_RXNE)?!=?RESET) ????{ ????????uint8_t?r?=?USART_ReceiveData(USART1); ????????USART_SendData(USART1,r); ????????while(USART_GetFlagStatus(USART1,USART_FLAG_TC)?!=?SET); ????} ????USART_ClearFlag(USART1,USART_FLAG_TC); }
| 驗證效果
把下位機代碼下到開發板, 然后運行自己編寫的上位機, 點擊上位機發送數據, 下位機就會把收到的數據返回到上位機, 可以通過控制臺查看接收到的數據;
| 簡單shell
main.c文件
#include"stm32f10x.h" #include"stdio.h" #include"string.h" #defineCMD_MAX_LEN16//定義最大命令長度 charcmd_buf[CMD_MAX_LEN];//定義命令緩沖區 uint8_tcmd_len=0;//定義命令長度 uint8_tcmd_flag=0;//定義命令接收完成標志 voidled_init(void); voidusart_init(uint32_tbound); voiduser_shell_irq(void); intmain(void) { led_init(); usart_init(115200); printf("ok "); while(1) { if(cmd_flag) { //匹配指令 if(strcmp(cmd_buf,"ledon")==0) { printf("ledon"); } //清理緩存 cmd_len=0;//清零命令長度 memset(cmd_buf,0,CMD_MAX_LEN);//清空命令緩沖區 cmd_flag=0;//清除命令接收完成標志 } } } voidled_init(void) { GPIO_InitTypeDefGPIO_InitStructure;//定義結構體變量 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//選擇你要設置的IO口 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//設置推挽輸出模式 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//設置傳輸速率 GPIO_Init(GPIOE,&GPIO_InitStructure);/*初始化GPIO*/ GPIO_SetBits(GPIOE,GPIO_Pin_5);//將LED端口拉高,熄滅所有LED } voidusart_init(uint32_tbound) { //GPIO端口設置 GPIO_InitTypeDefGPIO_InitStructure; USART_InitTypeDefUSART_InitStructure; NVIC_InitTypeDefNVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); /*配置GPIO的模式和IO口*/ GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX//串口輸出PA9 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//復用推挽輸出 GPIO_Init(GPIOA,&GPIO_InitStructure);/*初始化串口輸入IO*/ GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX//串口輸入PA10 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//模擬輸入 GPIO_Init(GPIOA,&GPIO_InitStructure);/*初始化GPIO*/ //USART1初始化設置 USART_InitStructure.USART_BaudRate=bound;//波特率設置 USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字長為8位數據格式 USART_InitStructure.USART_StopBits=USART_StopBits_1;//一個停止位 USART_InitStructure.USART_Parity=USART_Parity_No;//無奇偶校驗位 USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//無硬件數據流控制 USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//收發模式 USART_Init(USART1,&USART_InitStructure);//初始化串口1 USART_Cmd(USART1,ENABLE);//使能串口1 USART_ClearFlag(USART1,USART_FLAG_TC); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//開啟相關中斷 //Usart1NVIC配置 NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//串口1中斷通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//搶占優先級3 NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//子優先級3 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//IRQ通道使能 NVIC_Init(&NVIC_InitStructure);//根據指定的參數初始化VIC寄存器 } intfputc(intch,FILE*f)//printf重定向函數 { USART_SendData(USART1,(uint8_t)ch);//發送一字節數據 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//等待發送完成 returnch; } voidUSART1_IRQHandler(void) { if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET) { //shell user_shell_irq(); } } //獲取 voiduser_shell_irq(void) { uint8_ttemp=USART_ReceiveData(USART1); if(temp==' '||temp==' ') { cmd_buf[cmd_len]='?'; cmd_flag=1; } else { cmd_buf[cmd_len++]=temp; if(cmd_len>=CMD_MAX_LEN) { //清理緩存 cmd_len=0; memset(cmd_buf,0,CMD_MAX_LEN); } } }
驗證:
簡單介紹了QT的串口如何與下位機通信, 同時也簡單通過shell交互, 進一步拓展了串口通信場景.
審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
串口通信
+關注
關注
33文章
1585瀏覽量
55011 -
上位機
+關注
關注
26文章
906瀏覽量
54270 -
Qt
+關注
關注
1文章
299瀏覽量
37453 -
下位機
+關注
關注
0文章
90瀏覽量
18633
原文標題:QT|串口通信
文章出處:【微信號:玩轉單片機,微信公眾號:玩轉單片機】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
Qt小項目之串口助手控制LED
最近剛學了一點Qt開發上位機,嘗試著做個小軟件練練手。查找了很多資料,做了一個簡單的串口助手,可以實現串口基本發送和接收功能,支...
發表于 01-26 18:21
?1次下載
![<b class='flag-5'>Qt</b>小項目之<b class='flag-5'>串口</b>助手控制LED](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
基于Qt實現的串口示波器
摘要:逛github時看到這個QT的串口示波器,完全開源,支持串口、TCP、波形顯示、通信協議。感覺很不錯,跟以前分享的那個vofa+有點像。感興趣的可以下載下來學習學習。
QT與三菱PLC串口通信
最近兩天在學習QT與三菱PLC串口通信,特此記錄下來。 通信格式 我這里使用RS-232C連接的,根據FX編程口協議! 設置參數,以讀寫的方式打開串
發表于 04-17 16:08
?0次下載
![<b class='flag-5'>QT</b>與三菱PLC<b class='flag-5'>串口</b><b class='flag-5'>通信</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
基于QT的簡單的上位機
。同樣的,我們也從編寫一個簡單的基于QT的上位機來體會體會上位機開發及認識認識QT。我們本次實現的上位機的功能很簡單:上位機通過串口來控制開
發表于 05-08 10:57
?16次下載
![基于<b class='flag-5'>QT</b>的<b class='flag-5'>簡單</b>的上位機](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
QT篇QT上位機串口編程
QT 篇 QT上位機串口編程 最近因為項目需要,需要用到上位機,通過串口與上位機進行通訊,來上傳和下發一些數據以及控制指令,所以用QT寫了一
發表于 05-08 10:02
?23次下載
![<b class='flag-5'>QT</b>篇<b class='flag-5'>QT</b>上位機<b class='flag-5'>串口</b>編程](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
QT5串口編程——編寫簡單的上位機
下面開始介紹串口類的使用。 首先,QT5是自帶QSerialPort這個類的,使用時需要在pro文件里面添加一行: ?然后直接引用頭文件就可以了。 ?在QT5中,串口
發表于 05-10 14:28
?0次下載
![<b class='flag-5'>QT</b>5<b class='flag-5'>串口</b>編程——編寫<b class='flag-5'>簡單</b>的上位機](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
Qt5實現上位機與串口通信
Qt助手內搜索:Qt Serial Port為串口的相關函數? 1.添加串口頭文件: # include //使用串口功能# inc
發表于 05-10 10:46
?0次下載
![<b class='flag-5'>Qt</b>5實現上位機與<b class='flag-5'>串口</b><b class='flag-5'>通信</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
STM32單片機如何處理QT上位機串口中發過來的數據?
數據傳輸的通信方式。串口通信是一種簡單、穩定、可靠的通信方式,其原理是通過串口發送端口將數據轉換
評論