HAL STM32 SSI/SPI方式读取MT6701磁编码器获取角度例程

HAL STM32 SSI/SPI方式读取MT6701磁编码器获取角度例程


  • 📍相关篇《HAL STM32 I2C方式读取MT6701磁编码器获取角度例程》
  • 📌当前最新MT6701数据手册:https://www.magntek.com.cn/upload/MT6701_Rev.1.8.pdf
  • 📜SSI协议读角度,时序和数据关系
    在这里插入图片描述
    在这里插入图片描述

SSI方式完全可以使用3个IO配置为输入输出模式(两个配置为输出,一个配置为输入),通过SSI协议,读取电平状态,实现对数据解析。

  • 📝SSI核心代码实现:(参考《STM32 HAL库 驱动 MT6701 磁编码器》)
#define Loss_of_Track       4
#define Button_Detected     3
#define Field_Weak          2
#define Field_Strong        1
#define Normal              0


/*
 * SSI 方式读取信息
 * mode == 0 返回角度信息,0~360 浮点数
 * mode == 1 返回磁场信息
 */
double ReadDataSSI(uint8_t mode)
{
    uint8_t RawData[25] = {0};
    uint16_t angle = 0;
    double fangle = 0;

    HAL_GPIO_WritePin(SSI_CSN_GPIO_Port,SSI_CSN_Pin,GPIO_PIN_RESET);        //起始信号
    Delay_us(2);

    HAL_GPIO_WritePin(SSI_CLK_GPIO_Port,SSI_CLK_Pin,GPIO_PIN_RESET);        //跳过第一个时钟沿
    Delay_us(2);
    HAL_GPIO_WritePin(SSI_CLK_GPIO_Port,SSI_CLK_Pin,GPIO_PIN_SET);
    Delay_us(2);

    for(uint8_t i = 0; i < 25; i++)                                                                 //读取数据
    {
        HAL_GPIO_WritePin(SSI_CLK_GPIO_Port,SSI_CLK_Pin,GPIO_PIN_RESET);
        RawData[i] = HAL_GPIO_ReadPin(SSI_DI_GPIO_Port,SSI_DI_Pin);
        HAL_GPIO_WritePin(SSI_CLK_GPIO_Port,SSI_CLK_Pin,GPIO_PIN_SET);
        Delay_us(2);
    }
    HAL_GPIO_WritePin(SSI_CSN_GPIO_Port,SSI_CSN_Pin,GPIO_PIN_SET);          //结束信号

    for(uint8_t i = 0; i < 14; i++)
        angle += RawData[i] * (2 << (13 - i));
    fangle = (double)(angle * 180.0) / 16384.0;     //角度信息

    switch (mode)
    {
        case 0:
            return fangle;
        case 1:
        {
            if(RawData[14])
                return Loss_of_Track;
            else if(RawData[15])
                return Button_Detected;
            else if(RawData[16])
                return Field_Weak;
            else if(RawData[17])
                return Field_Strong;
            else
                return Normal;
        }
        default:
            return 0;
    }
}

  • 🌿引脚配置:
    在这里插入图片描述

📚SSI测试工程

链接:https://pan.baidu.com/s/1es233q_NBo_s_fLkgbmTjw?pwd=r90i 
提取码:r90i

⛳SPI方式

📗STM32 SPI参数配置:
  • 🌿STM32CubeMX中SPI基本配置信息:(其中Data Size,这里选择配置的是8位,配置16位也是可以的,不过软件编程上就与8位的编程代码就不同,不通用)。
    在这里插入图片描述

  • SPI串行同步时钟可以设置为不同的极性(Clock Polarity ,CPOL)与相位(Clock Phase ,CPHA)。

  • 时钟的极性(CPOL)用来决定在总线空闲时,同步时钟(SCK)信号线上的电位是高电平还是低电平。

  • 当时钟极性为0时(CPOL=0),SCK信号线在空闲时为低电平;当时钟极性为1时(CPOL=1),SCK信号线在空闲时为高电平;

  • 时钟的相位(CPHA)用来决定何时进行信号采样。

  • 当时钟相位为1时(CPHA=1),在SCK信号线的第二个跳变沿进行采样;这里的跳变沿究竟是上升沿还是下降沿,取决于时钟的极性。当时钟极性(CPOL)为0时,取下降沿;当时钟极性(CPOL)为1时,取上升沿;如下图:
    在这里插入图片描述

  • 🔖设置依据:根据手册SSI协议,可知:CLK空闲状态为low,决定CPOL配置为low,推荐CLK下降沿采集数据,那就配置CPHA为2,在SCK信号线的第二个跳变沿进行采样。
    在这里插入图片描述


  • 🌾 补充:
    • 当时钟相位为0时(CPHA=0),在SCK信号线的第一个跳变沿进行采样。跳变沿同样与时钟极性有关:当时钟极性为0时,取上升沿;当时钟极性为1时,取下降沿;如下图:
      在这里插入图片描述
  • 对应:
    在这里插入图片描述

SPI数据读取和转换实现

void MT6701_Read_RAW(uint8_t* pBuffer)   
{ 
	uint16_t i; 
	 MT6701_CSN_CLR;//MT6701_CSN=0  //片选 
	for (i = 0; i < 4; i++)
	{ 
		pBuffer[i]=SPIx_ReadWriteByte(0xFF);    //循环读入字节数据  
	}	
	 MT6701_CSN_SET;  //MT6701_CSN=1
} 

/*!
 *  @brief  Return position of encoder
 *  @return Angle value of encoder position
 */
float angleRead( void ){
	float angle_f = 0.0f;
	uint8_t data[3];
	uint16_t angle_u16;
	
	MT6701_Read_RAW(data);
		angle_u16  = (uint16_t)(data[1] >> 2);
		angle_u16 |= ((uint16_t)data[0] << 6);
		 angle_f =  (float)angle_u16 * (360.0f/16384.0f);
	return angle_f;
}
  • 🎉优化处理
//angle_raw返回原始角度数据,angle转换后的角度值:0-360,field_status磁场强度;
void mt6701_read(uint16_t*angle_raw, float*angle, uint8_t*field_status)
{
    float angle_f = 0.0f;
    uint8_t status;
    uint8_t data[3];
    uint16_t angle_u16;

    MT6701_Read_RAW(data);
    angle_u16 = (uint16_t)(data[1] >> 2); //原始值
    angle_u16 |= ((uint16_t)data[0] << 6);
    status = (data[2] >> 6);
    status |= (data[1] & 0x03) << 2;
    if(angle_raw != NULL) {
        *angle_raw = angle_u16;
    }

    if(angle != NULL) {

        angle_f = (float)angle_u16 * (360.0f / 16384.0f);
        *angle = angle_f;
    }
    if(field_status != NULL) {
        *field_status = status & 0x03;
    }
}
  • 🔖测试效果:
    在这里插入图片描述

📚SPI测试代码

链接:https://pan.baidu.com/s/1X3vUEo5mW3vEGRbXftowxw?pwd=7o6g 
提取码:7o6g

📙读取24位数据并CRC校验功能测试

  • 📝代码实现部分:
 unsigned int Angle = 0;
uint32_t AngleIn24bits = 0;
uint8_t Spi_TxData[4]={0x83,0xff,0xff,0xff};///03 04 05 寄存器存角度
uint8_t Spi_pRxData[4]={0};

uint32_t ReadAngle(void)
{
    //Read in Burst mode
	    
	    HAL_GPIO_WritePin(MT6701_CS_GPIO_Port, MT6701_CS_Pin, GPIO_PIN_RESET);///CSN LOW   
		HAL_SPI_TransmitReceive(&hspi1, &Spi_TxData[0], &Spi_pRxData[0],0x03,0xffff);
	    HAL_GPIO_WritePin(MT6701_CS_GPIO_Port, MT6701_CS_Pin, GPIO_PIN_SET);///CSN HIGH

	    AngleIn24bits= (Spi_pRxData[0]<<16)|(Spi_pRxData[1]<<8)|(Spi_pRxData[2]);
	 //   AngleIn14bits >>= 10;
	   	
        return (AngleIn24bits);	    
}
uint8_t crc6(uint8_t *data, uint8_t length)  
{  
	uint8_t i;  
	uint8_t crc = 0;    // Initial value  
	
	while(length--)  
	{  
		 crc ^= *data++; // crc ^= *data; data++;
		for (i=6; i>0; --i)  
        { 
            if (crc & 0x20)
                crc = (crc << 1) ^ 0x03;
            else
                crc = (crc << 1);
        }
	 }  
	return crc&0x3f;  
} 

int main(void)
{

  /* USER CODE BEGIN 1 */
	uint8_t s[3];
	uint8_t crcvalue = 0;
	uint32_t AngleInHex = 0;
					float angle=0.0f;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		 AngleInHex = ReadAngle();
			s[0]=AngleInHex>>18;
			s[1]=AngleInHex>>12;
			s[2]=AngleInHex>>6;
	        
			if(crc6(s, 3)==(AngleInHex&0x3f))
			{   
				printf("\r\nReadcrc=0x%x\r\n",AngleInHex&0x3F);
				
				printf("Cacucrc=0x%x\r\n",crc6(s, 3)&0x3F);
				printf("%.2f\r\n",(AngleInHex>>10)*360/16384.0);
				printf("%X\r\n",AngleInHex);
				 HAL_Delay(5);
				printf("\n-------------------\n");
				 HAL_Delay(5);
			}
			else
			{
				printf("\r\nReadcrc=0x%x\r\n",AngleInHex&0x3F);
				printf("Cacucrc=0x%x\r\n",crc6(s, 3)&0x3F);
			    printf("CRC check error!\r\n");
				printf("%.2f\r\n",(AngleInHex>>10)*360/16384.0);
				 HAL_Delay(5);
				printf("\n\r--------------------\n\r");
			}
		HAL_Delay(500);
  }
  /* USER CODE END 3 */
}
  • 📄打印测试

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

📚读取数据并带CRC校验测试工程

链接:https://pan.baidu.com/s/1p-tUWT0P2aetlLwCr9X-IQ?pwd=1epn 
提取码:1epn

📘SPI +DMA读取数据并带CRC校验测试工程

  • 🥕基于读取数据并带CRC校验测试工程版本基础上调整而来的。
链接:https://pan.baidu.com/s/1GCT23_lJC4ocbHautazoxg?pwd=9kvi 
提取码:9kvi

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/562273.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

flutter 实现表单的封装包含下拉框和输入框

一、表单封装组件实现效果 //表单组件 Widget buildFormWidget(List<InputModel> formList,{required GlobalKey<FormState> formKey}) {return Form(key: formKey,child: Column(children: formList.map((item) {return Column(crossAxisAlignment: CrossAxisAlig…

4月21日Linux运维用户相关的添加,分组,修改权限等shell脚本开发第一天

4月21日运维用户相关的添加&#xff0c;分组&#xff0c;修改权限等shell脚本开发第一天 第一天主要实现前2个功能 ​ 主要卡在了&#xff1a; 正确的写法如下&#xff0c;注意[]中的空格&#xff0c;要求很严格&#xff01;&#xff01;&#xff01; #!/bin/bash # 先查看已…

LIUNX系统编程:文件系统

目录 1.创建文件的本质 1.1目录本身也是一个文件&#xff0c;也有他自己的inode 1.2LINUX创建文件&#xff0c;一定是在目录中创建文件。 2.重谈文件的增删查改 2.1为什目录没有写权限&#xff0c;就不能新建文件。 2.2.文件的查找 3.路径 3.1挂载 3.2如何理解挂载 1.创…

【QT学习】8.qt事件处理机制,事件过滤器,自定义事件

1.qt事件处理机制 事件处理&#xff1a; 当用户移动鼠标的时候 &#xff0c;创建一个 鼠标移动事件对象 然后把这个对象放到 事件队列里面去&#xff0c;事件管理器 从队列中 取出事件&#xff0c;然后 调用其对应的事件处理函数。 多态机制&#xff1a; &#x…

2023年图灵奖颁发给艾维·维格森(Avi Wigderson),浅谈其计算复杂性理论方面做出的重要贡献

Avi Wigderson是一位以色列计算机科学家&#xff0c;他在计算复杂性理论方面做出了重要的贡献&#xff0c;并对现代计算产生了深远的影响。 Wigderson的主要贡献之一是在证明计算复杂性理论中的基本问题的困难性方面。他证明了许多经典问题的困难性&#xff0c;如图论中的图同构…

Day08React——第八天

useEffect 概念&#xff1a;useEffect 是一个 React Hook 函数&#xff0c;用于在React组件中创建不是由事件引起而是由渲染本身引起的操作&#xff0c;比如发送AJAx请求&#xff0c;更改daom等等 需求&#xff1a;在组件渲染完毕后&#xff0c;立刻从服务器获取频道列表数据…

每天五分钟机器学习:神经网络模型参数的选择

本文重点 在深度学习和人工智能的浪潮中,神经网络作为其中的核心力量,发挥着举足轻重的作用。然而,神经网络的性能并非一蹴而就,而是需要经过精心的参数选择和调优。 神经网络由大量的神经元组成,每个神经元之间通过权重进行连接。这些权重,以及神经元的偏置、激活函数…

Adobe Acrobat PDF 2024

Adobe Acrobat PDF 2024正式发布&#xff01;支持Windows和macOS系统&#xff0c;新界面做了轻微调整。 下载地址 Windows客户端&#xff1a;https://www.123pan.com/s/f43eVv-GKZKd.html macOS客户端&#xff1a;https://www.123pan.com/s/f43eVv-PKZKd.html

idea在controller或者service使用ctrl+alt+b进入方法后,如何返回到 进入前的那一层

idea在controller或者service使用ctrlaltb进入方法后&#xff0c;如何返回到进入方法的最外层 解决方案使用 ctrlalt ← /→← /→ 键盘上的左右键盘

数据结构练习-算法与时间复杂度

----------------------------------------------------------------------------------------------------------------------------- 1. 设n是描述问题规模的非负整数&#xff0c;下列程序段的时间复杂度是( )。 x0;while(n>(x1)*(x1)xx1; A.O(logn) B.O(n^(1/2)) C.O(n)…

【周总结】总结下这周的工作、(hashmap)知识巩固等

总结 这周开发任务已经全部结束&#xff0c;主要是在修改一些 jira 问题 需要反思的是&#xff0c;中间改造接口时&#xff0c;数据库表需要新增一个字段&#xff0c;这个 sql 脚本忘记加到 basetable.sql 脚本里面了&#xff0c;这样如果是新建的项目&#xff0c;创建的时候不…

百万级别mysql性能耗时自测

注&#xff1a;实际情况会因建表语句和服务器的配置造成偏差 测试环境 &#xff1a;8核CPU 16G运行内存 建表语句&#xff1a; CREATE TABLE user (id bigint(11) NOT NULL AUTO_INCREMENT,username varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,birthday varchar(255)…

AppWizard的软件开发GUI的使用记录

前言 这个软件是针对于EmWin6.0以上的这个软件在emWin的基础上又封装了一层,也只提供的API函数.基于消息事件为核心&#xff08;个人理解&#xff09;一些组件的之间的交互可以通过软件界面进行配置,比较方便本次是基于模拟器进行测试记录,观察api 按键和文本之间的关联 通过…

软考141-上午题-【软件工程】-杂题+小结

一、杂题 真题1&#xff1a; 真题2&#xff1a; 真题3&#xff1a; 真题4&#xff1a; 真题5&#xff1a; 真题6&#xff1a; 真题7&#xff1a; 真题8&#xff1a; 真题9&#xff1a; 真题10&#xff1a; 真题11&#xff1a; 真题12&#xff1a; 真题13&#xff1a; 真题14&a…

深入剖析Spring框架:循环依赖的解决机制

你好&#xff0c;我是柳岸花开。 什么是循环依赖&#xff1f; 很简单&#xff0c;就是A对象依赖了B对象&#xff0c;B对象依赖了A对象。 在Spring中&#xff0c;一个对象并不是简单new出来了&#xff0c;而是会经过一系列的Bean的生命周期&#xff0c;就是因为Bean的生命周期所…

05集合-CollectionListSet

Collection体系的特点、使用场景总结 如果希望元素可以重复&#xff0c;又有索引&#xff0c;索引查询要快? 用ArrayList集合, 基于数组的。(用的最多) 如果希望元素可以重复&#xff0c;又有索引&#xff0c;增删首尾操作快? 用LinkedList集合, 基于链表的。 如果希望增…

亚马逊测评自养号策略:手机与PC结合的重要性

亚马逊测评的核心关键技术在于精心培养买家账号&#xff0c;之所以称之为核心关键&#xff0c;原因在于测评下单的首要条件是拥有一个活跃的买家账号。买家账号并非一次性使用&#xff0c;因此&#xff0c;养号过程显得至关重要。然而&#xff0c;在养号的过程中&#xff0c;很…

Python基础03-深入探索Python字典操作

在Python中&#xff0c;字典是一种非常强大和灵活的数据结构&#xff0c;可以存储键值对&#xff0c;并提供了许多方法来操作这些键值对。本文将深入探讨Python字典的各种操作&#xff0c;包括如何创建、修改、合并和查找字典中的元素。 1. 创建字典 要创建一个字典&#xff…

【数字电路与系统】【北京航空航天大学】实验:时序逻辑设计——三色灯开关(三)、功能仿真测试

本次实验&#xff08;一&#xff09;见博客&#xff1a;【数字电路与系统】【北京航空航天大学】实验&#xff1a;时序逻辑设计——三色灯开关&#xff08;一&#xff09;、实验指导书 本次实验&#xff08;二&#xff09;见博客&#xff1a;【数字电路与系统】【北京航空航天…

【gdb调试】在ubuntu环境使用gdb调试一棵四层二叉树的数据结构详解

目录 &#x1f31e;1. 整体思路 &#x1f31e;2. 准备内容 &#x1f33c;2.1 配置.c文件 &#x1f33c;2.2 准备测试程序 &#x1f33c;2.3 GDB调试基础 &#x1f31e;3. GDB调试四层二叉树 &#x1f33c;3.1 测试程序分析 &#x1f33c;3.2 gdb分析 &#x1f33b;1. …