cathy 在 提交
简谈闲话
这两天本人利用周末时间粗略的学习一下openmv的使用,目的是用openmv图像处理数据并通过串口发送数据给STM32F103的单片机,并且用TFTLCD显示屏打印数据。在学习的过程中遇到了一些问题且成功解决,下面将讲述其中的过程,希望可以帮助需要的朋友,欢迎大家一起交流学习。
Openmv主要代码
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内字节数组。
STM32单片机的配置
UART4库函数初始化配置
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发送标志 }
UART4的中断函数
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精英版单片机,具体配置请参考其数据手册。
接收openmv数据
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单片机两个串口的的数据格式应保持一致
版权声明:本文为CSDN博主「啊,小刘」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/LJH_1999/article/details/88782943
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。