OpenMV与MSP432串口通信教程
openmv与msp432串口通信
根据 OpenMV与stm32,msp432等单片机的串口通讯(已经写好一个识别色块的例程,可直接使用)keil(MDK)改进。
一、首先有一个大思想的问题,举个例子就是假如msp432充当“大脑”,openmv就相当于“眼睛”,那么链接所写的就是“眼睛”一直在向“大脑”发送数据,中断会一直触发。那么我们换种思路,如果是我“大脑”发个信号之后,“眼睛”再将数据发送给“大脑”。
(利:中断触发减少,可调整数据发送速率,可主动请求数据。)
(弊:主程序占用,请求可能会被搁置,如果使用定时器的延时可以避免这个。)
二、就是他的那个代码里有一个数据的判断是错误的。
下面是openmv的代码
# Blob Detection and uart transport
import sensor, image, time
from pyb import UART
import json
import lcd
# For color tracking to work really well you should ideally be in a very, very,
# very, controlled enviroment where the lighting is constant...
yellow_threshold = (1, 17, -20, 11, -12, 17)
#记得更改要识别色块的阈值
# You may need to tweak the above settings for tracking green things...
# Select an area in the Framebuffer to copy the color settings.
sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.RGB565) # use RGB565.
sensor.set_framesize(sensor.QQVGA) # use QQVGA for speed.
sensor.skip_frames(10) # Let new settings take affect.
sensor.set_auto_whitebal(False) # turn this off.
clock = time.clock() # Tracks FPS.
lcd.init() # Initialize the lcd screen.
#lcd初始化
uart = UART(3, 115200)
uart.init(115200,bits=8,parity=None,stop=1)
#这里是UART3,115200
def find_max(blobs):
max_size=0
for blob in blobs:
if blob.pixels() > max_size:
max_blob=blob
max_size = blob.pixels()
return max_blob
#得到识别面积最大的色块
while(True):
img = sensor.snapshot() # Take a picture and return the image.
blobs = img.find_blobs([yellow_threshold])
if blobs:
max_blob=find_max(blobs)
img.draw_rectangle(max_blob.rect())
img.draw_cross(max_blob.cx(), max_blob.cy())
img.draw_string(0,0,'x='+str(max_blob.cx()),color=(0,0,0))
img.draw_string(0,10,'y='+str(max_blob.cy()),color=(0,0,0))
output_str=bytearray([0x2c,4,max_blob.cx(),max_blob.cy(),max_blob.w(),max_blob.h(),0x5B])
#output_str="[%d,%d,%d,%d]" % (max_blob.cx(),max_blob.cy(),max_blob.w(),max_blob.h()) #方式1
#output_str=json.dumps([max_blob.cx(),max_blob.cy()]) #方式2
#output_str = json.dumps(max_blob)
# print('you send:',output_str)
lcd.display(img) # Take a picture and display the image.
#将图像显示在lcd中
#else:
##print('not found!')
#print('you send:',output_str)
#output_str=bytearray([0x2c,0,0x5B])
#uart.write(output_str)
if uart.any():
a=uart.readline().decode().strip()
# b=int(a)
print(a)
if a=='x':
uart.write(output_str)
print('you send:',output_str)
a='NULL'
b=0
#加入了一个判断的条件,当主机发送'x'时,我发送数据
还有一些当时存在疑惑的地方这里解释一下
output_str=bytearray([0x2c,4,max_blob.cx(),max_blob.cy(),max_blob.w(),max_blob.h(),0x5B])
2c就相当于报头,5B相当于结尾
2c在ccs中不是16进制显示的话会是’,’ ASCII码是44
5B在ccs中不是16进制显示的话回是’[’ ASCII码是91
期中的max_blob.cx(),max_blob.cy(),max_blob.w(),max_blob.h()是最大的目标的x,y坐标,还有宽和高。
有一个.h头文件,在stm32中和msp432中都是一样的,都可以用。
#ifndef __openmv_H
#define __openmv_H
typedef struct
{
u16 cx;
u16 cy;//最大色块的中心坐标
u16 w;
u16 h;
u16 s;//最大色块的面积(在popenv ide软件上运行框起来的面积(w*h))
}_CARD;
void Openmv_Init(u32 bound);
void Openmv_Receive_Data(int16_t data);
extern _CARD CARD;
#endif
/* end of openmv.h */
(转自原作者)
还有.c文件
/******************************************************************************
* MSP432 UART - Loopback with 24MHz DCO BRCLK
*
* MCLK = HSMCLK = SMCLK = DCO of 24MHz
*
* MSP432P401
* -----------------
* | |
* RST -| P3.3/UCA0TXD|----定时发送数据请求
* | |
* -| |
* | P3.2/UCA0RXD|----接收数据,8bit*7个
* | |
* | |
*
*******************************************************************************/
/* DriverLib Includes */
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>
#include "openmv.h"
_CARD CARD={0};
uint8_t RXData = 0;
uint8_t TXData = 'x';
/* UART Configuration Parameter. These are the configuration parameters to
* make the eUSCI A UART module to operate with a 115200 baud rate. These
* values were calculated using the online calculator that TI provides
* at:
* http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html
*/
const eUSCI_UART_ConfigV1 uartConfig =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
13, // BRDIV
0, // UCxBRF
37, // UCxBRS 设置波特率为115200
EUSCI_A_UART_NO_PARITY, // No Parity
EUSCI_A_UART_LSB_FIRST, // LSB First
EUSCI_A_UART_ONE_STOP_BIT, // One stop bit
EUSCI_A_UART_MODE, // UART mode
EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION, // Oversampling
EUSCI_A_UART_8_BIT_LEN // 8 bit data length
};
void Openmv_Init(void)
{
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3,
GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
/* Configuring UART Module */
MAP_UART_initModule(EUSCI_A2_BASE, &uartConfig);
/* Setting DCO to 24MHz (upping Vcore) */
FlashCtl_setWaitState(FLASH_BANK0, 1);
FlashCtl_setWaitState(FLASH_BANK1, 1);
MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_24);
/* Enable UART module */
MAP_UART_enableModule(EUSCI_A2_BASE);
// MAP_UART_clearInterruptFlag (EUSCI_A2_BASE);
/* Enabling interrupts */
MAP_UART_enableInterrupt(EUSCI_A2_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
MAP_Interrupt_enableInterrupt(INT_EUSCIA2);
MAP_Interrupt_enableMaster();
}
void Openmv_Receive_Data(uint8_t data)//接收Openmv传过来的数据
{
static uint8_t openmv[7]; //存取数据
static uint8_t state = 0;
uint8_t i;
static uint8_t bit_number=0;
if(state==0&&data==0x2C)
{
state=1;
openmv[bit_number++]=data;
}
else if(state==1&&data==4)
{
state=2;
openmv[bit_number++]=data;
}
else if(state==2)
{
openmv[bit_number++]=data;
if(bit_number>=6)
{
state=3;
}
}
else if(state==3) //检测是否接受到结束标志
{
if(data == 0x5B)
{
state = 0;
openmv[bit_number++]=data;
CARD.cx=openmv[2];
CARD.cy=openmv[3];
CARD.w=openmv[4];
CARD.h=openmv[5];
CARD.s=openmv[4]*openmv[5];
}
else if(data != 0x5B)
{
state = 0;
for(i=0;i<=7;i++)
{
openmv[i]=0x00;
}
}
}
else
{
state = 0;
bit_number=0;
for(i=0;i<=7;i++)
{
openmv[i]=0x00;
}
}
}
//函数功能:延时
static void key_delay(uint16_t t)
{
volatile uint16_t x;
while (t--)
for (x = 0; x < 1000; x++)
;
}
int main(void)
{
/* Halting WDT */
MAP_WDT_A_holdTimer();
Openmv_Init();
while(1)
{
key_delay(1000);
MAP_UART_transmitData(EUSCI_A2_BASE, TXData);//openmv串口数据采集信号
}
}
void EUSCIA2_IRQHandler(void)
{
uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A2_BASE);
if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)
{
// RXData = MAP_UART_receiveData(EUSCI_A2_BASE);
Openmv_Receive_Data(MAP_UART_receiveData(EUSCI_A2_BASE));
}
}
错误在这里
else if(state==1&&data==4)
你可以在这里把它改为4,也可以在openmv那里改包里的数据,反正就是要相互对应。
接线的话
这就可以,记得将收发反着接。
最后还是要感谢HOUBYhcy这位大佬
小伙伴三清丨道长和隆美尔2.0辛苦了