板对板通信
在本实验中,您将在 Pi 4 和 HiFive 1 板之间建立基于 UART 的通信通道。
第 0 部分:设置 UART 连接(用于 TA)
在这部分,我们将通过两个 UART 通道连接 HiFive1 和 Raspberry Pi 4 板。
(请注意,此步骤将由 TA 执行。)
Pi 4 有 4 个 UART,我们将使用其中的两个(uart2 和 uart3)。在 /boot/config.txt 文件末尾添加以下行以启用 uart2 和 uart3。
dtoverlay=uart2,115200 dtoverlay=uart3,115200
重启系统后,会创建/dev/ttyAMA1和/dev/ttyAMA2。
图>将 HiFive 的 UART1 RX(引脚 7)连接到 Raspberry Pi 4 的 UART2 TX(引脚 27)。这是 Pi 4 和 HiFive1 之间的主要通信线路。在 Pi 4 上,您可以通过 /dev/ttyAMA1 访问该频道。
为了调试 HiFive 1,将 HiFive1 的 UART0 TX(pin1)连接到 Pi 4 的 UART3 RX(pin 29)。从 Pi 4,它可以通过 /dev/ttyAMA2 访问。
总之,您将能够从 Pi 4 访问以下两个文件。
/dev/ttyAMA1 Pi 4 → HiFive1:将转向角发送到 HiFive1 (uart1)。
/dev/ttyAMA2 HiFive1 → Pi 4:接收 HiFive1 的控制台 (uart0) 输出
第 1 部分:编程 HiFive1
在实验室的这一部分中,您将对 HiFive1 进行编程以接收来自 Pi 4 的数据。
在您的电脑上 (不是Pi 4),下载项目骨架如下。
$ cd ~/Documents/PlatformIO
$ wget https://ittc.ku.edu/~heechul/courses/eecs388/l10-comm.tar.gz
$ tar zxvf l10-comm.tar.gz
将 l10-interrupt 文件夹添加到 VSCode 工作区。
您的任务是从 HiFive1 的 UART1 通道接收数据并将接收到的数据发送到 UART0 通道。下面是一个粗略的伪代码 任务。
而 (1) {
如果(UART1 准备好了吗?){ 数据 =从 UART1 读取。将数据打印到 UART0。
}
要实现该任务,您可能需要使用提供的串行 API,如下所示。注意devid是0访问UART0,1访问UART1。
void ser_setup(int devid); int ser_isready(int devid);
void ser_write(int devid, char c);
void ser_printline(int devid, char *str); char ser_read(int devid);
int ser_readline(int devid, int n, char *str);
特别是,您可能需要使用 ser_isready() 函数来检查给定的 UART 通道是否有待读取的数据。为了更好地理解这些函数在做什么,请检查 eecs388_lib.h 和 eecs388_lib.c 文件。
int ser_isready(int devid)
{
uint32_t regval =*(volatile uint32_t *)(UART_ADDR(devid) + UART_IP);返回正则;
}
完成对 HiFive1 的编程后,切换到 Raspberry Pi 4 并打开两个终端:一个用于向HiFive1发送数据,一个用于查看HiFive1输出的调试信息。
发送方终端(term1)
$ 屏幕 /dev/ttyAMA1 115200
调试终端(term2)
$ 屏幕 /dev/ttyAMA2 115200
现在,在“term1”上输入任何字符串。
如果您对 HiFive 1 进行了正确编程,您应该会看到从“term2”终端发出的消息。
第 2 部分:对 Raspberry Pi 4 进行编程。
您现在无需使用终端,而是在 Pi 4 上运行 Python 程序与 HiFive1 进行通信。您的任务是扩展上一个实验中的 dnn.py,以便能够将转向输出发送到 /dev/ttyAMA1 串行通道。以下伪代码 提供了您需要对 dnn.py 进行的修改的总体思路:
打开与 /dev/ttyAMA1 和 /dev/ttyAMA2 的串行连接,同时为 True:
图像 =camera.read()
角度 =dnn_inference(image) 将“角度”写入 /dev/ttyAMA1 Wait_till_next_period()
关闭串行连接
要实现上述功能,您需要使用 Python 的 pySerial API,它可以通过导入串行包来使用:
导入序列
有了它,您应该创建两个单独的串行通道,一个用于写入 HiFive1 上
/dev/ttyAMA1 和另一个用于调试 /dev/ttyAMA2。注意两个通道都要以115200 bps的波特率打开。
ser1 =serial.Serial(…) ser2 =serial.Serial(…)
然后可以使用串行 write() 函数将在处理帧时从 DNN 接收到的角度发送到 HiFive1:
ser1.write(…)
但是,write() 需要一个字节值,而 DNN 生成的角度是一个 float32 值,因此您必须转换角度数据才能将其发送到 HiFive1。最后,在处理完所有帧后,可以通过调用串行 close() 函数来关闭串行连接:
ser1.close() ser2.close()
附录
Pi 4 的 GPIO 映射。
树莓派 4 引脚
Raspberry Pi 4 不仅具有新的硬件功能,而且在引擎盖下还有一些额外的 GPIO 功能,使生活更轻松,允许用户将外围设备扩展到他们的项目,而无需额外的硬件,特别是有一堆额外的I2C、UART和SPI接口,可用于Raspberry Pi 4。
GPIO 引脚
您可以在 Raspberry PI 4 本身上找到完整的 GPIO 引脚列表,只需转到命令行并输入pinout .
图>以下是所有新的 Raspberry Pi 4 额外引脚功能的列表:
图>GPIO – 通用输入输出引脚
这些数字引脚可以编程为接收数字输入或输出数字信号。 Raspberry Pi 在每个 GPIO 引脚上使用 3V3 逻辑,这意味着 3V3 是数字 1(ON),0V 是数字 0(OFF)。因此,您可以将数字组件连接到树莓派,并为其提供 3V3 (ON) 信号或接收电流不超过 16mA 的 3V3 数字信号。
I2C – 内部集成电路
这是设备之间相当常见的通信类型,它通过主设备和从设备进行工作。在这种情况下,主设备是 Raspberry Pi 本身,从设备是硬件外围设备,通常可以扩展项目的功能。 I2C 的优点在于您可以使用相同的两线接口将数百个设备连接到同一个主设备,前提是每个设备都有不同的 I2C 地址。您可以使用以下linux命令访问该界面并查看哪些设备已连接:
须藤 i2cdetect -y 1
其中“1”是主接口。 Raspberry Pi 4 总共有 6 个。
图>SPI – 串行外设接口
SPI 是另一种用于设备间通信的通信协议。它还使用主/从设置,但主要用于主(主)控制器和外围设备(从)之间的短距离,例如传感器。 SPI 通常使用 3 线与树莓派通信; SCLK、MOSI 和 MISO。在使用 SPI 之前,您需要在 Raspberry Pi 配置菜单中启用它:
图>UART – 通用异步接收器/发送器
与 I2c 和 SPI 不同,UART 不是协议。 UART (Serial) 是一种物理电路,用于传输和接收串行数据。 UART 不需要时钟信号,因此它是异步的。这最大限度地减少了发送和接收数据所需的电线,但它也需要一些额外的数据与数据包一起发送以进行错误检查,例如起始位和停止位。通常关于 Raspberry Pi UART 用于无头设置,这意味着没有 GUI 或其他界面。相反,您可以将 Raspberry Pi 连接到您的台式机/笔记本电脑或其他设备,并使用命令行界面通过 UART 与其进行通信。此方法适用于更高级的用户,因为它需要更多的知识来设置它。
另一个在 Raspberry Pi 用户中很常见的应用是将 Arduino UNO 板连接到 Raspberry Pi,因为 Pi 的模拟功能有限。
制造工艺