TI-MSPM0G3507外设使用,UART通信OPENMV视觉模块

写在前面

备战2024电赛,使用到了TI开发板,型号MSPM0G3507,该开发板除文档外,网上资料稀少。
现在为大家提供uart通信openmv视觉模块的代码,以促共同进步。
该代码由本人编写,转载请标明来源。
代码亲测成功,如有bug欢迎评论区指正。

头文件

openmv.h

#ifndef OPENMV_H
#define OPENMV_H
#include "../COMMON.h"

#define SELF_CHECK_CMD 0x1A
#define STOP_CMD 0x1C
#define TIME_OUT 0xFF
#define END1 0x01
#define END2 0xFE
#define END3 0xFF

uint8_t openmv_init();
void openmv_cmd(uint8_t cmd , uint8_t (*func)(uint8_t*));
float openmv_parse_float(uint8_t* data,uint8_t* index);
int openmv_parse_int(uint8_t* data, uint8_t* index);
const char* openmv_parse_string(uint8_t* data, uint8_t* index);
uint8_t openmv_parse_byte(uint8_t* data, uint8_t* index);

#define OMB(d,i) openmv_parse_byte((data),&(i))
#define OMF(d,i) openmv_parse_float((data),&(i))
#define OMI(d,i) openmv_parse_int((data),&(i))
#define OMS(d,i) openmv_parse_string((data),&(i))

#endif

源文件

#include "OpenMv.h"

uint8_t openmv_init(){
    DL_UART_transmitData(OPENMV_INST,SELF_CHECK_CMD);
    while (DL_UART_isBusy(OPENMV_INST));
    system_delay_ms(100);
    uint8_t data = 0;
    uint8_t time = 0;
    while (data != 0x1B) {
        if(time++ >= TIME_OUT)return 0;
        data = DL_UART_receiveDataBlocking(OPENMV_INST);
    }
    return 1;
}

void openmv_cmd(uint8_t cmd , uint8_t (*func)(uint8_t*)){
    DL_UART_transmitData(OPENMV_INST,cmd);
    while (DL_UART_isBusy(OPENMV_INST));
    system_delay_ms(100);
    uint8_t loop_flag = 1;
    uint8_t data[128];
    while (loop_flag){
        DL_UART_receiveDataBlocking(OPENMV_INST);
        uint8_t temp = DL_UART_receiveDataBlocking(OPENMV_INST);
        uint8_t last_temp = 0;
        uint8_t last_last_temp = 0;
        uint8_t i = 0;
        while (!(temp==END3&&last_temp==END2&&last_last_temp==END1)){
            data[i++] = temp;
            last_last_temp = last_temp;
            last_temp = temp;
            temp = DL_UART_receiveDataBlocking(OPENMV_INST);
        }
        loop_flag = func(data);
        system_delay_ms(50);
    } 
    DL_UART_transmitData(OPENMV_INST,STOP_CMD);
    while (DL_UART_isBusy(OPENMV_INST));
    system_delay_ms(100);
}
int openmv_parse_int(uint8_t* data, uint8_t* index) {
    int i = (int)(
        ((int32_t)data[*index]) |
        ((int32_t)data[*index + 1] << 8) |
        ((int32_t)data[*index + 2] << 16) |
        ((int32_t)data[*index + 3] << 24)
    );
    *index +=4;
    return i;
}
float openmv_parse_float(uint8_t* data,uint8_t* index){
    union {
        uint32_t i;
        float f;
    } u;

    u.i = ((uint32_t)data[*index]) |
          ((uint32_t)data[*index + 1] << 8) |
          ((uint32_t)data[*index + 2] << 16) |
          ((uint32_t)data[*index + 3] << 24);
    *index +=4;
    return u.f;
}
const char* openmv_parse_string(uint8_t* data, uint8_t* index) {
    const char* str = (const char*)(data + *index);
    uint8_t length = 0;
    while (data[*index + length] != '\0') {
        length++;
    }
    *index += length + 1;
    return str;
}
uint8_t openmv_parse_byte(uint8_t* data, uint8_t* index){
    *index+=1;
    return data[*index];
}

测试代码

1.ti-mspmg3507

#include "Library/COMMON.h"
uint8_t openmv_func_tftchar(uint8_t* data){
    static uint8_t num = 0;
    uint8_t ptr = 0;
    num++;
    tft180_show_int(0, 20, OMI(data,ptr),3);
    tft180_show_string(0, 40, OMS(data, ptr));
    tft180_show_float(0, 60, OMF(data,ptr),3,3);
    tft180_show_int(0, 80, OMB(data,ptr),3);
    system_delay_ms(3000);
    tft180_clear();
    if(num==5){
        num = 0;
        return 0;
    }
    else return 1;
} 
int main(void)
{
    SYSCFG_DL_init();
    tft180_init();
    tft180_show_int(0, 0, openmv_init(),3);
    openmv_cmd(0xe0, openmv_func_tftchar);
    while (1) {
        system_delay_ms(500);
    }
}

2.openmv

import time,random,struct
from pyb import UART,LED
uart = UART(3, 19200, timeout_char=1000)

def blink(i,n,t):
    for _ in range(0,n):
        LED(i).on();
        time.sleep_ms(t);
        LED(i).off();
        time.sleep_ms(t);

def send_float(f):
    uart.write(struct.pack('f', f))

def send_int(i):
    uart.write(struct.pack('i', i))

def send_string(s):
    uart.write(s+'\0')

def send_byte(b):
    uart.write(bytes([b]))

def send_end():
    uart.write(b'\x01\xfe\xff')

tft_flag = 0
while(True):
    a = uart.readchar()
    if a == 28:
        tft_flag = 0
        blink(1, 1, 200)
    elif a == 224 or tft_flag:
        tft_flag = 1
        send_int(-255)
        send_string("Hello,World!")
        send_float(255.51)
        send_end()
    elif a == 26:
        blink(2, 3, 200)
        uart.write(bytes([0x1b]))

    time.sleep_ms(50)

配置与使用说明

配置

一个UART,命名为OPENMV
注意波特率要与openmv端的一致,上述例子中为19200

如何使用?

1.连接验证

如果你的openmv端与示例代码一致
连接好openmv与ti单片机后启动ti,若openmv端绿灯闪烁3次并且ti单片机屏幕第一行显示1说明连接成功

2.命令注册

void openmv_cmd(uint8_t cmd , uint8_t (*func)(uint8_t*))

通过此函数进行命令的注册,其作用是当openmv接收到cmd命令时,执行相应的逻辑并返回数据,func回调函数将对数据进行处理。正如定义中的参数类型所示,func将接收到数据数组,并返回一个是否应该令openmv结束当前逻辑的标志
如示例中openmv_func_tftchar便是一个func

uint8_t openmv_func_tftchar(uint8_t* data)

openmv_cmd(0xe0, openmv_func_tftchar);

以及

if(num==5){
    num = 0;
    return 0;
}
else return 1;

很显然使用者只需关注命令值,对数据执行的逻辑以及何时结束即可,而不需要关注数据传输具体的细节

3.数据发送与解析

在openmv端使用以下四个函数即可完成大部分常用数据的发送,发送后一定要发送调用send_end帧尾标记结束

def send_float(f):
    uart.write(struct.pack('f', f))

def send_int(i):
    uart.write(struct.pack('i', i))

def send_string(s):
    uart.write(s+'\0')
    
def send_byte(b):
    uart.write(bytes([b]))

def send_end():
    uart.write(b'\x01\xfe\xff')

而在ti单片机端func函数内的数据解析则可以由以下三个函数进行 (注意data不包括帧尾只包括数据)

float openmv_parse_float(uint8_t* data,uint8_t* index);
int openmv_parse_int(uint8_t* data, uint8_t* index);
const char* openmv_parse_string(uint8_t* data, uint8_t* index);
uint8_t openmv_parse_byte(uint8_t* data, uint8_t* index);

只需要关注数据发送的顺序就可以完成相应的解析,index用于获取不同类型数据块解析的起始,每次解析后将指向data数组当前数据后面的位置。
index指向的值初始为0,比如说数据类型是"string–>int–>float"
先调用openmv_parse_string,那么index指向的值就会变为字符串结束后的下一位,即int的开始,此时又可以直接调用openmv_parse_int,紧接着是openmv_parse_float,完成所有数据的接收。

后话

还请大家鼓励支持
欢迎访问个人网址
项目开源地址

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值