使用stm32解析富斯i6接收机(IBUS)

2023-05-16

文章目录

    • 1、通信协议解析说明
    • 2、驱动程序设计
    • 3、实测
    • 4、使用串口空闲中断+DMA接收
    • 5、源码

1、通信协议解析说明

常见的官方遥控器大概如下所示:
在这里插入图片描述
常用的搭配接收机:
在这里插入图片描述
这里需要注意的是:i6是可以刷十通道固件的,但是十通道的性能要发挥出来需要用IA10B的接收机才行,IA6B的接收机解码IBUS(富斯官方的协议)最多仅支持到8通道,所以你看到下面我们解码最后两个通道无论怎么动都没有反应是正常的:

然后官方也公开了通信协议

从官网我们可以获取到的协议原文如下:
在这里插入图片描述
这里我也用逻辑分析仪,抓了一段数据,可以看到基本上和上面说的没什么区别,基本上也就是一帧32个字节的数据,然后开头0x20,0x40这样的,后面我们只需要按照要求进行解码就可以了。
在这里插入图片描述

2、驱动程序设计

首先是配置时钟,这里是时钟一定要拉到最高,不然通信的时候波特率会出问题(起因是我第一次忘了配然后一直通信失败,读不出准确的数据)
在这里插入图片描述
之后配置串口并开启串口中断,当然如果就是使用串口DMA也是可以的,我之前有一篇文章系统总结了一些串口中设备的处理办法:串口通信中一些常用的小工具
在这里插入图片描述
配置完成之后就可以生成代码了,这里我们首先配置下需要的串口号还有一些宏参数:
在这里插入图片描述
查看解析函数:
在这里插入图片描述
之后我们就可以在主函数中来测试接收函数了

3、实测

首先是在打开接收中断
在这里插入图片描述
在中断回调函数不断处理解析函数,获取解析的数据。
在这里插入图片描述
这样将程序下载到开发板并进入仿真就可以看到数据了,前面四个通道对应摇杆的四个位,中位的时候都是1500,对应PWM高电平时间都是1.5ms,最低的时候是1000,拉满是2000.
在这里插入图片描述

4、使用串口空闲中断+DMA接收

我们知道,这里其实就是处理个数据而已所以我们改为数据包即可,代码如下:

#define USART_DMA_RX_BUFFER_MAXIMUM 64 // DMA缓冲区大小
extern DMA_HandleTypeDef hdma_usart2_rx;

uint8_t FUSI_rx_buffer[USART_DMA_RX_BUFFER_MAXIMUM]; //串口1的DMA接收缓冲区
uint16_t FUSI_rx_len;                                // DMA一次空闲中断接收到的数据长度
uint8_t FUSI_data[USART_DMA_RX_BUFFER_MAXIMUM];      // DMA接收数据缓存区
uint16_t channel[IBUS_USER_CHANNELS];

void UART_DMA_start(void)
{
	for(uint8_t i = 0;i<IBUS_MAX_CHANNLES;i++)
	{
		channel[i] = 1500;
	}
	__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
	HAL_UART_Receive_DMA(&huart2,(uint8_t *)FUSI_rx_buffer, USART_DMA_RX_BUFFER_MAXIMUM);
}

uint16_t checksum_cal, checksum_ibus;

void IBUS_READ_CHANNEL(uint8_t user_channels)
{
	uint16_t channel_buffer[IBUS_MAX_CHANNLES] = {0};

	if(FUSI_data[0] == IBUS_LENGTH && FUSI_data[1] == IBUS_COMMAND40)
	{
		checksum_cal = 0xffff - FUSI_data[0] - FUSI_data[1];

		for(int i = 0; i < IBUS_MAX_CHANNLES; i++)
		{
			channel_buffer[i] = (uint16_t)(FUSI_data[i * 2 + 3] << 8 | FUSI_data[i * 2 + 2]);
			checksum_cal = checksum_cal - FUSI_data[i * 2 + 3] - FUSI_data[i * 2 + 2];
		}

		checksum_ibus = FUSI_data[31] << 8 | FUSI_data[30];

		if(checksum_cal == checksum_ibus)
		{
			for(int j = 0; j < user_channels; j++)
			{
				channel[j] = channel_buffer[j];
			}
		}
	}
}

void HAL_UART_ReceiveIdle(UART_HandleTypeDef *huart)
{
    //当触发了串口空闲中断
    if ((__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET))
    {
        if (huart->Instance == USART2)
        {
            __HAL_UART_CLEAR_IDLEFLAG(huart);
            HAL_UART_DMAStop(huart);
            FUSI_rx_len = USART_DMA_RX_BUFFER_MAXIMUM - (__HAL_DMA_GET_COUNTER(&hdma_usart2_rx));
            memcpy(FUSI_data, FUSI_rx_buffer, USART_DMA_RX_BUFFER_MAXIMUM);
            memset(FUSI_rx_buffer, 0, USART_DMA_RX_BUFFER_MAXIMUM);
            while (HAL_UART_Receive_DMA(&huart2, (uint8_t *)FUSI_rx_buffer, USART_DMA_RX_BUFFER_MAXIMUM) != HAL_OK)
                ;
			IBUS_READ_CHANNEL(IBUS_USER_CHANNELS);
        }
        //下面添加其他串口的处理函数
    }
}

之后在初始话部分开启DMA,并在中断处调用即可!

5、源码

fly_ibus.c

/*
 * fly_ibus.c
 *
 *  Created on: Feb 13, 2022
 *      Author: LX
 */

#include "fly_ibus.h"

uint8_t rx_buffer[32] = {0};
uint16_t channel[IBUS_USER_CHANNELS] = {0};
uint16_t checksum_cal, checksum_ibus;

void IBUS_INIT()
{
	HAL_UART_Receive_IT(IBUS_UART, rx_buffer, 32);
}

void IBUS_READ_CHANNEL(uint8_t user_channels)
{
	uint16_t channel_buffer[IBUS_MAX_CHANNLES] = {0};

	if(rx_buffer[0] == IBUS_LENGTH && rx_buffer[1] == IBUS_COMMAND40)
	{
		checksum_cal = 0xffff - rx_buffer[0] - rx_buffer[1];

		for(int i = 0; i < IBUS_MAX_CHANNLES; i++)
		{
			channel_buffer[i] = (uint16_t)(rx_buffer[i * 2 + 3] << 8 | rx_buffer[i * 2 + 2]);
			checksum_cal = checksum_cal - rx_buffer[i * 2 + 3] - rx_buffer[i * 2 + 2];
		}

		checksum_ibus = rx_buffer[31] << 8 | rx_buffer[30];

		if(checksum_cal == checksum_ibus)
		{
			for(int j = 0; j < user_channels; j++)
			{
				channel[j] = channel_buffer[j];
			}
		}
	}

	HAL_UART_Receive_IT(IBUS_UART, rx_buffer, 32);
}

fly_ibus.h

/*
 * fly_ibus.h
 *
 *  Created on: Feb 13, 2022
 *      Author: LX
 */

#ifndef FLY_IBUS_H_
#define FLY_IBUS_H_

#include "main.h"
#include "usart.h"

/* User configuration */
#define IBUS_UART				(&huart1)
#define IBUS_UART_INSTANCE		(USART1)
#define IBUS_USER_CHANNELS		10			// Use 6 channels
/* User configuration */

#define IBUS_LENGTH				0x20	// 32 bytes
#define IBUS_COMMAND40			0x40	// Command to set servo or motor speed is always 0x40
#define IBUS_MAX_CHANNLES		14

void IBUS_INIT();
void IBUS_READ_CHANNEL(uint8_t user_channels);

#endif /* FLY_IBUS_H_ */

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用stm32解析富斯i6接收机(IBUS) 的相关文章

  • STM32在Debug时程序运行时间不对,Debug时定时器中断每次进入断点时间不对,定时器一开启就进入中断的解决办法

    一 Debug时程序时间不对解决办法 1 点击魔术棒 2 点击Debug 点击Settings 3 点击Trace 在Core Clock里修改为你的系统时钟 二 Debug时定时器中断每次进入断点时间不对 在Debug时 程序停下来 定时
  • 51单片机 数码管中断操作

    实践目的 1 掌握中断的概念和思想 2 掌握51单片机中断系统和相关软硬件设计 实践内容 1 利用单片机的P0口接数码管的字段脚 P1 0脚接共阴极 P3 2 P3 3引脚接独立按键产生外部中断信号 编写程序 当程序正常运行时数码管显示H字
  • 如何在 Cortex-M3 (STM32) 上从 RAM 执行函数?

    我正在尝试从 Cortex M3 处理器 STM32 上的 RAM 执行函数 该函数会擦除并重写内部闪存 所以我肯定需要在 RAM 中 但我该怎么做呢 我尝试过的是 使用 memcpy 将函数复制到 RAM 中的字节数组 检查它是否正确对齐
  • 如何让printf在STM32F103上工作?

    我是 STM32F103 世界的新手 我有一个STM32F103的演示代码 我正在使用arm none eabi来编译它 我尝试了在谷歌上可以找到的内容 但到目前为止没有任何效果 我已经花了三天时间来解决这个问题 任何人都可以给我一个运行良
  • HAL库STM32常用外设教程(二)—— GPIO输入\输出

    HAL库STM32常用外设教程 二 GPIO输入 输出 文章目录 HAL库STM32常用外设教程 二 GPIO输入 输出 前言 一 GPIO功能概述 二 GPIO的HAl库驱动 三 GPIO使用示例 1 示例功能 四 代码讲解 五 总结
  • 匹配 STM32F0 和 zlib 中的 CRC32

    我正在研究运行 Linux 的计算机和 STM32F0 之间的通信链路 我想对我的数据包使用某种错误检测 并且由于 STM32F0 有 CRC32 硬件 并且我在 Linux 上有带有 CRC32 的 zlib 所以我认为在我的项目中使用
  • SHT10温湿度传感器——STM32驱动

    实验效果 硬件外观 接线 3 3V供电 IIC通讯 代码获取 查看下方 END
  • HAL 锁定和解锁函数如何使用以及为什么?

    我试图理解另一位程序员编写的代码 它使用了I C http en wikipedia org wiki I C2 B2C通信以将数据写入 STM32 微控制器的 EEPROM 一般来说 我理解他的代码是如何工作的 但我不明白他为什么使用HA
  • 在 Atollic TrueStudio、STM32CubeMX 中导入 C 库

    我目前正在开发 STM32F767ZI Nucleo 板和一个小安全芯片 microchip atecc508a 通过 i2c 连接进行连接 该芯片有一个可用的库加密验证库 https github com MicrochipTech cr
  • 最终启动顺序错误 - STM32L476 的 Eclipse System Workbench 调试

    我正在尝试调试和运行 STM32L476 的简单汇编代码 我已经设置了 Eclipse Oxygen 在 Eclipse 中安装了最新版本的 System Workbench 插件并安装了 ST Link 驱动程序 IDE 成功构建了程序
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • 毕设开题分享 单片机智能教室系统(智能照明+人数统计)

    1 简介 Hi 大家好 今天向大家介绍一个学长做的单片机项目 单片机智能教室系统 智能照明 人数统计 大家可用于 课程设计 或 毕业设计 项目分享 https gitee com feifei1122 simulation project
  • Arm:objcopy 如何知道 elf 中的哪些部分要包含在二进制或 ihex 中?

    我正在开发一个项目 其中涉及解析arm elf 文件并从中提取部分 显然 elf 文件中有很多部分没有加载到闪存中 但我想知道 objcopy 到底如何知道要在二进制文件中包含哪些部分以直接闪存到闪存中 以arm elf文件的以下reade
  • 嵌入式开发--STM32G4系列片上FLASH的读写

    这个玩意吧 说起来很简单 就是几行代码的事 但楞是折腾了我大半天时间才搞定 原因后面说 先看代码吧 读操作 读操作很简单 以32位方式读取的时候是这样的 data IO uint32 t 0x0800F000 需要注意的是 当以32位方式读
  • 库函数点亮Led

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 例如 随着人工智能的不断发展 机器学习这门
  • 嵌入式 C++11 代码 — 我需要 volatile 吗?

    采用 Cortex M3 MCU STM32F1 的嵌入式设备 它具有嵌入式闪存 64K MCU固件可以在运行时重新编程闪存扇区 这是由闪存控制器 FMC 寄存器完成的 所以它不像a b那么简单 FMC 获取缓冲区指针并将数据刻录到某个闪存
  • STM32 上的 ADC 单次转换

    我正在研究 STM32 F103x 上的 ADC 编程 并从最简单的情况 单次转换开始 测量内部温度传感器 连接到 ADC1 的值 并使用 USART 将其发送到 COM 端口 目标似乎很明确 但是当我尝试将源代码下载到闪存时 它不会向 C
  • STM32内部时钟

    我对 STM32F7 设备 意法半导体的 Cortex M7 微控制器 上的时钟系统感到困惑 参考手册没有充分阐明这些时钟之间的差异 SYSCLK HCLK FCLK 参考手册中阅读章节 gt RCC 为 Cortex 系统定时器 SysT
  • 当端点和 PMA 地址均更改时,CubeMX 生成的 USB HID 设备发送错误数据

    我正在调试我正在创建的复合设备的问题 并在新生成的仅 CubeMX 代码中重新创建了该问题 以使其更容易解决 我添加了少量代码main 让我发送 USB HID 鼠标点击 并在按下蓝色按钮时使 LED 闪烁 uint8 t click re

随机推荐

  • C++的一个问题点,数组作为参数传递到函数之后,不能直接求出长度

    YU 原数组 xff0c 传递参数之后 结果是作为参数传进去之后是作为指针 xff0c 是不能求出长度的 xff0c 所以需要把长度提前求出作为参数传入该函数 反思 xff1a 最近C 43 43 Python xff0c java轮流用
  • 基于from flask import Flask,render_template 上传网页遇到的问题

    我们要上传多个页面形成一个网站 xff0c 首先我们需要在index xff08 一般这个都是首页面 xff09 查看其源码 找到类似 这段代码里面包括了前面的网站 xff0c 所以这时候我们只需要把它变成带使用的状态 xff0c 操作就是
  • 跨交换机的VLAN设置

    实现目标 xff1a 进行多台主机多个vlan接口进行互相通信 需要知识 xff1a 1 不同的vlan接口的是不能进行通信的 2 在要跨越多个交换机进行通信的时候要对进行交互的交换机进行共享vlan端口的设置 3 在设置网络号的时候应该注
  • Wireshark抓取cookie:用户名...,TCP报文等信息实战

    这里我们要先安装Wireshark xff0c 这里要注意的是一些低级版本刚刚下下来的时候是找不到网络接口的 xff0c 所以这时候要更新 xff0c 然后再下应该WinPro xff08 应该是这个 xff09 xff0c 之后就有网络接
  • 计算机网络知识点总结提纲(谢希仁)

    1 IOS OSI对王道书上的缩减总结 清晰pdf xff1a 链接 xff1a https pan baidu com s 1f6DqMsHky4kP8i9WQLvCew pwd 61 the3 提取码 xff1a the3 来自百度网盘
  • C++getline和 cin的探讨

    从结果可以看出 xff0c cin是会把空格部分舍弃的 如果是输入一个 然后空格在输入其他的 xff0c 因为cin默认把空格去调 xff0c 则后面的字符我的理解就是溢出 xff1f 所以报错了 getline功能就比较强大了 xff0c
  • Pixhawk RPi CM4 Baseboard 树莓派CM4安装Ubuntu20.04 server 配置ros mavros mavsdk

    文章目录 硬件安装Ubuntu Server20 04下载rpiboot工具下载imager刷写系统配置USB配置WIFI 开机安装桌面配置wifi配置串口安装ROS安装mavros安装MAVSDK PythonInternet设置最后 参
  • docker迁移镜像

    docker迁移本地镜像 本文为docker基本镜像操作之一 查看本镜像 docker images 迁移 xff08 拷贝 xff09 本地镜像到其他设备 1 打包 docker save o 路径 目标包名 tar 源镜像名 标签 2
  • C++Linux服务器学习之路——1

    前言 xff1a 为了让所学的计网知识融合于实际 xff0c 让操作系统里的理论去满足工程需求 xff0c 故通过借鉴30dayMakeServer的路线以及进行相应知识点的学习 part1 首先我们要理解socket 为应用层和传输层提供
  • 计网牛客刷图总结

    久不学忘记了 xff0c 1111 1111 61 255 xff0c ip地址是32位二进制组成 xff0c x 26就是说主机号有26位 xff0c 其他都是网络号 所以后面只有2位主机号 xff0c 234 61 11101010 x
  • C++力扣算法刷题算法分析

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • Invalid bound statement (not found)问题解决

    在网上基本的解决方案就是查看 namespace有没有对应 xff0c 但是我确定我的路径都是正确的 xff0c 如果发现这类问题可以先尝试确定路径的正确 之后如果还不行 xff0c 我们进行解决 xff1a 首先在target文件中查找是
  • C指针基础普及

    https www programiz com c programming c pointers 先放网站 xff0c 等我有时间再来补我的扩展
  • Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异)

    之前在培训新生的时候 xff0c windows环境下配置opencv环境一直教的都是网上主流的vs studio配置属性表 xff0c 但是这个似乎对新生来说难度略高 虽然个人觉得完全是他们自己的问题 xff0c 加之暑假之后对cmake
  • Spring Aop的使用(含示例)

    介绍 在软件业 xff0c AOP为Aspect Oriented Programming的缩写 xff0c 意为 xff1a 面向切面编程 xff0c 通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术 AOP是OOP的延续
  • 超好用的开发工具-VScode插件EIDE

    EIDE介绍 一款适用于8051 STM8 Cortex M RSCv的单片机开发环境 在 vscode上提供8051 xff0c STM8 Cortex M xff0c RISC V 项目的开发编译烧录等功能 使用文档 xff1a 简介
  • 直流编码电机双闭环(速度+角度)控制

    目录 1 PID框图 2 pid控制器的表达式 3 传感器数据获取 4 硬件设计 5 工程配置 6 软件部分程序配置 7 调参过程记录 本文已更新 xff0c 加上曲线调试 xff0c 更好效果 xff0c 更多内容 xff0c 详情 xf
  • OPENMV配置记录(一)

    文章目录 1 刷写固件2 开始配置openmv3 图像获取与显示4 修改图像 xff0c 获取像素 xff0c 添加元素5 使用图像进行基本操作 颜色追踪6 xff0c 识别码7 模版匹配8 通过比例的方法来求解距离9 组合使用 正好回家带
  • 为什么你的软件编译时没问题,运行时却出错?—— Java 中的异常再复盘

    从开发工具谈起 xff1a 这是我平常用的几个编辑器 记得我刚开始学 C 语言 xff0c 学 Java 的时候 xff0c 还是用 Notepad 43 43 这种文本编辑器写代码 xff0c 老师说是为了打基础 xff0c 加深记忆 后
  • 使用stm32解析富斯i6接收机(IBUS)

    文章目录 1 通信协议解析说明2 驱动程序设计3 实测4 使用串口空闲中断 43 DMA接收5 源码 1 通信协议解析说明 常见的官方遥控器大概如下所示 xff1a 常用的搭配接收机 xff1a 这里需要注意的是 xff1a i6是可以刷十