2021-07-27凌霄飞控TM4C123G和openmv通信

7.12飞控TM4C123G和openmv通信

文章目录

遇到的问题:无法判断飞控接收到的openmv的数据是否正确,方案一:用匿名上位机查看飞控接受到的数据,但是由于匿名通信协议调试不出来,只能另外找方法来查看数据是否正确

解决方法:用一块stm32f1指南针芯片作为调试工具,用野火调试助手查看

具体实现流程:

1.tm4c串口2接收openmv的数据存在缓存数组中

2.然后把缓存数组通过串口3发送给stm32

3.stm32将接受到的数据发送给野火串口调试助手,若接受到的数据在串口助手上显示正确则说明飞控正确的接受并解析到了一帧完整的数据。

一、openmv部分:

1.openmv实现的功能,找红色的色块

2.openmv数据帧格式:

帧头:0xaa//一个字节
目的地址:0x61(凌霄飞控硬件地址)//一个字节
帧ID:0x70//一个字节
数据内容长度(不包括帧头帧尾,只包括openMV的数据内容长度):假设为四个(色块的数据)//一个字节
数据内容://四个字节
一个帧一共8个字节。

3.代码实现:

while(True):
    clock.tick()
    img = sensor.snapshot()
    blobs = img.find_blobs([red_threshold_01])
    cx=0;cy=0;
    if blobs:
            max_b = find_max(blobs)
            #如果找到了目标颜色
            cx=max_b[5]
            cy=max_b[6]
            cw=max_b[2]
            ch=max_b[3]
            img.draw_rectangle(max_b[0:4]) # rect
            img.draw_cross(max_b[5], max_b[6]) # cx, cy
            FH = bytearray([0xAA,0x61,0x70,0x04,cx,cy,cw,ch])
            uart.write(FH)
    print(clock.fps())

二、TM4C123G部分:

1.帧头||目的地址||ID||数据长度||数据内容8

2.用TM4C123G的串口2接受openmv数据,用串口3发送给stm32

3.代码实现:

//串口从openmv接收数据,在中断服务函数里面调用该函数
void AnoOPENMV_GetOneByte(uint8_t data)
{
	static u8 _data_len = 0, _data_cnt = 0;
	static u8 rxstate = 0;

	if (rxstate == 0 && data == 0xAA)//帧头0xAA 
	{
		rxstate = 1;
		_datatemp_openmv[0] = data;
	}
	
	else if (rxstate == 1 && (data == 0xff || data == 0x61))//目的地址
	{
		rxstate = 2;
		_datatemp_openmv[1] = data;
	}
	else if (rxstate == 2&&data == 0x70)//功能码ID
	{
		rxstate = 3;
		_datatemp_openmv[2] = data;
	}
	else if (rxstate == 3 && data < 250)//数据长度length
	{
		rxstate = 4;
		_datatemp_openmv[3] = data;
		_data_len = data;
		_data_cnt = 0;
	}
	else if (rxstate == 4 && _data_len > 0)//这里的数据内容的个数可能不只有一个
	{
		_data_len--;//3,2,1,0
		_datatemp_openmv[4 + _data_cnt++] = data;//data_cnt = 1,2,3,4
		if (_data_len == 0)
			rxstate = 5;
	}
	else
	{
		rxstate = 0;
	}
}

//中断服务函数调用void AnoOPENMV_GetOneByte(uint8_t data)
#define U2GetOneByte	AnoOPENMV_GetOneByte
void UART2_IRQHandler(void)
{
	uint8_t com_data;
	/*获取中断标志 原始中断状态 不屏蔽中断标志*/		
	uint32_t flag = ROM_UARTIntStatus(UART4_BASE,1);
	/*清除中断标志*/	
	ROM_UARTIntClear(UART4_BASE,flag);		
	/*判断FIFO是否还有数据*/		
	while(ROM_UARTCharsAvail(UART4_BASE))		
	{			
		com_data=ROM_UARTCharGet(UART4_BASE);
		U2GetOneByte(com_data);
	}
	if(flag & UART_INT_TX)
	{
		DrvUart2TxCheck();
	}
}

//将缓存数据通过串口3发送出来
void U3Send_OmvToPc(uint8_t *data)
{
	u8 datanum = (*(data+3)+4);	
	DrvUart3SendBuf(data,datanum);
}

三、stm32调试工具部分

1.这里我用的是串口5的Rx,接收飞控芯片TM4C的串口Tx,然后串口5的Tx接stm32板子上内嵌的ttl-usb芯片的Rx

2.串口:

(1)串口的分配:串口1usb转串口用掉了;串口3wifi用掉了;串口2,4,5空闲

(2)对应的引脚图:串口2 PA2,PA3;串口4 PC10,PC11;串口5 PD2,PC12

在这里插入图片描述
在这里插入图片描述

3.代码实现:

串口5配置
/**
  * @brief  配置嵌套向量中断控制器NVIC
  * @param  无
  * @retval 无
  */
static void NVIC_Configuration_5(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 嵌套向量中断控制器组选择 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 配置USART为中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
  /* 抢断优先级*/
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /* 子优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /* 使能中断 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  /* 初始化配置NVIC */
  NVIC_Init(&NVIC_InitStructure);
}

 /**
  * @brief  USART GPIO 配置,工作参数配置
  * @param  无
  * @retval 无
  */
void USART_Config_5(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	// 打开串口GPIO的时钟
	DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
	
	// 打开串口外设的时钟
	DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);

	// 将USART Tx的GPIO配置为推挽复用模式
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

  // 将USART Rx的GPIO配置为浮空输入模式
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
	
	// 配置串口的工作参数
	// 配置波特率
	USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
	// 配置 针数据字长
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	// 配置停止位
	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(DEBUG_USARTx, &USART_InitStructure);
	
	// 串口中断优先级配置
	NVIC_Configuration_5();
	
	// 使能串口接收中断
	USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);	
	
	// 使能串口
	USART_Cmd(DEBUG_USARTx, ENABLE);		

  // 清除发送完成标志
	//USART_ClearFlag(USART1, USART_FLAG_TC);  
}

中断服务函数
void DEBUG_USART_IRQHandler(void)
{

	uint8_t ucTemp;
	if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET)
	{		
		ucTemp = USART_ReceiveData(DEBUG_USARTx);
    USART_SendData(DEBUG_USARTx,ucTemp);    
	}	 
}


四、接线图示意图:

在这里插入图片描述
在这里插入图片描述

注意:

(1)openmv的Tx接TM4C的串口2的Rx,GND接GND
(2)TM4C的串口3的Tx接stm32的串口5的Rx,GND接GND
(3)stm32通过usb转串口接电脑上位机
(4)由于飞控串口通过4根杜邦线引出来的,从左到右的顺序位vcc,gnd,Tx,Rx由于当时调试的时候这四根先的接线错误,导致调试了一整个下午才成功。(浪费了很多时间)。

((最开始测试的时候是没有接GND)当时测试的时候,stm32部分接受数据是完全没有问题的,但是我们先用飞控用死循环一直发送0x01进行最简单的检测,32任然无法接受数据,断定不是程序的问题。然后检查接线的问题,最后了查出原因)

(5)当串口调试助手显示到接受的数据之后,发现数据有误,不是原来设定的一帧数据,可以判断飞控能够发送数据,但是可能是由于波特率设置太高了设置成了500000(太快),导致PC机(串口调试助手)接受数据有误,改成115200,就接收正常了。

五、最后上图,一下午的成果呜呜呜~~~~~

在这里插入图片描述

  • 8
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值