当前位置:   article > 正文

stm32与openmv进行串口通讯_openmv与stm32串口

openmv与stm32串口

目录

 

一、openmv端配置:

二、STM32F103C8T6端配置


 

一、openmv端配置:

         openmv代码:

         我使用的是将被识别的目标中心点坐标通过串口通讯发送给STM32,中心值感觉不是很准,后面还需要调整,但是基本的收发已经完成。

  1. # Untitled - By: zzy - 周五 11月 25 2022
  2. import sensor, image, time
  3. from pyb import UART
  4. import json
  5. #output_str_green="[0,0]"
  6. output_str_white="[0,0]"
  7. #green_threshold = ( 0, 80, -70, -10, -0, 30)
  8. #使用的白色测试阈值
  9. white_threshold = (53, 100, -128, 127, -128, 127)
  10. sensor.reset()
  11. sensor.set_pixformat(sensor.RGB565)
  12. sensor.set_framesize(sensor.QVGA)
  13. sensor.set_windowing((0,20,320,200))#QVGA find Region Of Interest
  14. #sensor.set_windowing((5,10,160,95))#QQVGA find Region Of Interest
  15. sensor.skip_frames(10)
  16. sensor.set_auto_whitebal(False)#白平衡增益关闭
  17. clock = time.clock()
  18. uart = UART(3, 115200)
  19. def find_max(blobs):
  20. max_size=0
  21. for blob in blobs:
  22. if blob.pixels() > max_size:
  23. max_blob=blob
  24. max_size = blob.pixels()
  25. return max_blob
  26. def detect(max_blob):#输入的是寻找到色块中的最大色块
  27. #print(max_blob.solidity())
  28. shape=0
  29. if max_blob.solidity()>0.90 or max_blob.density()>0.84:
  30. img.draw_rectangle(max_blob.rect(),color=(255,255,255))
  31. shape=1
  32. elif max_blob.density()>0.6:
  33. img.draw_circle((max_blob.cx(), max_blob.cy(),int((max_blob.w()+max_blob.h())/4)))
  34. shape=2
  35. elif max_blob.density()>0.4:
  36. img.draw_rectangle(max_blob.rect(),color=(0,0,0))
  37. shape=3
  38. return shape
  39. while(True):
  40. #clock.tick()
  41. img = sensor.snapshot() # Take a picture and return the image.
  42. blobs_white = img.find_blobs([white_threshold])
  43. if blobs_white:
  44. max_blob_white=find_max(blobs_white)
  45. shape_white=detect(max_blob_white)
  46. #img.draw_rectangle(max_blob_blue.rect(),color=(0,0,255))
  47. img.draw_cross(max_blob_white.cx(), max_blob_white.cy(),color=(0,0,255))
  48. output_str_white="[%d,%d]" % (max_blob_white.cx()-160,max_blob_white.cy()-100) #方式1
  49. img_data=bytearray([0x2C,7,4,max_blob_white.cx()-160,max_blob_white.cy()-100,1,0X5B]) # 数据倒数前三位可发送成功
  50. uart.write(img_data)
  51. print('white:',output_str_white)
  52. else:
  53. print('not found white !')
  54. # uart.write(output_str_green + output_str_red + output_str_blue + output_str_brown + output_str_yellow + '\r\n')
  55. #print(clock.fps())

上面代码中如果需要引用,最主要的是串口的配置和发送部分,串口配置就一句话,串口的发送是两句话,包括下面这两句:

其中0X2C是帧头,0X5B是帧尾。中间夹的就是数据。目前调用的是第三和第四位数据,STM32那边对应的是第二和第三位。

  1. img_data=bytearray([0x2C,7,4,max_blob_white.cx()-160,max_blob_white.cy()-100,1,0X5B]) # 数据倒数前三位可发送成功
  2. uart.write(img_data)

根据自己的需要完成OPENMV端的配置后就可跳转到STM32端的配置

二、STM32F103C8T6端配置

     system文件中应包含有sys,usart,delay三个基本文件才能进行后续运行。其中uart需要进行一定的修改。

     下面是相关的库文件代码:

usart.c文件:

  1. #include "sys.h"
  2. #include "usart.h"
  3. #include "openmv.h"
  4. //如果使用ucos,则包括下面的头文件即可.
  5. #if SYSTEM_SUPPORT_OS
  6. #include "includes.h" //ucos 使用
  7. #endif
  8. //
  9. //加入以下代码,支持printf函数,而不需要选择use MicroLIB
  10. #if 1
  11. #pragma import(__use_no_semihosting)
  12. //标准库需要的支持函数
  13. struct __FILE
  14. {
  15. int handle;
  16. };
  17. FILE __stdout;
  18. //定义_sys_exit()以避免使用半主机模式
  19. void _sys_exit(int x)
  20. {
  21. x = x;
  22. }
  23. //重定义fputc函数
  24. int fputc(int ch, FILE *f)
  25. {
  26. while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
  27. USART1->DR = (u8) ch;
  28. return ch;
  29. }
  30. #endif
  31. #if EN_USART1_RX //如果使能了接收
  32. //串口1中断服务程序
  33. //注意,读取USARTx->SR能避免莫名其妙的错误
  34. u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
  35. //接收状态
  36. //bit15, 接收完成标志
  37. //bit14, 接收到0x0d
  38. //bit13~0, 接收到的有效字节数目
  39. u16 USART_RX_STA=0; //接收状态标记
  40. //初始化IO 串口1
  41. void uart_init(u32 bound){
  42. //GPIO端口设置
  43. GPIO_InitTypeDef GPIO_InitStructure;
  44. USART_InitTypeDef USART_InitStructure;
  45. NVIC_InitTypeDef NVIC_InitStructure;
  46. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE); //使能USART1,GPIOA时钟以及复用功能时钟
  47. //USART1_TX PA.9
  48. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  49. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  50. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
  51. GPIO_Init(GPIOA, &GPIO_InitStructure);
  52. //USART1_RX PA.10
  53. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  54. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  55. GPIO_Init(GPIOA, &GPIO_InitStructure);
  56. //Usart1 NVIC 配置
  57. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  58. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
  59. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
  60. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
  61. NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
  62. //USART 初始化设置
  63. USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
  64. USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
  65. USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
  66. USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
  67. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
  68. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
  69. USART_Init(USART1, &USART_InitStructure); //初始化串口
  70. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
  71. USART_Cmd(USART1, ENABLE); //使能串口
  72. printf("usart1_init_success\r\n");
  73. }
  74. void USART1_IRQHandler(void) //串口1中断服务程序
  75. {
  76. u8 Res;
  77. #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
  78. OSIntEnter();
  79. #endif
  80. if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
  81. {
  82. Res =USART_ReceiveData(USART1);//(USART1->DR); //读取接收到的数据
  83. Openmv_Receive_Data(Res);
  84. Openmv_Data();
  85. if((USART_RX_STA&0x8000)==0)//接收未完成
  86. {
  87. if(USART_RX_STA&0x4000)//接收到了0x0d
  88. {
  89. if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
  90. else USART_RX_STA|=0x8000; //接收完成了
  91. }
  92. else //还没收到0X0D
  93. {
  94. if(Res==0x0d)USART_RX_STA|=0x4000;
  95. else
  96. {
  97. USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
  98. USART_RX_STA++;
  99. if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
  100. }
  101. }
  102. }
  103. }
  104. #if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
  105. OSIntExit();
  106. #endif
  107. }
  108. #endif

usart.h

  1. #ifndef __USART_H
  2. #define __USART_H
  3. #include "stdio.h"
  4. #include "stm32f10x.h"
  5. #include "sys.h"
  6. #define USART_REC_LEN 200 //定义最大接收字节数 200
  7. #define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收
  8. extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
  9. extern u16 USART_RX_STA; //接收状态标记
  10. //如果想串口中断接收,请不要注释以下宏定义
  11. void uart_init(u32 bound);
  12. #endif

openmv.c

  1. #include "openmv.h"
  2. #include "usart.h"
  3. int openmv[7];//stm32接收数据数组
  4. int16_t data1;
  5. int16_t data2;
  6. int16_t data3;
  7. int16_t data4;
  8. int i=0;
  9. void Openmv_Receive_Data(int16_t data)//接收Openmv传过来的数据
  10. {
  11. static u8 state = 0;
  12. if(state==0&&data==0x2C)
  13. {
  14. state=1;
  15. openmv[0]=data;
  16. }
  17. else if(state==1&&data==7)
  18. {
  19. state=2;
  20. openmv[1]=data;
  21. }
  22. else if(state==2)
  23. {
  24. state=3;
  25. openmv[2]=data;
  26. }
  27. else if(state==3)
  28. {
  29. state = 4;
  30. openmv[3]=data;
  31. }
  32. else if(state==4)
  33. {
  34. state = 5;
  35. openmv[4]=data;
  36. }
  37. else if(state==5)
  38. {
  39. state = 6;
  40. openmv[5]=data;
  41. }
  42. else if(state==6) //检测是否接受到结束标志
  43. {
  44. if(data == 0x5B)
  45. {
  46. state = 0;
  47. openmv[6]=data;
  48. Openmv_Data();
  49. }
  50. else if(data != 0x5B)
  51. {
  52. state = 0;
  53. for(i=0;i<7;i++)
  54. {
  55. openmv[i]=0x00;
  56. }
  57. }
  58. }
  59. else
  60. {
  61. state = 0;
  62. for(i=0;i<7;i++)
  63. {
  64. openmv[i]=0x00;
  65. }
  66. }
  67. }
  68. void Openmv_Data(void)
  69. {
  70. data1=openmv[0];
  71. data2=openmv[3];
  72. data3=openmv[4];
  73. data4=openmv[5];
  74. }

openmv.h
 

  1. #ifndef __OPENMV_H
  2. #define __OPENMV_H
  3. #include "sys.h"
  4. extern int openmv[7];//stm32接收数据数组
  5. extern int16_t data1;
  6. extern int16_t data2;
  7. extern int16_t data3;
  8. extern int16_t data4;
  9. void Openmv_Receive_Data(int16_t data);
  10. void Openmv_Data(void);
  11. #endif

最后是main.c

  1. #include "stm32f10x.h"
  2. #include "sys.h"
  3. #include "delay.h"
  4. #include "usart.h"
  5. #include "led.h"
  6. #include "oled.h"
  7. #include "openmv.h"
  8. extern int openmv[7];//stm32接收数据数组
  9. extern int16_t data1;
  10. extern int16_t data2;
  11. extern int16_t data3;
  12. extern int16_t data4;
  13. int16_t data;
  14. int main(void)
  15. {
  16. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
  17. delay_init(); //初始化延时函数
  18. uart_init(115200); //初始化串口波特率为115200
  19. LED_Init(); //初始化LED
  20. OLED_Init(); //初始化LCD FSMC接口
  21. while(1)
  22. {
  23. OLED_ShowString(1,1,"CX:");
  24. OLED_ShowNum(1, 5, data2, 3);
  25. OLED_ShowString(2,1,"CY:");
  26. OLED_ShowNum(2, 5, data3, 3);
  27. delay_ms(150);
  28. }
  29. }

将上述库文件和主函数配置完成后,按照下面的接线方式进行接线即可完成串口通讯

  1. STM32 PA9--P5 OPENMV
  2. STM32 PA10-P4 OPENMV
  3. STM32 GND-GND OPENMV
  4. OLED SCL-PA8
  5. OLED SDA-PA9

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/570835
推荐阅读
相关标签
  

闽ICP备14008679号