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辛苦了

物联沃分享整理
物联沃-IOTWORD物联网 » OpenMV与MSP432串口通信教程

发表评论