刚刚开始玩nanopi,一个光秃秃的开发板,看着大牛们能玩出花来,自己对其充满向往,然而到了自己手里就不是那么回事了,从拿到板子,到装完debian系统,各种配置就已经让我焦头烂额,对于师兄们留下的文档反复揣摩,终于最后系统配置成功。
然后就开始做的第一个实验,基于QT的串口通信。 话说这个qt5的安装还真是一帆风顺
sudo apt-get update sudo apt-get upgrade sudo apt-cache search qt5 sudo apt-cache show qt5-default sudo apt-get install qt5-default //查看版本 sudo apt-get install qtcreator然后配置qtcreator,一般来说找到自己的gcc编译器的位置,把路径放在Complier path里面就行了,我的是/usr/lib/gcc,相信大部分人都会是这样。 qt版本就选高的(如果装了好几个的话),还有可以根据自己的喜好来配置编辑的界面,(texteditor老铁没毛病)。
准备工作都做完了,好,开始之前再检查一遍。 qmake -v 检查版本最好是5以上的。 在qtcreator里写一个helloworld试试。
#include<QApplication> #include<QLabel> int main(int argc,char **argv) { QApplication a(argc,argv); QLabel *label=new QLabel("hello world"); label->setGeometry(200,200,100,100); label->show(); return a.exec(); }Ctrl+R编译运行成功,美滋滋。但是当时我却有几个很奇怪的问题,就是居然给了我数不清的warning,说我某某某文件在未来的多少秒被改动了,当时就给我看懵逼了。后来想明白了,自己的系统的时间比那个qt资源的使用时间还要早,搞了半天结果是我穿越了。。。解决办法就是改变一下系统的时间,然后把qt相关文件touch一遍。之前不明白吧能找到的命令弄了一遍,比如什么 make clean什么的,等以后回来再看我自己的行为吧。
现在开始做实验了。nanopi2(smart4418)的串口通信可以通过两个串口,一个是com0,一个是com3,这两个串口对应于安装后的debian系统来说,分别是设备文件/dev/ttyAMA0和/dev/ttyAMA2。 一般来说,com0用于连接pc端系统的超级终端,比如win上的serialctr,linux的minicom。com3用来传输信息,当然这也不是绝对的。 首先,把rs232接口接在开发板com3上,然后用rs232转usb接在电脑上。 这里我是用win做的测试,下载一个serial port utility的软件,是串口通信的调试软件。配置好连接自己的开发板,com口不一定是com3,要在设备管理器里查看。这个可以通过数据线发信息给开发板。 下面有一个测试的代码(某位好心人的代码)
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <termios.h> int main() { int fd = -1; fd = open("/dev/ttyAMA2", O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) { perror("Open Serial Port Error!\n"); return -1; } struct termios options; tcgetattr(fd, &options); //115200, 8N1 options.c_cflag = B115200 | CS8 | CLOCAL | CREAD; options.c_iflag = IGNPAR; options.c_oflag = 0; options.c_lflag = 0; options.c_cc[VTIME]=0; options.c_cc[VMIN]=1; tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &options); unsigned char rx_buffer[256]; while(1){ int rx_length = read(fd, (void*)rx_buffer, 255); if (rx_length > 0) { //Bytes received rx_buffer[rx_length] = '\0'; printf("%i bytes read : %s\n", rx_length, rx_buffer); } } close(fd); return 0; }在开发板上编译运行,就可以接受到来自win上的串口调试助手发来的信息。相当的好用,没有写代码,但是已经几乎把代码的原理弄完了,就是文件的读写,大一时的C语言的最后的fopen,fread,fwrite,fclose几个类似函数的应用。
下面说QT的代码,其实看到这里很多人大概已经知道该怎么做了。
新建工程取名SerialPort,选择Widget application,然后默认就好了。 因为要做串口通信的实验,所以这个时候要利用QT5已经有的函数包,加入头文件
#include<QtSerialPort/QSerialPort>如果没有这个文件,那么可能下载了残缺的qt5资源包
sudo apt-get install libqt5serialport5-dev然后再在.pro文件内加上QT+=serialport 紧接着就可以开始搭建自己想要的界面了,利用ui,什么编辑框,按钮什么的,我的比较简单。
然后就往里面添代码。右键两个按钮,会有一个跳到槽,自动构建方法,往里面添代码就好了。 然后再widget.h中的类里面添加成员变量,和一个方法
private: QSerialPort serial; bool flag; //这个可用可不用 private slots: void read_Com();然后要初始化自己的串口信息,以及一些变量的初始值,在构造函数里面添加
flag=false; serial.setPortName("/dev/ttyAMA2"); serial.setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections); serial.setDateBit(QSerialPort::Data8); serial.setFlowControl(QSerialPort::NoFlowControl); serial.setParity(QSerialPort::NoParity); serial.setStopBits(QSerialPort::OneSteo);为什么我不加注释呢?因为这些都是在配置端口的时候的信息,不管是minicom,serialctr,还是调试助手,都会看到不止一遍。 然后添加open的按钮响应事件的代码。
if(!flag) { serial.close(); if(serial.open(QIODevice::ReadWrite)) { connect(&serial,SIGNAL(readyRead()),this,SLOT(read_Com())); } ui->openport->setText("CLOSE"); flag=true; } else { serial.close(); flag=false; ui->openport->setText("OPEN"); }这里要对read_Com()进行解释,这个是读取串口文件内容,并显示到resvText的一个函数
void Widget::read_Com() { QByteArray temp=serial.read(2); if(!temp.isEmpty()) { ui->resvtext->insertPlainText(temp); ui->resvtext->insertPlainText("\n"); } } void Widget::on_sendmes_clicked() { serial.write(ui->textEdit->toPlainText().toLatin1()); }到这里,代码已经写完了,我这边测试运行是没有问题的,附上运行的图片
实验很小,但是做的很开心,总结的也很开心,希望一直会这样,多年以后再回来看到自己写的东西不知会怎么样。