一、准备工作
有关OPENMV最大色块追踪及与STM32通信内容,详情见【STM32+HAL】与OpenMV通信
有关七针OLED屏显示内容,详情见【STM32+HAL】七针OLED(SSD1306)配置(SPI版)
二、所用工具
1、芯片:STM32F407ZGT6
2、CUBEMX配置软件
3、KEIL5
4、OPENMV
三、实现功能
二维云台追踪最大色块,并显示中心x,y坐标至OLED
四、HAL配置步骤
1、生成两路PWM波控制舵机
周期为20ms
2、中断配置
五、KEIL填写代码
1、ptz.c
cpp
#include "ptz.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "main.h"
#include "tim.h"
#include "usart.h"
#define RXBUFFERSIZE 256
#define CCR_UD TIM2->CCR2 //up and down.... RANGE:420-2000
#define CCR_LR TIM2->CCR3 //Left and Right.... RANGE:420-2500
#define Cen_x 160 //x轴中心坐标值
#define Cen_y 120 //y轴中心坐标值
#define sp1 7 //x轴速度
#define sp2 6 //y轴速度
#define range 40 //识别范围
char RxBuffer[RXBUFFERSIZE],rx_buf[RXBUFFERSIZE];
uint8_t aRxBuffer;
uint8_t Uart1_Rx_Cnt = 0;
int cnt_rx=0,cnt_dt=0;
int cx=0,cy=0;
void Tilt(void)
{
if(cx < (Cen_x-range)) CCR_LR = (CCR_LR>2450)?2450:CCR_LR+sp1;
else if (cx > (Cen_x+range)) CCR_LR = (CCR_LR<450)?450:CCR_LR -sp1;
else CCR_LR= CCR_LR;
if(cy < (Cen_y-range)) CCR_UD = (CCR_UD<420)?420:CCR_UD -sp2;
else if (cy > (Cen_y+range)) CCR_UD = (CCR_UD>1800)?1800:CCR_UD+sp2;
else CCR_UD= CCR_UD;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
if(huart==&huart2){
RxBuffer[Uart1_Rx_Cnt] = aRxBuffer;
Uart1_Rx_Cnt++;
if((RxBuffer[Uart1_Rx_Cnt-1] == 0xb3)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0xb3)) cnt_rx=1; //帧头判定
else if((RxBuffer[Uart1_Rx_Cnt-2] == 0x0d)&&(RxBuffer[Uart1_Rx_Cnt-1] == 0x0a)) cnt_rx=2; //帧尾判定
else cnt_rx=0;
switch (cnt_rx)
{
case 1:
Uart1_Rx_Cnt = 0;
memset(RxBuffer,0x00,sizeof(RxBuffer));
break;
case 2:
RxBuffer[Uart1_Rx_Cnt-1] = '\0';
RxBuffer[Uart1_Rx_Cnt-2] = '\0';
strcpy(rx_buf,RxBuffer);
int st=0; //有效数值开始位置
cnt_dt=0; //空格数
for(int i=0;rx_buf[i];i++){
if(cnt_dt==4) break;
if(rx_buf[i]==' ') {
cnt_dt++;
int temp=0;
for(int j=st;j<i;j++)
temp=temp*10+(rx_buf[j]-'0');
switch (cnt_dt){
case 1:cx=temp;break;
case 2:cy=temp;break;
}
st=i+1;
}
}
while(HAL_UART_GetState(&huart2) == HAL_UART_STATE_BUSY_TX);
Uart1_Rx_Cnt = 0;
memset(RxBuffer,0x00,sizeof(RxBuffer));
break;
default:break;
}
HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);
}
}
2、main.c
cpp
/* USER CODE BEGIN 2 */
OLED_Init();
HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);
TIM2->CCR2 = 420-1;
TIM2->CCR3 = 1400-1;
HAL_TIM_PWM_Start (&htim2, TIM_CHANNEL_2);
HAL_TIM_PWM_Start (&htim2, TIM_CHANNEL_3);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
OLED_ShowNum(30,20,cx,3,16);
OLED_ShowNum(30,40,cy,3,16);
OLED_Refresh();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(flag) Tilt();
}
/* USER CODE END 3 */
}
3、按键控制暂停
cpp
/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == KEY0_Pin){
HAL_Delay(20); //延时消抖
if(GPIO_Pin == KEY0_Pin){
flag=0;
}
}
}
/* USER CODE END 4 */
六、巨人之肩
【毕业设计】基于STM32F103C8T6最小系统板与OpenMV的二维云台PID控制追踪系统
后续优化方案:PID调控
七、源码提供
【STM32+OPENMV】二维云台颜色识别及追踪【无PID版】
八、成果展示
PTZ