本文主要介绍了在树莓派的CM3+的平台上实现gpio接口的复用功能的方法。以gpio32和gpio33实现uart1的功能为例。以及在gpio14和gpio15上面实现uart0的方法。
硬件平台:raspberrypi CM3+(bcm2837)
系统:2019-09-26-raspbian-buster-full
根据树莓派的官方文档的CM3+的datasheet得知gpio32和gpio33引脚是既可以作为uart0也可以作为uart1功能的:
本文主要实现的是将这两个gpio口实现为ALT5,也就是TXD1和RXD1功能。
通过修改树莓派的股票GPU解析的设备数文件:dt-blob-disp1-cam2.dts
文件的下载地址:https://www.raspberrypi.org/documentation/hardware/computemodule/cmio-display.md
dts文件的修改如下:
然后在系统使用dtc工具编译GPU解析的文件dt-blob.bin文件:
dtc -I dts -O dtb -o dt-blob.bin dt-blob-disp1-cam2.dts
将生成的dt-blob.bin文件复制到/boot目录下。
参考:https://www.raspberrypi.org/forums/viewtopic.php?p=1442712
在/boot/cmdline.txt文件中加入:8250.nr_uarts=1
在树莓派系统中的sudo raspi-config中打开enable serial 配置后。
重启后的设备节点:
增加了ttyS0设备节点以及serial1。
执行时串口会 打开失败:
继续参考:https://github.com/agherzan/meta-raspberrypi/issues/400
在/boot/config.txt文件中加入如下的内容:
enable_uart=1
disable_splash=1
#disable_fw_kms_setup=1
dioverlay=pi3-disable-bt
dtparam=uart1=on
core_freq=250
#dtoverlay=mini-uart1
dtoverlay=uart1,txd1_pin=32,rxd1_pin=33
加入上述内容后,reboot后,可以正常的通过pin32和pin33引脚的uart1的设备节点ttyS0传输数据。
树莓派系统中默认的uart0的引脚死14和15。然而,uart0串口也可以是32和33两个引脚,如下:
如果想通过操作/dev/ttyAMA0设备节点操作其他引脚的uart0,那么可以修改如下内容,将uart0的引脚由之前的14和15修改为32和33。
修改dts文件dt-blob-disp1-cam2.dts如下:
然后在应用软件中打开ttyAMA0.可以正常打开串口设备。
以下是在树莓派系统中使用ttyAMA0和ttyS0的基于qt 串口测试代码
#if 1
QSerialPort serial0;
//设置串口名
serial0.setPortName("ttyAMA0");//ttyAMA0
//serial0.setPortName("ttyS0");//ttyS0
//设置波特率
serial0.setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);
//设置数据位数
serial0.setDataBits(QSerialPort::Data8);
//设置奇偶校验
serial0.setParity(QSerialPort::NoParity);
//设置停止位
serial0.setStopBits(QSerialPort::OneStop);
//设置流控制
serial0.setFlowControl(QSerialPort::NoFlowControl);
//打开串口
if(!serial0.open(QIODevice::ReadWrite))
{
std::cout << "serial port ttyAMA0 open failed" << std::endl;
return -1;
}
char serial0_tx_buff[10] = {0,1,2,3,4,5,6,7,8,9};
int ret = serial0.write(serial0_tx_buff, sizeof(serial0_tx_buff));
int ret1 = serial0.waitForBytesWritten(1000);
char serial0_rx_buff[50] = {0};
//usleep(10000);
int serial0_rx_len = serial0.read(serial0_rx_buff, sizeof(serial0_rx_buff));
if(serial0_rx_len > 0){
printf("read data: serial0_rx_len %d ", serial0_rx_len);
for(int i = 0; i < serial0_rx_len; i++){
printf("%02x ", serial0_rx_buff[i]);
}
printf("\n");
}
#endif
值得注意的是默认情况下,引脚14和15是串口0(/dev/serial0)的,但是这个串口是
根据树莓派官方文档得知,serial0在系统中也可以作为系统的串口终端控制,在/boot/cmdline.txt中加入
tty=serial0,115200然后重启即可。如果想使用这个串口和其他设备通信的话,必须将删除这段内容。否则,这个串口使用的时候很不稳定,开始几秒钟能传输正常,后面就会传输就会有问题。