QT串口通信是上位機(jī)和下位機(jī)通信常用的通信方式,也是學(xué)習(xí)QT必須學(xué)會的基礎(chǔ)知識, 這篇就簡單介紹一下QT串口通信的簡單使用.
| 創(chuàng)建項目
1: 創(chuàng)建新項目

2: 配置相關(guān)信息




3: 設(shè)計界面


4:編寫代碼
目的: 通過簡單實驗驗證串口通信.
4.1: 配置項目

4.2: 編寫上位機(jī)代碼
widget.h文件
#ifndefWIDGET_H #defineWIDGET_H #include//引入頭文件 #include #include namespaceUi{ classWidget; } classWidget:publicQWidget { Q_OBJECT public: explicitWidget(QWidget*parent=0); ~Widget(); //定義曹函數(shù) 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" //調(diào)試輸出頭文件 #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點擊觸發(fā)的槽函數(shù) voidWidget::on_pushButton_clicked() { if(m_serialPort->isOpen())//如果串口已經(jīng)打開了先給他關(guān)閉了 { m_serialPort->clear(); m_serialPort->close(); } m_serialPort->setPortName(ui->comboBox->currentText());//當(dāng)前選擇的串口名字 if(!m_serialPort->open(QIODevice::ReadWrite))//用ReadWrite的模式嘗試打開串口 { qDebug()<<"打開失敗!"; ????????return; ????} ????qDebug()<<"串口打開成功!"; ????m_serialPort->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);//設(shè)置波特率和讀寫方向 m_serialPort->setDataBits(QSerialPort::Data8);//數(shù)據(jù)位為8位 m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//無流控制 m_serialPort->setParity(QSerialPort::NoParity);//無校驗位 m_serialPort->setStopBits(QSerialPort::OneStop);//一位停止位 //手動綁定槽函數(shù) connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo())); connect(ui->pushButton_2,SIGNAL(clicked()),this,SLOT(sendInfo())); } //接收到單片機(jī)發(fā)送的數(shù)據(jù)進(jìn)行解析 voidWidget::receiveInfo() { qDebug()<<"接收"; ????QByteArray?info?=?m_serialPort->readAll(); qDebug()<<"receive?info:"< write("0x55"); m_serialPort->write("0xaa"); }
4.3: 編寫下位機(jī)代碼
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;//定義結(jié)構(gòu)體變量 ????RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); ????GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;??//選擇你要設(shè)置的IO口 ????GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;???//設(shè)置推挽輸出模式 ????GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;???//設(shè)置傳輸速率 ????GPIO_Init(GPIOE,&GPIO_InitStructure);??????/*?初始化GPIO?*/ ????GPIO_SetBits(GPIOE,GPIO_Pin_5);???//將LED端口拉高,熄滅所有LED } void?usart_init(uint32_t?bound) { ????//GPIO端口設(shè)置 ????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;??????//復(fù)用推挽輸出 ????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?初始化設(shè)置 ????USART_InitStructure.USART_BaudRate?=?bound;//波特率設(shè)置 ????USART_InitStructure.USART_WordLength?=?USART_WordLength_8b;//字長為8位數(shù)據(jù)格式 ????USART_InitStructure.USART_StopBits?=?USART_StopBits_1;//一個停止位 ????USART_InitStructure.USART_Parity?=?USART_Parity_No;//無奇偶校驗位 ????USART_InitStructure.USART_HardwareFlowControl?=?USART_HardwareFlowControl_None;//無硬件數(shù)據(jù)流控制 ????USART_InitStructure.USART_Mode?=?USART_Mode_Rx?|?USART_Mode_Tx;??//收發(fā)模式 ????USART_Init(USART1,?&USART_InitStructure);?//初始化串口1 ????USART_Cmd(USART1,?ENABLE);??//使能串口1? ????USART_ClearFlag(USART1,?USART_FLAG_TC); ????USART_ITConfig(USART1,?USART_IT_RXNE,?ENABLE);//開啟相關(guān)中斷 ????//Usart1?NVIC?配置 ????NVIC_InitStructure.NVIC_IRQChannel?=?USART1_IRQn;//串口1中斷通道 ????NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//搶占優(yōu)先級3 ????NVIC_InitStructure.NVIC_IRQChannelSubPriority?=3;????//子優(yōu)先級3 ????NVIC_InitStructure.NVIC_IRQChannelCmd?=?ENABLE;??????//IRQ通道使能 ????NVIC_Init(&NVIC_InitStructure);??//根據(jù)指定的參數(shù)初始化VIC寄存器 } int?fputc(int?ch,FILE?*f)???//printf重定向函數(shù) { ????USART_SendData(USART1,(uint8_t)ch);???//發(fā)送一字節(jié)數(shù)據(jù) ????while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)?==?RESET);???//等待發(fā)送完成 ????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); }
| 驗證效果
把下位機(jī)代碼下到開發(fā)板, 然后運行自己編寫的上位機(jī), 點擊上位機(jī)發(fā)送數(shù)據(jù), 下位機(jī)就會把收到的數(shù)據(jù)返回到上位機(jī), 可以通過控制臺查看接收到的數(shù)據(jù);

| 簡單shell
main.c文件
#include"stm32f10x.h"
#include"stdio.h"
#include"string.h"
#defineCMD_MAX_LEN16//定義最大命令長度
charcmd_buf[CMD_MAX_LEN];//定義命令緩沖區(qū)
uint8_tcmd_len=0;//定義命令長度
uint8_tcmd_flag=0;//定義命令接收完成標(biāo)志
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);//清空命令緩沖區(qū)
cmd_flag=0;//清除命令接收完成標(biāo)志
}
}
}
voidled_init(void)
{
GPIO_InitTypeDefGPIO_InitStructure;//定義結(jié)構(gòu)體變量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//選擇你要設(shè)置的IO口
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//設(shè)置推挽輸出模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//設(shè)置傳輸速率
GPIO_Init(GPIOE,&GPIO_InitStructure);/*初始化GPIO*/
GPIO_SetBits(GPIOE,GPIO_Pin_5);//將LED端口拉高,熄滅所有LED
}
voidusart_init(uint32_tbound)
{
//GPIO端口設(shè)置
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;//復(fù)用推挽輸出
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初始化設(shè)置
USART_InitStructure.USART_BaudRate=bound;//波特率設(shè)置
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字長為8位數(shù)據(jù)格式
USART_InitStructure.USART_StopBits=USART_StopBits_1;//一個停止位
USART_InitStructure.USART_Parity=USART_Parity_No;//無奇偶校驗位
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//無硬件數(shù)據(jù)流控制
USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//收發(fā)模式
USART_Init(USART1,&USART_InitStructure);//初始化串口1
USART_Cmd(USART1,ENABLE);//使能串口1
USART_ClearFlag(USART1,USART_FLAG_TC);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//開啟相關(guān)中斷
//Usart1NVIC配置
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//串口1中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//搶占優(yōu)先級3
NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//子優(yōu)先級3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//IRQ通道使能
NVIC_Init(&NVIC_InitStructure);//根據(jù)指定的參數(shù)初始化VIC寄存器
}
intfputc(intch,FILE*f)//printf重定向函數(shù)
{
USART_SendData(USART1,(uint8_t)ch);//發(fā)送一字節(jié)數(shù)據(jù)
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//等待發(fā)送完成
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的串口如何與下位機(jī)通信, 同時也簡單通過shell交互, 進(jìn)一步拓展了串口通信場景.
-
串口通信
+關(guān)注
關(guān)注
34文章
1662瀏覽量
57971 -
上位機(jī)
+關(guān)注
關(guān)注
27文章
1002瀏覽量
57053 -
Qt
+關(guān)注
關(guān)注
2文章
320瀏覽量
40884 -
下位機(jī)
+關(guān)注
關(guān)注
0文章
97瀏覽量
19486
原文標(biāo)題:QT|串口通信
文章出處:【微信號:玩轉(zhuǎn)單片機(jī),微信公眾號:玩轉(zhuǎn)單片機(jī)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
基于QT的串口調(diào)試工具設(shè)計
QT串口通信的相關(guān)資料推薦
Qt串口通信專題教程
利用QT 串口通信進(jìn)行RS232協(xié)議開發(fā)
基于Qt實現(xiàn)的串口示波器
QT與三菱PLC串口通信
基于QT的簡單的上位機(jī)
QT篇QT上位機(jī)串口編程
QT實現(xiàn)簡單的上位機(jī)軟件
Qt5實現(xiàn)上位機(jī)與串口通信
QT串口通信的簡單使用
評論