Example: 07-Interface-Library/00-Arduino/arduino_spi_slave.py

# 本作品采用MIT许可证授权。
# 版权所有 (c) 2013-2023 OpenMV LLC。保留所有权利。
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# SPI 以 Arduino 为主设备,OpenMV Cam 为从设备。
#
# 请按如下方式将您的OpenMV Cam连接到Arduino:
#
# OpenMV Cam 主出从入 (P0) - Arduino Uno MOSI (11)
# OpenMV Cam 主入从出 (P1) - Arduino Uno MISO (12)
# OpenMV Cam 串行时钟 (P2) - Arduino Uno SCK (13)
# OpenMV Cam 从选择 (P3) - Arduino Uno SS (10)
# OpenMV Cam 地线 - Arduino 地线

import pyb
import struct
import time

text = "Hello World!\n"
data = struct.pack("<bi%ds" % len(text), 85, len(text), text)  # 85 是同步字符。
# 使用“struct”构建要发送的数据包。
# “<”将结构中的数据按小端序排列。
# "b" 在数据流中放入一个有符号字符。
# "i" 在数据流中放入一个有符号整数。
# “%ds”在数据流中放入一个字符串。例如,“13s”对应“Hello World!\n”(13个字符)。
# 参见 https://docs.python.org/3/library/struct.html

# 请阅读!!!
#
# 请理解,当您的 OpenMV Cam 不是 SPI 主设备时,它可能会错过响应
# 作为 SPI 从设备发送数据,无论您是在中断回调中还是在
# 下面的主循环中调用 "spi.send()"。因此,您必须绝对设计您的通信协议,使得
# 如果从设备(OpenMV Cam)没有及时调用 "spi.send()",则垃圾数据
# 从SPI外设读取的数据由主设备(Arduino)丢弃。为了实现这一点,我们使用
# 同步字符85(二进制01010101),Arduino会将其作为读取的第一个字节。
# 如果没有看到这个字符,它将中止SPI事务并重试。其次,为了
# 清除SPI外设状态,我们总是发送四字节的倍数,并额外发送四个零
# 字节,以确保SPI外设不会保留任何可能是85的陈旧数据。注意
# OpenMV Cam会随机错过“spi.send()”窗口,因为它需要处理
# 中断。连接到PC时,中断会频繁发生。

# 您的OpenMV Cam的硬件SPI总线始终是SPI总线2。
# 极性=0 -> 时钟空闲时为低电平。
# 相位=0 -> 在时钟上升沿采样数据,在时钟下降沿输出数据。
spi = pyb.SPI(2, pyb.SPI.SLAVE, polarity=0, phase=0)


# NSS回调。
def nss_callback(line):
    global spi, data
    try:
        spi.send(data, timeout=1000)
    except OSError as err:
        pass  # 不要在意错误 - 所以跳过。
        # 请注意,有3种可能的错误。超时错误、通用错误或
        # 忙碌错误。错误代码分别为116、5、16,对应"err.arg[0]"。


# 配置NSS/CS为IRQ模式,以便在主设备请求时发送数据。
pyb.ExtInt(pyb.Pin("P3"), pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, nss_callback)

while True:
    time.sleep_ms(1000)

###################################################################################################
# Arduino代码
###################################################################################################
#
# #include <SPI.h>
# #define SS_PIN 10
# #define BAUD_RATE 19200
# #define CHAR_BUF 128
#
# void setup() {
#   pinMode(SS_PIN, OUTPUT);
#   Serial.begin(BAUD_RATE);
#   SPI.begin();
#   SPI.setBitOrder(MSBFIRST);
#   SPI.setClockDivider(SPI_CLOCK_DIV16);
#   SPI.setDataMode(SPI_MODE0);
#   delay(1000); // Give the OpenMV Cam time to bootup.
# }
#
# void loop() {
#   int32_t len = 0;
#   char buff[CHAR_BUF] = {0};
#   digitalWrite(SS_PIN, LOW);
#   delay(1); // Give the OpenMV Cam some time to setup to send data.
#
#   if(SPI.transfer(1) == 85) { // saw sync char?
#     SPI.transfer(&len, 4); // get length
#     if (len) {
#       SPI.transfer(&buff, min(len, CHAR_BUF));
#       len -= min(len, CHAR_BUF);
#     }
#     while (len--) SPI.transfer(0); // eat any remaining bytes
#   }
#
#   digitalWrite(SS_PIN, HIGH);
#   Serial.print(buff);
#   delay(1); // Don't loop to quickly.
# }

results matching ""

    No results matching ""