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

ops/2024/11/13 19:54:55/

MT6701_0">
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;elsereturn 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 modeHAL_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 HIGHAngleIn24bits= (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;elsecrc = (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

http://www.ppmy.cn/ops/6859.html

相关文章

linux设备树-of_parse_phandle_with_args

1.设备树实例 interrupt-controller1 { compatible "vendor,gic"; #interrupt-cells <2>; interrupt-controller; reg <0x01 0x1000>; }; deviceA { compatible "vendor,device-a"; reg <0x02 0x100>; interrupts <&interr…

物联网与服务器有什么样的联系?

当今物联网是比较火的词汇&#xff0c;那么物联网是什么呢&#xff1f;物联网对人们的生活会产生哪些影响呢&#xff1f;。说的通俗一点物联网就是将设 备接入网络&#xff0c;实现设备智能化。那么物联网与服务器又有着怎样的联系呢&#xff1f;下面我们就一起来探讨一下这个问…

MySql运维篇

目录 一.日志 1.1日志分类 1.2Error Log 1.3BinaryLog 1.4SlowQuery Log 二.备份 2.1备份原因 2.2备份目标 2.3备份技术 2.3.1物理备份 2.3.2逻辑备份 2.4备份方式 2.4.1完全备份 2.4.2增量备份 2.4.3差异备份 2.5备份环境准备 2.6完全备份实验 2.6.1完全备…

Ubuntu 中如何高效的使用grep命令

grep 是一个命令行实用程序&#xff0c;在 Unix 和类 Unix 操作系统中用于在文本文件和命令输出中搜索模式。它的名称代表“全局正则表达式打印”。 基本语法&#xff1a; grep [选项] 模式 [文件 …] **模式&#xff1a;**你想搜索的文本模式。它可以是一个简单的字符串或一…

考试酷基本功修炼课学习历程_FPGA成长篇

本文为明德扬原创文章&#xff0c;转载请注明出处&#xff01;作者&#xff1a;明德扬学员&#xff1a;考试酷账号&#xff1a;11167760 我是硬件工程师&#xff0c;日常工作中主要跟数字电路、模拟电路、嵌入式系统打交道&#xff0c;当然也会涉及到FPGA&#xff0c;但是苦于…

手把手学浪视频怎么保存到本地

很多人在学浪app上面购买了课程,但是并不是所有课程都是永久观看,所以就想要下载下来,进行永久观看 由于很多人都是小白用户,考虑到这一点,我封装成软件,大家不需要考虑视频m3u8地址是怎么获取的、KEY是怎么解密的,只需要掌握工具怎么用 工具我也给大家准备好了,有需要的自己…

6.SpringBoot 日志文件

文章目录 1.日志概述2.日志作用3.使用和观察日志3.1如何观察日志3.2使用日志3.3日志级别3.4日志持久化3.5日志分割 4.日志框架4.1门面模式(外观模式)4.2 SLF4J框架介绍4.3 日志格式的说明4.3.1日志名称 5.日志颜色设置6.总结 大家好&#xff0c;我是晓星航。今天为大家带来的是…

头歌实训作业答案c++

由于“头歌实训作业答案C”这个表述可能指的是某个特定课程或机构的C编程作业答案&#xff0c;通常这类作业答案不会公开分享&#xff0c;因为这涉及到版权和学术诚信的问题。但我可以提供一些C编程的通用指导和资源&#xff0c;帮助你完成实训作业。 ### C编程基础 1. **变量…