这两天本人利用周末时间粗略的学习一下openmv的使用,目的是用openmv图像处理数据并通过串口发送数据给STM32F103的单片机,并且用TFTLCD显示屏打印数据。在学习的过程中遇到了一些问题且成功解决,下面将讲述其中的过程,希望可以帮助需要的朋友,欢迎大家一起交流学习。
import sensor, image, time, math
from pyb import UART
import json
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
clock = time.clock()
uart = UART(3,115200) #定义串口3变量
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
####################################
#
#此为颜色处理代码
#
###################################
#bytearray为可变序列的字节数组 返回一个新的字节数组(将数据转为16进制)
img_data = bytearray([0x2C,18,X_black_Sign,Y_black_Sign,X_black_relative_displacement,Y_black_relative_displacement,
X_red_Sign,Y_red_Sign,X_red_relative_displacement,Y_red_relative_displacement,X_yellow_Sign,
Y_yellow_Sign,X_yellow_relative_displacement,Y_yellow_relative_displacement,
L_black,L_red,L_yellow,0x5B])
uart.write(img_data)
上述代码中引用了感光元件sensor及串口UART.
先定义了一个寻色块面积最大的函数,然后对目标颜色进行处理,最后通过bytearray对数据进行处理并赋值给变量img_data。
bytearray为python内字节数组,详情请点击此处
void uart4_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //串口端口配置结构体变量
USART_InitTypeDef USART_InitStructure;//串口参数配置结构体变量
NVIC_InitTypeDef NVIC_InitStructure;//串口中断配置结构体变量
//使能 UART4 时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); //打开串口复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //打开PC端口时钟
//UART4_TX GPIOC.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PC.10
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设定IO口的输出速度为50MHz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC.10
//UART4_RX GPIOC.11初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PC.11
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = 115200;//串口波特率为115200
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(UART4, &USART_InitStructure); //初始化串口4
USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(UART4, ENABLE); //使能串口4
//如下语句解决第1个字节无法正确发送出去的问题
USART_ClearFlag(UART4, USART_FLAG_TC); //清串口4发送标志
}
void UART4_IRQHandler(void) //串口4全局中断服务函数
{
u8 com_data;
//接收中断
if( USART_GetITStatus(UART4,USART_IT_RXNE) )
{
USART_ClearITPendingBit(UART4,USART_IT_RXNE);//清除中断标志
com_data = UART4->DR;
Openmv_Receive_Data(com_data);//openmv数据处理函数
}
}
本次实验我采用的是STM32F103zet6精英版单片机,具体配置请参考其数据手册。
void Openmv_Receive_Data(int16_t data)//接收Openmv传过来的数据
{
static u8 openmv[18]; //存取数据
static u8 state = 0;
static u8 bit_number=0;
if(state==0&&data==0x2C)
{
state=1;
openmv[bit_number++]=data;
}
else if(state==1&&data==18)
{
state=2;
openmv[bit_number++]=data;
}
else if(state==2)
{
openmv[bit_number++]=data;
if(bit_number>=17)
{
state=3;
}
}
else if(state==3) //检测是否接受到结束标志
{
if(data == 0x5B)
{
state = 0;
openmv[bit_number++]=data;
}
else if(data != 0x5B)
{
state = 0;
for(i=0;i<18;i++)
{
openmv[i]=0x00;
}
}
}
else
{
state = 0;
bit_number=0;
for(i=0;i<18;i++)
{
openmv[i]=0x00;
}
}
}
函数就是数据后先对比帧头是否正确,正确则进行数据存储,否则数据数组一直等待正确帧头的到来。
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
uart4_Init();
LED_Init(); //LED端口初始化
KEY_Init(); //初始化与按键连接的硬件接口
LCD_Init();
POINT_COLOR=RED;
while(1)
{
LCD_ShowNum(0,20,200,10,24);
LCD_ShowNum(0,40,X_black_data,10,24);
LCD_ShowNum(0,70,Y_black_data,10,24);
LCD_ShowNum(0,90,X_red_data,10,24);
LCD_ShowNum(0,110,Y_red_data,10,24);
LCD_ShowNum(0,130,X_yellow_data,10,24);
LCD_ShowNum(0,150,Y_yellow_data,10,24);
}
}
- 若使用寄存器初始化串口,则应只有USART1使用PCLK2(最高72MHz)。其它USART使用PCLK1(最高36MHz)。
- openmv的波特率应与接收端单片机串口波特率对应
- openmv与STM32单片机两个串口的的数据格式应保持一致