完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
前言
最近一段时间都在捣鼓OpenMV和Stm32的通信问题,刚开始不知道哪里出了问题,一直通信失败,明明使用TTL串口接收OpenMv发送的数据是可以在串口调试助手上显示的,但就是无法发给Stm32的USART串口。经过了差不多一周的时间,终于解决了。于是在这里记录学习记录。 一、OpenMv配置 1.第一种发送方法 OpenMv代码如下 # Untitled - By: 86188 - 周二 5月 25 2021 import sensor, image, time,pyb from pyb import UART,LED import json import ustruct #white_threshold_01 = ((95, 100, -18, 3, -8, 4)); #白色阈值 red_threshold_01 = ((2, 51, 11, 127, -128, 127)) #红色阈值 LED_R = pyb.LED(1) # Red LED = 1, Green LED = 2, Blue LED = 3, IR LEDs = 4. LED_G = pyb.LED(2) LED_B = pyb.LED(3) LED_R.on() LED_G.on() LED_B.on() 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() LED_R.off() LED_G.off() LED_B.off() uart = UART(3,115200) #定义串口3变量 uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters 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 def send_data_packet(x,y,z,w): temp = ustruct.pack(" 0x12, #帧头2 int(x), # up sample by 2 #数据1 int(y), # up sample by 2 #数据2 int(z), int(w)) #0x5B) uart.write(temp); #串口发送 while(True): img = sensor.snapshot() #time.sleep_ms(1000) #send_data_packet(x,y) blobs = img.find_blobs([red_threshold_01]); cx=0;cy=0; if blobs: #如果找到了目标颜色 max_b = find_max(blobs); # Draw a rect around the blob. img.draw_rectangle(max_b[0:4]) # rect #用矩形标记出目标颜色区域 img.draw_cross(max_b[5], max_b[6]) # cx, cy #img.draw_cross(160, 120) # 在中心点画标记 #在目标颜色区域的中心画十字形标记 cx=max_b[5]; cy=max_b[6]; cw=max_b[2]; ch=max_b[3]; #data = bytearray([x,y]) send_data_packet(cx,cy,cw,ch) #time.sleep_ms(1000) 代码作用:OpenMv使用的是python语言编写,而这段代码的主要目的就是在openmv视野种寻找红色色块,并将其中点坐标发送会Stm32,并在OLED屏幕上显示。 主要通信函数如下 def send_data_packet(x,y,z,w): temp = ustruct.pack(" 0x12, #帧头2 int(x), # up sample by 2 #数据1 int(y), # up sample by 2 #数据2 int(z), int(w)) #0x5B) uart.write(temp); #串口发送 这里使用了数据包的形式发送数据,将一帧的数据包装,并发送给Stm32,此数据包中的包头非常重要,也就是0x2C以及0x12,这两个数据便与Stm32接收中断中进行判断,以确保数据的正确性。 对于数据包格式,此等的使用规划: #pack各字母对应类型 #x pad byte no value 1 #c char string of length 1 1 #b signed char integer 1 #B unsigned char integer 1 #? _Bool bool 1 #h short integer 2 #H unsigned short integer 2 #i int integer 4 #I unsigned int integer or long 4 #l long integer 4 #L unsigned long long 4 #q long long long 8 #Q unsilong long long 8 #f float float 4 #d double float 8 #s char[] string 1 #p char[] string 1 #P void * long 对于此处我所使用的" 如图,一串完整的数据便是 2C 12 36 00 80 00 2E 00 9D 00。 2.第二种发送方法 除了以上这种以包(pack)的方式发送给stm32外,还可以使用另外的一种方法发送: def send_data(cx,cy,w,h): datalist = [ 0x2C,0x12,cx,cy,w,h] datalist.append(sum_checkout(datalist)) data = bytearray(datalist) return data #检验数据和 def sum_checkout(data_list): data_sum = 0 for temp in data_list: data_sum = data_sum + temp return data_sum 这段代码和之前不同的是:我将0x5B 最后一位的数据校验位改成了用sum_checkout() 这段函数求和取余的方法作为该数据的数据校验位。 但是使用这样不封包的方法发送,就必须加上data = bytearray(datalist),将数据转化,才可以进行通讯。 二、Stm32配置 Stm32的USART1配置如下: u16 USART_RX_STA=0; //接收状态标记 void uart1_init(u32 bound){ //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟 //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9 //USART1_RX GPIOA.10初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 //USART 初始化设置 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_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断 USART_Cmd(USART1, ENABLE); //使能串口1 } 相比于平常配置并未存在较大差别,而实现通信的重要步骤是在USART1的串口接收中断中。 void USART1_IRQHandler(void) { u8 Res; static u8 Rebuf[20]={0}; static u8 i = 0; if( USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET ) { Rebuf[i++] = USART_ReceiveData(USART1); if(Rebuf[0] != 0x2c) i = 0; if((i==2)&&Rebuf[1] != 0x12) i = 0; if(i>=10) { memcpy(OpenMV_Rx_BUF,Rebuf,i); i = 0; } USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除中断标志 } } 其中定义了一个OpenMV_Rx_BUF[20]的数组来接收openmv发送过来的数据,需要使用extern修饰这个变量,以便于事项后续操作。 同时memcpy()函数也是十分重要的一个内置函数,可以实现两个数组的拷贝任务。 主函数的代码如下: int main(void) { delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart1_init(115200); //串口初始化为115200 LED_Init(); //LED端口初始化 OLED_Init(); while(1) { LED0=!LED0; delay_ms(200); OLED_Refresh_Gram(); OLED_ShowNumber(0,20,OpenMV_Rx_BUF[2],3,12); OLED_ShowNumber(20,20,OpenMV_Rx_BUF[4],3,12); OLED_ShowNumber(40,20,OpenMV_Rx_BUF[6],3,12); OLED_ShowNumber(60,20,OpenMV_Rx_BUF[8],3,12); } } 前面就提到了,由于我数据包的格式设置问题,存入OpenMV_Rx_BUF[] 数组中的数据,真正有效的是第3、5、7、9位(因为选择了h类型数据格式,一个数据占2位)。 总结 博主我之前数据一直发送失败的原因是,博主使用了 uart.write() 这个函数,企图通过 uart.write() 这个函数实现数据发送。 这个函数在实现OpenMv和PC端的通信上没有问题,可以将数据打在串口调试助手上,但在其与Stm32的通信问题上就存在问题。 若要使用 uart.write() 实现与stm32的通信,便要使用bytearray()函数将其转化,才可以进行通信。 FH = bytearray([0x2C,0x12]) uart.write(FH) |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1935浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
728浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
567浏览 3评论
593浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
551浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 10:49 , Processed in 0.805173 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号