MT6825编码器在STM32中的使用

news2024/11/26 0:49:18

文章目录

  • 1、PWM 绝对值位置读取功能
    • 1.1 DataSheet说明
    • 1.2 硬件支持
    • 1.3 Cubemax配置及使用
    • 1.4 项目代码实现
    • 1.5 效果验证
    • 1.6 注意事项
  • 2、SPI 绝对值位置读取功能
    • 2.2 硬件支持
    • 2.3 Cubemax配置及使用
    • 2.4 项目代码实现

1、PWM 绝对值位置读取功能

1.1 DataSheet说明

在这里插入图片描述

1.2 硬件支持

在这里插入图片描述

1.3 Cubemax配置及使用

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

1.4 项目代码实现

PWM输入捕获定时器初始化:

void MX_TIM4_Init(void)
{

  /* USER CODE BEGIN TIM4_Init 0 */

  /* USER CODE END TIM4_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_SlaveConfigTypeDef sSlaveConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM4_Init 1 */

  /* USER CODE END TIM4_Init 1 */
  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 83;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 0xFFFF;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_IC_Init(&htim4) != HAL_OK)
  {
    Error_Handler();
  }
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
  sSlaveConfig.InputTrigger = TIM_TS_TI2FP2;
  sSlaveConfig.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sSlaveConfig.TriggerPrescaler = TIM_ICPSC_DIV1;
  sSlaveConfig.TriggerFilter = 0xA;
  if (HAL_TIM_SlaveConfigSynchro(&htim4, &sSlaveConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
  sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0xA;
  if (HAL_TIM_IC_ConfigChannel(&htim4, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  if (HAL_TIM_IC_ConfigChannel(&htim4, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM4_Init 2 */

  /* USER CODE END TIM4_Init 2 */

}

编码器初始化函数:

/**
  * @brief  
	* @param  void
  * @retval void
  */
void Bsp_Encoder_Init(void)
{
    if(sensor_peripheral.AuxEncoder_Sensor.encType==ENCODER_TYPE_MT_PWM_Abs)
	{
	    MX_TIM4_Init();
		  
        HAL_TIM_IC_Start_IT (&htim4, TIM_CHANNEL_1);
        HAL_TIM_IC_Start_IT (&htim4, TIM_CHANNEL_2);	

        ENC_485_RX_EN;		
	}

  MX_TIM3_Init();		//ENC

  HAL_TIM_Encoder_Start_IT(&htim3, TIM_CHANNEL_ALL);
}

输入捕获中断回调:

/**
  * @brief  Input Capture callback in non-blocking mode
  * @param  htim TIM IC handle
  * @retval None
  */
#define TIM_ENCODER_PWM TIM4
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance == TIM_ENCODER_PWM)  //
	{
       Encoder_MT_PWM_Readout();
	} 
}

输入捕获中断处理函数:

void Encoder_MT_PWM_Readout(void)
{
	if (htim4.Channel == HAL_TIM_ACTIVE_CHANNEL_2)
  {
		enc_mt_pwm_input.freqTemp[0]=HAL_TIM_ReadCapturedValue(&htim4, TIM_CHANNEL_2)+1;                                                // 1.读取整周期时间
		enc_mt_pwm_input.dutyTemp[0]=HAL_TIM_ReadCapturedValue(&htim4, TIM_CHANNEL_1)+1;                                                // 2.读取高电平时间
		__HAL_TIM_SetCounter(&htim4, 0);   
  }
}

角度读取函数(包含数据处理):

uint16_t Bsp_get_PWM_angle(void)
{
	enc_mt_pwm_input.usPwmAngReadFlag = 1;
	enc_mt_pwm_input.freq=enc_mt_pwm_input.freqTemp[0];
	enc_mt_pwm_input.duty=enc_mt_pwm_input.dutyTemp[0];
		
	if(enc_mt_pwm_input.dir)
	{
			if(enc_mt_pwm_input.duty>=enc_mt_pwm_input.freq)
				 enc_mt_pwm_input.duty=enc_mt_pwm_input.freq;
			else
				 enc_mt_pwm_input.duty=enc_mt_pwm_input.freq-enc_mt_pwm_input.duty;            //get negation
	}
	
	enc_mt_pwm_input.factor=enc_mt_pwm_input.freq/enc_mt_pwm_input.div;               //Acquire resolution
	enc_mt_pwm_input.res=enc_mt_pwm_input.freq-(enc_mt_pwm_input.offset_h+enc_mt_pwm_input.offset_l)*enc_mt_pwm_input.factor;
		
	if(enc_mt_pwm_input.duty>=enc_mt_pwm_input.factor * enc_mt_pwm_input.offset_h)
			 enc_mt_pwm_input.angle_temp=enc_mt_pwm_input.duty - enc_mt_pwm_input.factor * enc_mt_pwm_input.offset_h;    //get angle
	else
			 enc_mt_pwm_input.angle_temp=0;
		
	enc_mt_pwm_input.angle=enc_mt_pwm_input.angle_temp*(4095/(enc_mt_pwm_input.res*(84/(ENC_PWM_INPUT_PRE+1))));     /* get value from 0 to 4095 */
	
  return enc_mt_pwm_input.angle;
}

结构体定义及初始化:

#define SAMPLE_NUM               1                                              /* Number of samples */
typedef struct
{
	 uint8_t  sample_count;                /* counts of samples */
   uint16_t freqTemp[SAMPLE_NUM];        /* Acquisition frequency */
	 float freq;                           /* frequency */
	 uint16_t dutyTemp[SAMPLE_NUM];        /* Capture high level */
	 float duty;                           /* duty */
	 uint8_t dir;
	 uint8_t offset_h;                     //16 high 
	 uint8_t offset_l;                     //8 low 
	 uint16_t div;                         //4095+16+8=4119
	 float factor; 
	 float res;                            /* Resolution */
	 float angle_temp;	
   uint16_t angle;	
	 uint8_t  usPwmAngReadFlag;
}enc_mt_pwm_input_t;

extern enc_mt_pwm_input_t enc_mt_pwm_input;


/************************************************************************************/
enc_mt_pwm_input_t enc_mt_pwm_input={
         .sample_count=0,
	     .freqTemp={0},
		 .freq=0,
		 .dutyTemp={0},
		 .duty=0,
		 .dir=1,
		 .offset_h=16,
		 .offset_l=8,
		 .div=4119,
		 .factor=0,
		 .res=0,
		 .angle=0,
		 .usPwmAngReadFlag = 0
};

1.5 效果验证

在这里插入图片描述角度(占空比)周期化变化,满足预期。

1.6 注意事项

在这里插入图片描述

2、SPI 绝对值位置读取功能

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

2.2 硬件支持

MT6825编码器电路
MT6825编码器电路
驱动板电路在这里插入图片描述

2.3 Cubemax配置及使用

在这里插入图片描述

2.4 项目代码实现

SPI外设初始化:

/* SPI1 init function */
void MX_SPI1_Init(void)
{

  /* USER CODE BEGIN SPI1_Init 0 */

  /* USER CODE END SPI1_Init 0 */

  /* USER CODE BEGIN SPI1_Init 1 */

  /* USER CODE END SPI1_Init 1 */
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;  //8 10.5Mbit/s 64 1.3125Mbits 16 5.25Mbit/s
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */

  /* USER CODE END SPI1_Init 2 */

}

结构体及初始化:

typedef struct{
	uint16_t  cmd[3];
	uint16_t  rec_data[3];
	uint8_t  no_mag_warning_flag;
	uint8_t  over_speed_flag;
	uint8_t  pc1_flag;
	uint8_t  pc2_flag;
	uint8_t  pc1_count;
	uint8_t  pc2_count;
	uint8_t  err;
	uint32_t sample_data;
	uint32_t angle_data;
	uint32_t pre_angle_data;
}mag_enc_t;

extern mag_enc_t mag_enc;

/**********************************************************/
mag_enc_t mag_enc = {
    .cmd = {0x8300, 0x8400, 0x8500},
    .rec_data = {0, 0, 0},
    .no_mag_warning_flag = 0,
    .over_speed_flag = 0,
    .pc1_flag = 0,
    .pc2_flag = 0,
    .pc1_count = 0,
    .pc2_count = 0,
	.err = 0,
    .sample_data = 0,
	.angle_data =0,
	.pre_angle_data =0
};

SPI读取绝对值位置:

uint32_t SPI1_MT6825_fast_ReadData(void)
{
	short timeOut=1000;
	
	SPI1_CS_LOW;
//	HAL_SPI_Transmit(&hspi1 ,(unsigned char *)&mag_enc.cmd[0] ,1,200);
//	HAL_SPI_Receive(&hspi1 ,(unsigned char *)&mag_enc.rec_data[0] ,3,200);
    HAL_SPI_TransmitReceive(&hspi1 ,(unsigned char *)&mag_enc.cmd[0] ,(unsigned char *)&mag_enc.rec_data[0] ,3,200 );
	while( hspi1.State == HAL_SPI_STATE_BUSY )
	{
	  if (timeOut-- ==0) return 0;
	}   // wait for transmission complete
  SPI1_CS_HIGH;

  mag_enc.angle_data=((mag_enc.rec_data[0]&0x00FF)<<10)+((mag_enc.rec_data[1]&0xFC00)>>6)+((mag_enc.rec_data[1]&0x00F0)>>4);
  return mag_enc.angle_data;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【计算机网络篇】物理层(4)信道的极限容量,信道复用技术

文章目录 &#x1f354;信道的极限容量&#x1f6f8;造成信号失真的主要因素⭐码元的传输速率 &#x1f6f8;奈氏准则&#x1f6f8;香农公式&#x1f388;练习 &#x1f5d2;️小结 &#x1f354;信道复用技术⭐常见的信道复用技术&#x1f388;频分复用FDM&#x1f388;时分复…

TouchGFX之性能测量

TouchGFX Core开放了几个信号&#xff0c;可用于测量性能。 当这些信号在内部触发时&#xff0c;用户可在应用程序中同步触发单个GPIO&#xff0c;从而实现“渲染时间”和其他有用信号的可视化。 信号在GPIO.hpp中定义 /* 用于操作GPIO的接口类&#xff0c;以便在目标硬件上进…

ANOMALY TRANSFORMER: TIME SERIES ANOMALY DETECTION WITH ASSOCIATION DISCREPANCY

论文题目&#xff1a; ANOMALY TRANSFORMER: TIME SERIES ANOMALY DETECTION WITH ASSOCIATION DISCREPANCY 发表会议&#xff1a;ICLR 2022 论文地址&#xff1a;https://openreview.net/pdf?idLzQQ89U1qm_ 论文代码&#xff1a;https://github.com/thuml/Anomaly-Transforme…

“惠才俊·暖同行”成都蓉北商圈“政策进楼宇”系列活动第二站

活动时间 2024年3月27日下午14:00活动地点 四川省成都市金牛区福堤路99号数媒大厦(5楼共享会议室)主办单位 成都蓉北商圈发展服务局 成都市金牛区新经济和科技局 成都树莓信息技术有限公司协办单位 蓉北人力资源服务产业园 主讲单位 蓉北商圈服务局、区新经济和科技局、国…

PyQt上手指南

文章目录 前言PyQt的好处从一个最简单的例子入手PyQt5基础组件体系源码结构 Qt Designer基础布局高级界面Web控件 多线程列表图形绘制PyQt5.QtGuiPyQtGraphmatplotlib和PyQt结合和mplfinance结合 工具使用打包链接 前言 用户界面开发&#xff0c;我搞过visual C MFC、Delphi V…

thinkphp 使用phpmailer发送邮件以及使用消息队列异步解耦发送邮件

邮箱注册配置&#xff1a; 注册163或qq邮箱&#xff0c;开启smtp服务 25端口 ssl则465端口 下载phpmailer composer 安装phpmailer composer require phpmailer/phpmailer设置配置文件 配置文件 书写代码 代码 <?php namespace app\job; use think\facade\Log; us…

安卓(uniapp)上架华为踩坑合集

1.如果是离线打包&#xff0c;注意在manifest那里修改&#xff1a; android:debuggablefalse2…您的应用targetsdk版本低于30&#xff0c;不符合华为应用市场审核标准。 修改建议&#xff1a;请您将应用targetsdk等级升级到30或30以上。 因为之前我升到30被打回来过&#xff…

【LAMMPS学习】三、构建LAMMPS(5)可选的构建设置

3、构建LAMMPS 3.5.可选的构建设置 LAMMPS 可以通过多种可选设置来构建。每个小节都解释了如何使用 CMake 和 make 进行构建。 3.5.1. C11 标准合规性 编译 LAMMPS 需要 C11 标准兼容编译器。 LAMMPS 2020 年 3 月 3 版是核心代码和大多数软件包与之前的 C98 标准兼容的最…

使用 Flink + Faker Connector 生成测试数据压测 MySQL

博主历时三年精心创作的《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详情&#xff0c;…

基于java校园在线打印预约系统设计与实现

摘 要 二十一世纪以来&#xff0c;计算机行业应用技术不断发展&#xff0c;人们的观念也在不断改变。传统打印行业&#xff0c;用户已经意识到传统的打印文件方法等待时间太长。校园在线打印预约系统可以通过网络来打印文件&#xff0c;用户可以在特定的时间预约打印文件&#…

【RabbitMQ | 第一篇】消息队列基础知识

文章目录 1.消息队列基础知识1.1什么是消息队列&#xff1f;1.2消息队列有什么用&#xff1f;&#xff08;结合项目说&#xff09;1.2.1异步处理1.2.2削峰/限流1.2.3降低系统耦合性1.2.4实现分布式事务 1.3消息队列的缺点1.4JMS和AMQP1.4.1 JMS的两种消息模型&#xff08;1&…

PSQLException:limit must not be negative

limit must not be negative异常原因及解决 在PostgreSQL中遇到PsqlException: limit must not be negative异常&#xff0c;通常是由于在执行SQL查询时&#xff0c;传递给LIMIT子句的值为负数导致的。LIMIT子句用于限制查询结果的数量&#xff0c;其值必须是非负整数。 解决这…

C++ Qt开发:QUdpSocket实现组播通信

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍如何运用QUdpSocket组件实现基于UDP的组播通信…

15届蓝桥杯第二期模拟赛所有题目解析

文章目录 &#x1f9e1;&#x1f9e1;t1_求余&#x1f9e1;&#x1f9e1;思路代码 &#x1f9e1;&#x1f9e1;t2_灌水&#x1f9e1;&#x1f9e1;思路代码 &#x1f9e1;&#x1f9e1;t3_字符显示&#x1f9e1;&#x1f9e1;思路代码 &#x1f9e1;&#x1f9e1;t4_区间最大和…

Mysql:行锁,间隙锁,next-key锁?

注&#xff1a;以下讨论基于InnoDB引擎。 文章目录 问题引入猜想1&#xff1a;只加了一行写锁&#xff0c;锁住要修改的这一行。语义问题数据一致性问题 猜想2&#xff1a;要修改的这一行加写锁&#xff0c;扫描过程中遇到其它行加读锁猜想3&#xff1a;要修改的这一行加写锁&…

[ C++ ] STL---list的使用指南

目录 list简介 list的常用接口 构造函数 赋值运算符重载 迭代器 容量相关接口 元素访问接口 修改相关接口 头插push_front() 头删pop_front() 尾插push_back() 尾删pop_back() insert() erase() list的迭代器失效 list简介 1. list是可以以O(1)的时间复杂度在任意…

ORACLE 上机操作3-1

sqlplus / as sysdba 显示parameter结构 SQL> set pause on SQL> desc v$parameter 显示系统静态参数 SQL> select name from v$parameter where isses_modifiable FALSE; 显示db_files是否可以用命令修改 SQL> select isses_modifiable, issys_modifiable, ismod…

使用 OpenAI 的 Embedding模型 构建知识向量库并进行相似搜索

OpenAI的embedding模型的使用 首先第一篇文章中探讨和使用了ChatGPT4的API-Key实现基础的多轮对话和流式输出&#xff0c;完成了对GPT-API的一个初探索&#xff0c;那第二步打算使用OpenAI的embedding模型来构建一个知识向量库&#xff0c;其实知识向量库本质上就是一个包含着一…

四、HarmonyOS应用开发-ArkTS开发语言介绍

目录 1、TypeScript快速入门 1.1、编程语言介绍 1.2、基础类型 1.3、条件语句 1.4、函数 1.5、类 1.6、模块 1.7、迭代器 2、ArkTs 基础&#xff08;浅析ArkTS的起源和演进&#xff09; 2.1、引言 2.2、JS 2.3、TS 2.4、ArkTS 2.5、下一步演进 3、ArkTs 开发实践…

【Linux】网络基础一

网络基础一 1.计算机网络背景1.1 网络发展1.2 认识 “协议” 2.网络协议初识2.1 协议分层2.2 OSI七层模型2.3 TCP/IP五层(或四层)模型 3. 网络传输基本流程3.1 网络传输流程图 4.数据包封装和分用5.网络中的地址管理 从今天开始我们将要从系统横跨到网络的学习了&#xff0c;因…