个人笔记。这是之前的一个实验,现在把它整理出来。
本实验用的是stm32h743和openmv作为硬件,实现用openmv识别出我们想要的颜色,将获取的颜色坐标和目标区域的宽、高 通过串口发送给 stm32,最后在串口助手中显示。
硬件连接:
stm32 openmv
rx p4
tx p5
GND GND
openmv程序:
img_data=bytearray([0x2C,7,1,2,3,4,0X5B])用到了bytearry(),所以在openmv程序开头要import math,第0位为开始标志,最后一位为结束标志,第1位为总位数7,其他为要传输的数据。
stm32程序:
openmv
void Openmv_Receive_Data(int16_t data)//接收Openmv传过来的数据
{
static uint8_t state = 0; //state判断openmv代码中bytearry()的第几位
if(state==0&&data==0x2C) //开始位
{
state=1;
openmv[0]=data;
}
else if(state==1&&data==7)
{
state=2;
openmv[1]=data;
}
else if(state==2) //第一有效位
{
state=3;
openmv[2]=data;
}
else if(state==3)
{
state = 4;
openmv[3]=data;
}
else if(state==4)
{
state = 5;
openmv[4]=data;
}
else if(state==5) //第四有效位
{
state = 6;
openmv[5]=data;
}
else if(state==6) //检测是否接受到结束标志
{
if(data == 0x5B)
{
state = 0;
openmv[6]=data;
Openmv_Data();
}
else if(data != 0x5B)
{
state = 0;
for(i=0;i<7;i++)
{
openmv[i]=0x00;
}
}
}
else
{
state = 0;
for(i=0;i<7;i++)
{
openmv[i]=0x00;
}
}
}
void Openmv_Data(void)
{
data1=openmv[2]; //第一个有效位
data2=openmv[3];
data3=openmv[4];
data4=openmv[5];
}
usart
uint8_t ucaRxBuf[256];
uint16_t usRxCount=0;
extern uint8_t Rxflag;
extern int ucTemp;
void DEBUG_USART_IRQHandler(void)
{
if(__HAL_UART_GET_IT( &UartHandle, UART_IT_RXNE ) != RESET)
{
Rxflag=1;
HAL_UART_Receive(&UartHandle, (uint8_t *)&ucTemp, 1, 1000); // (uint8_t *)
Openmv_Receive_Data(ucTemp);
Openmv_Data();
if((Rxflag&0x8000)==0)//接收未完成
{
if(Rxflag&0x4000)//接收到了0x0d
{
if(ucTemp!=0x0a)Rxflag=0;//接收错误,重新开始
else Rxflag|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(ucTemp==0x0d)Rxflag|=0x4000;
else
{
ucaRxBuf[Rxflag&0X3FFF]=ucTemp ;
Rxflag++;
if(Rxflag>(usRxCount-1))Rxflag=0;//接收数据错误,重新开始接收
}
}
}
}
// HAL_UART_IRQHandler(&UartHandle);
}
void GET_USART1DATE(void) //接收到USART数据
{
if(Rxflag)
{
if (usRxCount < sizeof(ucaRxBuf))
{
ucaRxBuf[usRxCount] = ucTemp; //把数据放在缓冲区里
// Openmv_Receive_Data(ucaRxBuf[usRxCount++]);
// Openmv_Data();
}
else
{
usRxCount = 0;
}
/* 简单的通信协议,遇到回车换行符认为1个命令帧,可自行加其它判断实现自定义命令 */
/* 遇到换行字符,认为接收到一个命令 */
if (ucTemp == 0x0A) /* 换行字符 */
{
/*检测到有回车字符就把数据返回给上位机*/
HAL_UART_Transmit( &UartHandle, (uint8_t *)ucaRxBuf,usRxCount,1000 );
usRxCount = 0;
}
Rxflag=0;
}
}
这是串口中断部分。串口配置部分直接用CubeMX生成就可以,也可到野火或原子找串口例程。
main
volatile uint8_t Rxflag=0; //接收完成标志:0表示未完成,1表示接收完成
uint8_t ucTemp; //数据变量
int main(void)
{
uint8_t ucaRxBuf[256]; //接收缓冲,定义最大接收字节数 256
uint16_t usRxCount=0;
SystemClock_Config();
/* 配置串口1为:115200 8-N-1 */
USART_Config();
while(1)
{
printf("%.d %.d %.d %.d\r\n",data1,data2,data3,data4);
}
}
实验现象:
以最后一组数据为例:
openmv数据为167 95 6 7
stm32接收的16进制数据为2C 07 A7 5F 06 07 5B
数据匹配。
注意:
1、硬件连接别连错
2、使用其他型号的stm32也可以,只不过串口引脚可能不一样,其他的都可通用。