关于OPENMV的串口传输简单的数据其实,官网上有具体的操作流程。但是官网上面的单个字符传输数据,有时候满足不了我们日常的项目要求。比如说自动泊车、智能送药小车、板球等等需要多个标志位和相关巡线,找色块等等复杂多个功能、多个标志位之时一个字符的简单串口收发就很明显不够用了。 这个时候就需要增加位数了,来达到一次数据发送,就可以实现多个功能的利用。
以下是OPENMV端的相关代码:
import pyb, sensor, image, math, time
from pyb import UART
from pyb import LED
import ustruct
import json
sensor.reset() #初始化
sensor.set_pixformat(sensor.RGB565)#565彩图 sensor.GRAYSCALE灰度图
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 10)
sensor.set_hmirror(True)
sensor.set_vflip(True)
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False)#关闭白平衡
recv_data=str(0)
uart = UART(3, 115200)
uart.init(115200, bits=8, parity=None, stop=1)
clock = time.clock() #跟踪FPS帧率
roi1 =[
(2,45,158,19),
(6,96,27,24),
(127,90,33,28),
(27,30,93,37)
]
#roil感兴区域
THRESHOLD =[(0, 70, 28, 127, -128, 127),
(0, 27, -128, 9, -128, 127)
] #阈值
def Uart_recv(): # 串口接收数据
if uart.any(): # 更新串口接收数据
recv_data = eval(str(uart.read())) #接收读取的字符串
#b=hex(recv_data[1])
#b=int(b)
#print(b)
while(True):
Uart_recv()
clock.tick() # 追踪两个snapshots()之间经过的毫秒数.
img = sensor.snapshot()#将捕获的图片存于IMG
data = bytearray([0,0x0d,0x0a])
uart.write(data)
下面就详细讲解一下相关的函数以及其作用:
uart = UART(3, 115200) #设置OPENMV端的串口3,其P4为TX,P5为RX,设置串口通信的波特率为115200,这个不管 和什么其他什么型号的单片机通信,通信的两端都必须保证波特率是一样的,这样才能保证能够通信。
uart.init(115200, bits=8, parity=None, stop=1) #串口初始化 ,波特率为115200, 一次发送8位, 没有奇偶效验位,一位停止位。
当你的OPENMV端在你所需要的程序中写下这两段代码后,你OPENMV端串口发送数据的所有准备工作就已经完成了。剩下的你只需要将你要发送的数据放入data这个数组中。
data=bytearray([0,0x0d,0x0a]) 首先解释一下,bytearray()这个函数的具体用法和意义,它是将()中的数组,存为一个8位的数组,也就是当你需要发送的数据时,不够8位,但是你初始化设置了8位,这时它就起作用了,着你的数组后面补齐8位。(也就是简单的一句话,不够8位补齐,多余8位报错)还有一个值得注意的就是他只能法int类型的数据,最大为256.也就是当你数据出现float、double、char它都会报错。当你无意间获得了不是int类型的变量x你就需要将其强制转化为int类型,具体操作如下:data=bytearray([int(x),0x0d,0x0a])
最后说一下为什么要加0X0d和0x0a,这个是为了在32端或者m0等等你需要发送数据的一段去检验你的数据有没有发错。其实最主要的不是说防止错发,而是串行,也就是你收到的数据帧有上一段和本段的,这样你就检测不出来你受到的数据有没有问题。
这个时候就体现出了0x0a和0X0d的重要性,这个的用处就是在你解包的时候,判断第七位和第八位是否为0x0a和0X0d,如果是的,那么你所解包的这个数据就是对的,就能够利用,如果不这个,就说明你解包的数据有问题,也就“不是正确的”(只是对你你当前的用法,以及每位数据对应不上)就把他丢弃,不进行处理。
当这些准备工作做完了之后你就可以,开始测试你的数据能否发出来了,你可以打开你串口助手。我这里用的是xcom,也就是以下用的这个界面。
首先选择你设置的波特率,其次找到你对应的串口。然后看有没有数据传输过来。如果有数据传输过来你就可以进行 下一步了。(没有的话再检查一下rx、tx有没有接错口,或者有没有共地、波特率是不是一致的、你的com口是否选择正确)
以下是MSPG3507端接收数据的程序:
#include "usart.h"
#include <ti/driverlib/m0p/dl_interrupt.h>
#include <ti/driverlib/dl_uart_main.h>
#include <ti/driverlib/dl_uart.h>
int a;
void Usart_A0_Init(void)
{
NVIC_EnableIRQ(UART0_INT_IRQn);
}
uint8_t USART_RX_BUF[USART_REC_LEN]; //½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.
//½ÓÊÕ״̬
//bit15£¬ ½ÓÊÕÍê³É±êÖ¾
//bit14£¬ ½ÓÊÕµ½0x0d
//bit13~0£¬ ½ÓÊÕµ½µÄÓÐЧ×Ö½ÚÊýÄ¿
uint16_t USART_RX_STA=0;
void UART0_IRQHandler(void)
{
uint8_t Res;
switch (DL_UART_Main_getPendingInterrupt(UART0)) //½ÓÊÕÖжÏ(½ÓÊÕµ½µÄÊý¾Ý±ØÐëÊÇ0x0d 0x0a½áβ)
{ case DL_UART_MAIN_IIDX_RX:
Res =DL_UART_Main_receiveData(UART0);//(USART1->DR); //¶ÁÈ¡½ÓÊÕµ½µÄÊý¾Ý
if((USART_RX_STA&0x8000)==0)//½ÓÊÕδÍê³É
{
if(USART_RX_STA&0x4000)//½ÓÊÕµ½ÁË0x0d
{
if(Res!=0x0a)USART_RX_STA=0;//½ÓÊÕ´íÎó,ÖØпªÊ¼
else USART_RX_STA|=0x8000; //½ÓÊÕÍê³ÉÁË
}
else //»¹Ã»ÊÕµ½0X0D
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//½ÓÊÕÊý¾Ý´íÎó,ÖØпªÊ¼½ÓÊÕ
}
}
if(USART_RX_STA&0x8000){USART_RX_STA=0;}
}
break;
default:
break;
}
}
这里与上0x8000是为了判断你接受的数据帧,这个打包发过来的数据你有没有接收完毕。其他的就没有必要细讲了。
以下是STM32F407的串口接收程序,只不过这里判断条件要修改成为:帧头0X2c、0x12,帧尾为0x5d(OPENMV端)。
#include "sys.h"
#include "usart.h"
#include "led.h"
#include "pwm.h"
#include "oled.h"
static u8 Cx=0,Cy=0,Cw=0,Ch=0;
int x,h,w;
int y;
int biaozhi=0;
//
//Èç¹ûʹÓÃucos,Ôò°üÀ¨ÏÂÃæµÄÍ·Îļþ¼´¿É.
#if SYSTEM_SUPPORT_OS
#include "includes.h" //ucos ʹÓÃ
#endif
#if 1
#pragma import(__use_no_semihosting)
//±ê×¼¿âÐèÒªµÄÖ§³Öº¯Êý
struct __FILE
{
int handle;
};
FILE __stdout;
//¶¨Òå_sys_exit()ÒÔ±ÜÃâʹÓðëÖ÷»úģʽ
void _sys_exit(int x)
{
x = x;
}
//Öض¨Òåfputcº¯Êý
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//Ñ»··¢ËÍ,Ö±µ½·¢ËÍÍê±Ï
USART1->DR = (u8) ch;
return ch;
}
#endif
#if EN_USART1_RX //Èç¹ûʹÄÜÁ˽ÓÊÕ
//´®¿Ú1ÖжϷþÎñ³ÌÐò
//×¢Òâ,¶ÁÈ¡USARTx->SRÄܱÜÃâĪÃûÆäÃîµÄ´íÎó
u8 USART_RX_BUF[USART_REC_LEN]; //½ÓÊÕ»º³å,×î´óUSART_REC_LEN¸ö×Ö½Ú.
//½ÓÊÕ״̬
//bit15£¬ ½ÓÊÕÍê³É±êÖ¾
//bit14£¬ ½ÓÊÕµ½0x0d
//bit13~0£¬ ½ÓÊÕµ½µÄÓÐЧ×Ö½ÚÊýÄ¿
u16 USART_RX_STA=0; //½ÓÊÕ״̬±ê¼Ç
//³õʼ»¯IO ´®¿Ú1
//bound:²¨ÌØÂÊ
void uart_init(u32 bound){
//GPIO¶Ë¿ÚÉèÖÃ
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //ʹÄÜGPIOAʱÖÓ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//ʹÄÜUSART1ʱÖÓ
//´®¿Ú1¶ÔÓ¦Òý½Å¸´ÓÃÓ³Éä
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9¸´ÓÃΪUSART1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10¸´ÓÃΪUSART1
//USART1¶Ë¿ÚÅäÖÃ
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_10; //GPIOA9ÓëGPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//¸´Óù¦ÄÜ
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //ËÙ¶È50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //ÍÆÍ츴ÓÃÊä³ö
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //ÉÏÀ
GPIO_Init(GPIOA,&GPIO_InitStructure); //³õʼ»¯PA9£¬PA10
//USART1 ³õʼ»¯ÉèÖÃ
USART_InitStructure.USART_BaudRate = bound;//²¨ÌØÂÊÉèÖÃ
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö³¤Îª8λÊý¾Ý¸ñʽ
USART_InitStructure.USART_StopBits = USART_StopBits_1;//Ò»¸öֹͣλ
USART_InitStructure.USART_Parity = USART_Parity_No;//ÎÞÆæżУÑéλ
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ÎÞÓ²¼þÊý¾ÝÁ÷¿ØÖÆ
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //ÊÕ·¢Ä£Ê½
USART_Init(USART1, &USART_InitStructure); //³õʼ»¯´®¿Ú1
USART_Cmd(USART1, ENABLE); //ʹÄÜ´®¿Ú1
//USART_ClearFlag(USART1, USART_FLAG_TC);
#if EN_USART1_RX
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//¿ªÆôÏà¹ØÖжÏ
//Usart1 NVIC ÅäÖÃ
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//´®¿Ú1ÖжÏͨµÀ
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//ÇÀÕ¼ÓÅÏȼ¶
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //×ÓÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨµÀʹÄÜ
NVIC_Init(&NVIC_InitStructure); //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷¡¢
#endif
}
//int Vertical_Kp1=50;
//int Vertical_Kd1=10;
//int y,x,w,h;
//int back1;
//int biaozhi=1;
//extern uint8_t Fore,Left,Right;
//extern int mubiaoshudu;
//extern int ruku;
//extern int buxuanxian;
//int left,right,on,down;
//int leftpwm=0,rightpwm=0;
// int Bluetooth_data;
void USART1_IRQHandler(void) //´®¿Ú1ÖжϷþÎñ³ÌÐò
{
int lastcx;
u8 com_data;
u8 i;
static u8 RxCounter1=0;
static u16 RxBuffer1[10]={0};
static u8 RxState = 0;
static u8 RxFlag1 = 0;
if( USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET) //½ÓÊÕÖжÏ
{
USART_ClearITPendingBit(USART1,USART_IT_RXNE); //Çå³ýÖжϱêÖ¾
com_data = USART_ReceiveData(USART1);
if(RxState==0&&com_data==0x2C) //0x2cÖ¡Í·
{
RxState=1;
RxBuffer1[RxCounter1++]=com_data;
}
else if(RxState==1&&com_data==0x12) //0x12Ö¡Í·
{
RxState=2;
RxBuffer1[RxCounter1++]=com_data;
}
else if(RxState==2)
{
RxBuffer1[RxCounter1++]=com_data;
if(RxCounter1>=10||com_data == 0x5B) //RxBuffer1½ÓÊÜÂúÁË,½ÓÊÕÊý¾Ý½áÊø
{
RxState=3;
RxFlag1=1;
Cx=RxBuffer1[RxCounter1-5];
Cy=RxBuffer1[RxCounter1-4];
Cw=RxBuffer1[RxCounter1-3];
Ch=RxBuffer1[RxCounter1-2];
}
}
else if(RxState==3) //¼ì²âÊÇ·ñ½ÓÊܵ½½áÊø±êÖ¾
{
if(RxBuffer1[RxCounter1-1] == 0x5B)
{
USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//¹Ø±ÕDTSABLEÖжÏ
if(RxFlag1)
{
x=Cy;
y=Cx;
w=Cw;
h=Ch;
biaozhi=1;
}
RxFlag1 = 0;
RxCounter1 = 0;
RxState = 0;
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
}
else //½ÓÊÕ´íÎó
{
RxState = 0;
RxCounter1=0;
for(i=0;i<10;i++)
{
RxBuffer1[i]=0x00; //½«´æ·ÅÊý¾ÝÊý×éÇåÁã
}
}
}
else //½ÓÊÕÒì³£
{
RxState = 0;
RxCounter1=0;
for(i=0;i<10;i++)
{
RxBuffer1[i]=0x00; //½«´æ·ÅÊý¾ÝÊý×éÇåÁã
}
}
}
}
#endif
void usart6_init(u32 bound){
//GPIO¶Ë¿ÚÉèÖÃ
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); //ʹÄÜGPIOAʱÖÓ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE);//ʹÄÜUSART1ʱÖÓ
//´®¿Ú1¶ÔÓ¦Òý½Å¸´ÓÃÓ³Éä
GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_USART6); //GPIOA9¸´ÓÃΪUSART1
GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_USART6); //GPIOA10¸´ÓÃΪUSART1
//USART1¶Ë¿ÚÅäÖÃ
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; //GPIOA9ÓëGPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//¸´Óù¦ÄÜ
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //ËÙ¶È50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //ÍÆÍ츴ÓÃÊä³ö
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //ÉÏÀ
GPIO_Init(GPIOC,&GPIO_InitStructure); //³õʼ»¯PA9£¬PA10
//USART1 ³õʼ»¯ÉèÖÃ
USART_InitStructure.USART_BaudRate = bound;//²¨ÌØÂÊÉèÖÃ
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö³¤Îª8λÊý¾Ý¸ñʽ
USART_InitStructure.USART_StopBits = USART_StopBits_1;//Ò»¸öֹͣλ
USART_InitStructure.USART_Parity = USART_Parity_No;//ÎÞÆæżУÑéλ
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ÎÞÓ²¼þÊý¾ÝÁ÷¿ØÖÆ
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //ÊÕ·¢Ä£Ê½
USART_Init(USART6, &USART_InitStructure); //³õʼ»¯´®¿Ú1
USART_Cmd(USART6, ENABLE); //ʹÄÜ´®¿Ú1
//USART_ClearFlag(USART1, USART_FLAG_TC);
#if EN_USART1_RX
USART_ITConfig(USART6, USART_IT_RXNE, ENABLE);//¿ªÆôÏà¹ØÖжÏ
//Usart1 NVIC ÅäÖÃ
NVIC_InitStructure.NVIC_IRQChannel = USART6_IRQn;//´®¿Ú1ÖжÏͨµÀ
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//ÇÀÕ¼ÓÅÏȼ¶
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //×ÓÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨµÀʹÄÜ
NVIC_Init(&NVIC_InitStructure); //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷¡¢
#endif
}
void USART6_IRQHandler(void) //´®¿Ú1ÖжϷþÎñ³ÌÐò
{
if(USART_GetITStatus(USART6,USART_IT_RXNE)!=0) // ½ÓÊÕÖжϱê־λÀ¸ß
{
printf("10");
}
}
void Serial_SendByte(uint16_t Byte)
{
USART_SendData(USART6,Byte);
}