Qt-UART-demo

1、串口

串行通信的接口

常见的数据通信的基本方式可分为:并行通信与串行通信

串行通信是指利用一条传输线将数据以比特位为单位顺序传送

特点:成本低、线路操作简单、适合远距离传输

1.1、并行传输:

字符编码的各位(比特)同时传输。

特点:

(1)传输速度快:一位(比特)时间内可传输一个字符;

(2)通信成本高:每位传输要求一个单独的信道支持;因此如果一个字符包含8个二进制位,则并行传输要求8个独立的信道的支持;

(3)不支持长距离传输:由于信道之间的电容感应,远距离传输时,可靠性较低

1.2、串行传输:

将组成字符的各位串行地发往线路。

特点:

(1)传输速度较低,一次一位;

(2)通信成本也较低,只需一个信道。

(3)支持长距离传输,目前计算机网络中所用的传输方式均为串行传输。

1.3、串行传输有两种传输方式:同步和异步

同步通信原理

同步通信是一种连续串行传送数据的通信方式,一次通信只传送一帧信息。这里的信息帧与异步通信中的字符帧不同,通常含有若干个数据字符。 采用同步通信时,将许多字符组成一个信息组,这样,字符可以一个接一个地传输,但是,在每组信息(通常称为帧)的开始要加上同步字符,在没有信息要传输时,要填上空字符,因为同步传输不允许有间隙。在同步传输过程中,一个字符可以对应5~8位。当然,对同一个传输过程,所有字符对应同样的数位,比如说n位。这样,传输时,按每n位划分为一个时间片,发送端在一个时间片中发送一个字符,接收端则在一个时间片中接收一个字符。 同步传输时,一个信息帧中包含许多字符,每个信息帧用同步字符作为开始,一般将同步字符和空字符用同一个代码。在整个系统中,由一个统一的时钟控制发送端的发送和空字符用同一个代码。接收端当然是应该能识别同步字符的,当检测到有一串数位和同步字符相匹配时,就认为开始一个信息帧,于是,把此后的数位作为实际传输信息来处理

异步通信原理

异步通信是一种很常用的通信方式。异步通信在发送字符时,所发送的字符之间的时间间隔可以是任意的。当然,接收端必须时刻做好接收的准备。发送端可以在任意时刻开始发送字符,因此必须在每一个字符的开始和结束的地方加上标志,即加上开始位和停止位,以便使接收端能够正确地将每一个字符接收下来

异步通信的好处

通信设备简单、便宜,但传输效率较低(因为开始位和停止位的开销所占比例较大)

同步通信与异步通信区别:

1.同步通信要求接收端时钟频率和发送端时钟频率一致,发送端发送连续的比特流;异步通信时不要求接收端时钟和发送端时钟同步,发送端发送完一个字节后,可经过任意长的时间间隔再发送下一个字节

2.同步通信效率高;异步通信效率较低

3.同步通信较复杂,双方时钟的允许误差较小;异步通信简单,双方时钟可允许一定误差。 4.同步通信可用于点对多点;异步通信只适用于点对点

1.4、异步串口 UART

UART->RS232/TTL

RS232:连接电脑的串口。-15v~ -3v 代表1 +3v~ +15v 代表0

TTL:芯片数据传输的常用串口。串口正极:+3.3V~5V,低电平:0V

1.5、单工、半双工、全双工

1.6、test 串口异步通信

grep “B115200” -r -n //递归查找包含 “B115200” 的文件

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>	
#include <termios.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>

static const char *ttySAC1 = "/dev/ttySAC1";//snd TX1
static const char *ttySAC2 = "/dev/ttySAC2";//rcv RX2

void init_uart(int fd)
{
	struct termios new_cfg, old_cfg;

    bzero(&new_cfg,sizeof(new_cfg));
	bzero(&old_cfg,sizeof(old_cfg));
	// 保存原先串口配置
	tcgetattr(fd,&old_cfg);
	// 激活选项(本地连接和接收使能)
	new_cfg.c_cflag |= CLOCAL | CREAD;

	// 设置原始模式和波特率
	cfmakeraw(&new_cfg);
	cfsetispeed(&new_cfg, B115200);
	cfsetospeed(&new_cfg, B115200);

	// 设置字符大小
	new_cfg.c_cflag	&= ~CSIZE; /* 用数据位掩码清空数据位设置 */
	new_cfg.c_cflag	|= CS8;
	//设置奇偶校验
	//无校验位
	new_cfg.c_cflag &= ~PARENB;
	//设置停止位
	new_cfg.c_cflag &= ~CSTOP;/* 将停止位设置为一个比特 */
	// new_cfg.c_cflag |= CSTOPB; /* 将停止位设置为两个比特 */

	//设置最小字符和等待时间
	new_cfg.c_cc[VTIME] = 0;
	new_cfg.c_cc[VMIN] = 1;

	//清除串口缓冲
	tcflush(fd, TCIOFLUSH);
	//激活配置
	tcsetattr(fd,TCSANOW,&new_cfg);
}

void *thread_uart(void * arg)
{
	int fd = *(int *)arg;
	while(1)
	{
        //收数据
		char buf[10] = {0};
		read(fd,buf,10);
		printf("data: %s\n",buf);
	}
}

int main(int argc, char *argv[])
{
	int fd1 = open(ttySAC1,O_RDWR | O_NOCTTY);
	int fd2 = open(ttySAC2,O_RDWR | O_NOCTTY);
	if(fd1 < 0 || fd2 < 0)
	{
		perror("open");
		exit(0);
	}

	init_uart(fd1);
	init_uart(fd2);

	pthread_t tid;
	pthread_create(&tid,NULL,thread_uart,(void *)&fd2);

	while(1)
	{
		//发送数据
		char buf[10]={0};
		scanf("%s",buf);
		write(fd1,buf,strlen(buf));
	}

	close(fd1);
	close(fd2);
	return 0;
}

/*
// tcflag_t c_iflag;       input modes
// tcflag_t c_oflag;       output modes 
// tcflag_t c_cflag;       control modes 
// tcflag_t c_lflag;       local modes 
// cc_t     c_cc[NCCS];    special characters 

设置奇偶校验位需要用到 termios 中的两个成员:c_cflag 和 c_iflag。首先要激活 c_cflag 中的校验位使能标志 PARENB 和是否要进行偶校验,同时还要激活 c_iflag 中 的对于输入数据的奇偶校验使能(INPCK)。
无校验位,代码如下:
new_cfg.c_cflag &= ~PARENB;
如使能奇校验时,代码如下所示:
new_cfg.c_cflag |= (PARODD | PARENB);
new_cfg.c_iflag |= INPCK;
而使能偶校验时,代码如下所示:
new_cfg.c_cflag |= PARENB;
new_cfg.c_cflag &= ~PARODD;       //清除偶校验标志,则配置为奇校验
new_cfg.c_iflag |= INPCK;

tcsetattr(int fd, int optional_actions, const struct termios*termios_p);
其中参数 termios_p 是 termios 类型的新配置变量。
参数 optional_actions 可能的取值有以下 3 种:
TCSANOW:配置的修改立即生效。
TCSADRAIN:配置的修改在所有写入 fd 的输出都传输完毕之后生效。
TCSAFLUSH:所有已接受但未读入的输入都将在修改生效之前被丢弃。
该函数若调用成功则返回 0,若失败则返回-1,代码如下所示:
if ((tcsetattr(fd, TCSANOW, &new_cfg)) != 0)
{
       perror("tcsetattr");
       return -1;
}
*/

2、QT串口编程

QSerialPort
QSerialPortInfo

2.1、在工程文件里添加

QT += serialport

2.2、添加头文件

#include <QSerialPort>
#include <QSerialPortInfo>

2.3、获取本机串口

foreach(constQSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
    ui->cbb_com->addItem(info.portName());
}

2.4、创建串口对象

QSerialPort mserial;

2.5、配置串口

mserial.setBaudRate(115200);//设置波特率
mserial.setDataBits(QSerialPort::Data8);//设置数据位
mserial.setStopBits(QSerialPort::OneStop);//停止位
mserial.setParity(QSerialPort::NoParity);//无奇偶校验
mserial.setFlowControl(QSerialPort::NoFlowControl);//无流控

2.6、打开串口

mserial.setPortName(ui->comboBox->currentText());
if(!mserial.open(QIODevice::ReadWrite))
{
    qDebug()<<"串口打开失败";
}
else
{
    qDebug()<<"串口打开成功";
}

2.7、 读写数据

//读数据
//关联可读信号的槽函数
connect(&mserial, &QSerialPort::readyRead, this, &MainWindow::read_data);
void MainWindow::read_data()
{
    QString msg = mserial.readAll();
    ui->textBrowser->append(msg);
}
//写数据
void MainWindow::on_btn_send_clicked()
{
    mserial.write(ui->textEdit->toPlainText().toUtf8());
}

3.8 关闭串口

mserial.close();
::read_data);
void MainWindow::read_data()
{
    QString msg = mserial.readAll();
    ui->textBrowser->append(msg);
}
//写数据
void MainWindow::on_btn_send_clicked()
{
    mserial.write(ui->textEdit->toPlainText().toUtf8());
}

3.8 关闭串口

mserial.close();
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yengi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值