MicroMV SPI通信
502748957@qq.com(讨论 | 贡献)2018年12月7日 (五) 03:11的版本
MicroMV上的SPI通讯
- 做为SPI主机
# SPI Control # # This example shows how to use the SPI bus on your OpenMV Cam to directly # the LCD shield without using the built-in lcd shield driver. You will need # the LCD shield to run this example. import sensor, image, time from pyb import Pin, SPI cs = Pin("P8", Pin.OUT_PP) cs.high() # The hardware SPI bus for your OpenMV Cam is always SPI bus 2. spi = SPI(2, SPI.MASTER, baudrate=int(1000000000/66), polarity=0, phase=0) def write_command_byte(c): cs.low() rs.low() spi.send(c) cs.high() def write_data_byte(c): cs.low() rs.high() spi.send(c) cs.high() def write_command(c, *data): write_command_byte(c) if data: for d in data: write_data_byte(d) def write_image(img): cs.low() rs.high() spi.send(img) cs.high() # Reset the LCD. rst.low() time.sleep(100) rst.high() time.sleep(100) write_command(0x11) # Sleep Exit time.sleep(120) # Memory Data Access Control write_command(0x36, 0xC0) # Interface Pixel Format write_command(0x3A, 0x05) # Display On write_command(0x29) sensor.reset() # Initialize the camera sensor. sensor.set_pixformat(sensor.RGB565) # must be this sensor.set_framesize(sensor.QQVGA2) # must be this sensor.skip_frames(time = 2000) # Let new settings take affect. clock = time.clock() # Tracks FPS. while(True): clock.tick() # Track elapsed milliseconds between snapshots(). img = sensor.snapshot() # Take a picture and return the image. write_command(0x2C) # Write image command... write_image(img) print(clock.fps()) # Note: Your OpenMV Cam runs about half as fast while # connected to your computer. The FPS should increase once disconnected.
- 做为SPI从机
# SPI with the Arduino as the master device and the OpenMV Cam as the slave. # # Please wire up your OpenMV Cam to your Arduino like this: # # OpenMV Cam Master Out Slave In (P0) - Arduino Uno MOSI (11) # OpenMV Cam Master In Slave Out (P1) - Arduino Uno MISO (12) # OpenMV Cam Serial Clock (P2) - Arduino Uno SCK (13) # OpenMV Cam Slave Select (P3) - Arduino Uno SS (10) # OpenMV Cam Ground - Arduino Ground import pyb, ustruct text = "Hello World!\n" data = ustruct.pack("<bi%ds" % len(text), 85, len(text), text) # 85 is a sync char. # Use "ustruct" to build data packets to send. # "<" puts the data in the struct in little endian order. # "b" puts a signed char in the data stream. # "i" puts a signed integer in the data stream. # "%ds" puts a string in the data stream. E.g. "13s" for "Hello World!\n" (13 chars). # See https://docs.python.org/3/library/struct.html # Zero pad data to a multiple of 4 bytes plus 4 bytes. data += "\x00" * (4 + (len(data) % 4)) # READ ME!!! # # Please understand that when your OpenMV Cam is not the SPI master it may miss responding to # sending data as a SPI slave no matter if you call "spi.send()" in an interrupt callback or in the # main loop below. Because of this you must absolutely design your communications protocol such # that if the slave device (the OpenMV Cam) doesn't call "spi.send()" in time that garbage data # read from the SPI peripheral by the master (the Arduino) is tossed. To accomplish this we use a # sync character of 85 (binary 01010101) which the Arduino will look for as the first byte read. # If it doesn't see this then it aborts the SPI transaction and will try again. Second, in order to # clear out the SPI peripheral state we always send a multiple of four bytes and an extra four zero # bytes to make sure that the SPI peripheral doesn't hold any stale data which could be 85. Note # that the OpenMV Cam will miss the "spi.send()" window randomly because it has to service # interrupts. Interrupts will happen a lot more while connected to your PC. # The hardware SPI bus for your OpenMV Cam is always SPI bus 2. # polarity = 0 -> clock is idle low. # phase = 0 -> sample data on rising clock edge, output data on falling clock edge. spi = pyb.SPI(2, pyb.SPI.SLAVE, polarity=0, phase=0) pin = pyb.Pin("P3", pyb.Pin.IN, pull=pyb.Pin.PULL_UP) print("Waiting for Arduino...") # Note that for sync up to work correctly the OpenMV Cam must be running this script before the # Arduino starts to poll the OpenMV Cam for data. Otherwise the SPI byte framing gets messed up, # and etc. So, keep the Arduino in reset until the OpenMV Cam is "Waiting for Arduino...". while(True): while(pin.value()): pass try: spi.send(data, timeout=1000) # If we failed to sync up the first time we'll sync up the next time. print("Sent Data!") # Only reached on no error. except OSError as err: pass # Don't care about errors - so pass. # Note that there are 3 possible errors. A timeout error, a general purpose error, or # a busy error. The error codes are 116, 5, 16 respectively for "err.arg[0]". while(not pin.value()): pass ################################################################################################### # Arduino Code ################################################################################################### # # #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 temp = 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(&temp, 4); // get length # int zero_legnth = 4 + ((temp + 1) % 4); # if (temp) { # SPI.transfer(&buff, min(temp, CHAR_BUF)); # temp -= min(temp, CHAR_BUF); # } # while (temp--) SPI.transfer(0); // eat any remaining bytes # while (zero_legnth--) SPI.transfer(0); // eat zeros. # } # # digitalWrite(SS_PIN, HIGH); # Serial.print(buff); # delay(1); // Don't loop to quickly. # }