树莓派+Pixhawk之二:通过串口0建立连接

树莓派3B+和Pixhawk 2.4.8的连接 —— 使用 serial0
树莓派+Pixhawk之二:通过串口0建立连接_第1张图片
树莓派管脚定义图
树莓派+Pixhawk之二:通过串口0建立连接_第2张图片
查看树莓派的系统版本

cat /proc/version

显示

Linux version 4.14.79-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1159 SMP Sun Nov 4 17:50:20 GMT 2018

查看串口的对应关系

ls -l /dev/serial*

可以看到设备的映射关系

lrwxrwxrwx 1 root root 7 2月  16 12:58 /dev/serial0 -> ttyS0
lrwxrwxrwx 1 root root 5 2月  16 12:58 /dev/serial1 -> ttyAMA0

根据树莓派官方文档的描述,

树莓派上使用的SoCs有两个内置UART,一个是PL011,一个是mini UART。它们是使用不同的硬件块实现的,因此它们具有稍微不同的特征。然而,两者都是3.3V的设备,这意味着当连接到RS232或其他使用不同电压水平的系统时必须格外小心。…
默认情况下,在安装了无线/蓝牙模块(Raspberry Pi 3和Raspberry Pi Zero W)的树莓派上,PL011 UART与蓝牙模块相连,而mini UART则是主要的UART,上面有一个Linux控制台。在所有其他型号上,PL011被用作主要的UART。
在Linux设备术语中,默认情况下,/dev/ttyS0表示迷你UART,而/dev/ttyAMA0表示PL011。主要的UART是分配给Linux控制台的UART,它依赖于上面描述的树莓派模型。还有符号链接:/dev/serial0,它总是引用主要的UART(如果启用);/dev/serial1,它同样总是引用次要的UART(如果启用)。

但这个mini UART有点复杂

mini UART的波特率与VC4 GPU上的VPU的核心频率有关。这意味着,当VPU调频器改变核心频率时,UART的波特率也会发生变化。这使得UART在默认状态下只能有限使用。默认情况下,如果选择mini UART作为主要的UART,它将被禁用。要启用它,请将enable_uart=1添加到/root/config.txt。这也将固定核心频率到250MHz(除非设置force_turbo,当它将固定到VPU turbo频率)。当迷你UART不是主要的UART时,例如您使用它来连接蓝牙控制器,您必须向config添加core_freq=250到conifg.txt,否则迷你UART将无法工作。

最新的Raspbian提供一个补丁,把蓝牙映射到mini UART,而让GPIO 14和GPIO 15管脚作为串口0的收发管脚。
执行

sudo nano /boot/config.txt

把下面内容添加进去即可。

enable_uart=1

dtoverlay=pi3-miniuart-bt
force_turbo=1

还要保证串口不被作为启动的控制台

sudo nano /boot/cmdline.txt

内容为

dwc_otg.lpm_enable=0  console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repai$

即保证和串口相关的定义都删除掉。
然后重启

sudo reboot

查看串口的属性

stty -F /dev/ttyAMA0 -a  #ttyS0为要查看的串口
#默认波特率是9600
stty -F /dev/ttyAMA0 ispeed 115200 ospeed 115200 cs8 # 可以用stty设置串口参数

设置了波特率,打开测试

echo "This is from RaspBerry Pi"  > /dev/ttyAMA0 | cat /dev/ttyAMA0

在PC上测试时,连接线不能太长,否则会出妖蛾子。

有可能串口被占用,用pi打开的时候报Permission Denied,删掉相关服务

sudo systemctl stop [email protected]
sudo systemctl disable [email protected]
sudo systemctl stop [email protected]
sudo systemctl disable [email protected]

写个基本的测试,参考的是
https://blog.csdn.net/qq_33479881/article/details/83540738
的代码。不知道为什么,我的板子上wiringSerial库不好使。

//////////////////////serial_test.cpp////////////////////////////
 
#include 
#include 
#include 
#include 
#include 
#include  
#include 
#include 
using namespace std;

//Open Port & Set Port
int SerialInit(const char* device,speed_t baud) {

	int fd = open(device, O_RDWR|O_NOCTTY|O_NDELAY);

	if(-1 == fd) {
		cerr << "Open Serial Port Error!" << endl; 
		return -1;
	}

	if( (fcntl(fd, F_SETFL, 0)) < 0 ) {
		cerr << "Fcntl F_SETFL Error!" << endl;
		close(fd);
		return -1;
	}
	termios stNew, stOld;
	if(tcgetattr(fd, &stOld) != 0) {
		cerr << "tcgetattr error!" << endl;
		close(fd);
		return -1; 
	} 
	stNew = stOld;
	cfmakeraw(&stNew); 
	
	//set speed
	cfsetispeed(&stNew, baud); 
	cfsetospeed(&stNew, baud); 

	//set databits
	stNew.c_cflag |= (CLOCAL|CREAD);
	stNew.c_cflag &= ~CSIZE;
	stNew.c_cflag |= CS8;
	
	//set parity
	stNew.c_cflag &= ~PARENB;
	stNew.c_iflag &= ~INPCK;

	//set stopbits
	stNew.c_cflag &= ~CSTOPB;
	stNew.c_cc[VTIME]=0;// 
	stNew.c_cc[VMIN]=1;//  

	tcflush(fd,TCIFLUSH);// 
	if( tcsetattr(fd,TCSANOW,&stNew) != 0 ) {
		cerr << "tcsetattr Error!" << endl;
		close(fd);
		return -1;

	}
	return fd;
} 

int main(int argc, char **argv) { 
	int fd = SerialInit("/dev/ttyAMA0",/*B921600 */ B115200);
	if( -1 == fd ) {
		cerr << "SerialInit Error!" << endl; 
		return 1;
	} 
	const char* sendmsg = "This is from RaspberryPi!\n";
	int len = strlen(sendmsg); 
	write(fd,sendmsg,len); 
	cout <<  sendmsg << endl;
	char buffer[100];
	while(1) {
		usleep(20000);  
		int bytes = read(fd, buffer, 100);
		if(-1 == bytes) {
			cerr << "Read Data Error!" << endl;
			break;
		}
		if(0 < bytes) {
			buffer[bytes] = 0;
			cout << "Recv Data: " <<  buffer << endl;

		}
	}
	close(fd);
	return 0;
} 

编译执行

g++ serial_test.cpp -o serial_test

在电脑上能收发信息了,下一步和飞控通讯。

你可能感兴趣的:(硬件平台)