HC32F103BCB使用SPI获取AS5040编码器数据

1.AS5040介绍

2.硬件电路

硬件上使用SSI通信方式连接。

3.配置硬件SPI

查看手册,AS5040时序

可以看到在空闲阶段不发生数据传输的时候时钟(CLK)和数据(DO)都保持高电位(tCLKFE阶段),在第一个脉冲的下降沿触发编码器载入发送数据,然后每一个时钟脉冲的上升沿编码器送出数据,数据的高位在前,低位在后,共发送10个数据(对应其分辨率10BIT),后面是6BIT校验数据;当传送完所有的位数以后时钟回到高电平,数据也对应回到高电平,直到下一个传输周期到达。

谢谢此文章作者的分享

stm32使用SPI获取磁性单圈绝对值编码器数据 - 知乎​​​​​​​

代码操作:

/*
*********************************************************************************************************
*
*	模块名称 : BSP_AS5040.C
*	文件名称 : 编码器驱动模块
*	版    本 : V0.1
*	说    明 :在空闲阶段不发生数据传输的时候时钟(CLK)和数据(DO)都保持高电位(tCLKFE阶段),
在第一个脉冲的下降沿触发编码器载入发送数据
然后每一个时钟脉冲的上升沿编码器送出数据,数据的高位在前,低位在后,共发送10个数据(对应其分辨率10BIT)
当传送完所有的位数以后时钟回到高电平,数据也对应回到高电平,直到下一个传输周期到达。对比四种模式,只有当CPOL配置成“0”和CPHA配置成“1”的时候 才符合每一个时钟脉冲的上升沿编码器送出数据的情况。使用SPI获取AS5040磁性单圈绝对值编码器数据。 10bit+6bit
*********************************************************************************************************
*/
#include "bsp.h"/* GPIO口对应配置 *///绝对值编码器  CSN引脚     A4  黄色 29				--SPI1_NSS
#define ABSCSN_PORT         GPIOA
#define ABSCSN_RCC	        RCC_APB2Periph_GPIOA
#define ABSCSN_PIN          GPIO_Pin_4//绝对值编码器  CLK引脚     A5  绿色 30				---SPI1_SCK
#define ABSCLK_PORT         GPIOA
#define ABSCLK_RCC	        RCC_APB2Periph_GPIOA
#define ABSCLK_PIN          GPIO_Pin_5//绝对值编码器  DO引脚     A6  蓝色 31				---SPI1_MISO
#define ABSDO_PORT         GPIOA
#define ABSDO_RCC	         RCC_APB2Periph_GPIOA
#define ABSDO_PIN          GPIO_Pin_6//时钟线高低电平
#define ABSCLK_H            GPIO_SetBits(ABSCLK_PORT,ABSCLK_PIN)
#define ABSCLK_L            GPIO_ResetBits(ABSCLK_PORT,ABSCLK_PIN)//片选高低电平
#define ABSCSN_H            GPIO_SetBits(ABSCSN_PORT,ABSCSN_PIN)
#define ABSCSN_L            GPIO_ResetBits(ABSCSN_PORT,ABSCSN_PIN)//数据线读
#define READABS_DO          GPIO_ReadInputDataBit(ABSDO_PORT,ABSDO_PIN)//函数声明
uint16_t SPI1_ReadWriteByte(uint8_t TxData);void AbsEncoder_Init(void)
{/*GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(ABSCLK_RCC| ABSCSN_RCC | ABSDO_RCC|RCC_APB2Periph_AFIO,ENABLE);//GPIO_DeInit(GPIOA);	//时钟线 初始化     推挽输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = ABSCLK_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(ABSCLK_PORT,&GPIO_InitStructure);//片选线 初始化  推挽输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = ABSCSN_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(ABSCSN_PORT,&GPIO_InitStructure);//数据线 初始化  上拉输入GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin = ABSDO_PIN;GPIO_Init(ABSDO_PORT,&GPIO_InitStructure);//先把时钟和片选拉高ABSCLK_H;ABSCSN_H;*/GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef  SPI_InitStructure;/* 使能GPIO 时钟 */RCC_APB2PeriphClockCmd(ABSCSN_RCC, ENABLE);/* 配置片选口线为推挽输出模式 */ABSCSN_H;		/* 片选置高,不选中 */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = ABSCSN_PIN;GPIO_Init(ABSCSN_PORT, &GPIO_InitStructure);/*SPI配置*/RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE );	//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6);//SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master;					//设置SPI工作模式:设置为主SPISPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;		//设置SPI的数据大小:SPI发送接收16位帧结构SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;					//选择了串行时钟的稳态:低电平SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;				//数据捕获于第二个时钟沿SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;		//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;		//定义波特率预分频的值:波特率预分频值为256SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始SPI_InitStructure.SPI_CRCPolynomial = 7;	//CRC值计算的多项式//SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器SPI_Cmd(SPI1, ENABLE); //使能SPI外设//SPI1_ReadWriteByte(0xff);//启动传输		/**/
}
//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
uint16_t SPI1_ReadWriteByte(uint8_t TxData)
{		u8 retry=0;				 	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位{retry++;if(retry>200)return 0;}			  SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据retry=0;while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)//检查指定的SPI标志位设置与否:接受缓存非空标志位{retry++;if(retry>200)return 0;}	  						    return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据					    
}
/*
*********************************************************************************************************
*	函 数 名: 
*	功能说明: 
*	形    参:  无
*	返 回 值: 无
*********************************************************************************************************
*/uint16_t SPIDataBuff;	//储存SPI采集绝对编码器的数据void Torque_Read(void)
{ABSCSN_L;SPIDataBuff = SPI1_ReadWriteByte(0x00);	//SPI采集绝对值,数据只有10位SPIDataBuff = SPIDataBuff >> 6;		 			//将采到的值移6位,对应10BitABSCSN_H;
}
/*
*********************************************************************************************************
*	模块名称 : 
*	文件名称 : bsp_encoder.h
*	版    本 : V1.0
*	说    明 :  
*	修改记录 :
*		版本号  日期        作者     说明
*********************************************************************************************************
*/
#ifndef _BSP_ENCODER_H
#define _BSP_ENCODER_H//声明
extern uint16_t SPIDataBuff;	void Torque_Read(void);
uint16_t SPI1_ReadWriteByte(uint8_t TxData);
void AbsEncoder_Init(void);#endif

主函数读取

int main()
{SYS_Configuration();RCC_config();bsp_Init();/**/AbsEncoder_Init();	/* AS5040磁编码器 *//**/bsp_StartAutoTimer(1, 300);	/* 定时器1周期 300毫秒 *///while (1){bsp_Idle();		/* 空闲时执行的函数,比如喂狗. 在bsp.c中 */if (bsp_CheckTimer(1))	/* 定时到 */{Torque_Read();	}}
}

抓取时序:

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是线程安全?如何保证线程安全?

目录 一、引入线程安全 👇 二、 线程安全👇 1、线程安全概念 🔍 2、线程不安全的原因 🔍 抢占式执行(罪魁祸首,万恶之源)导致了线程之间的调度是“随机的” 多个线程修改同一个变量 修改…

VGG论文解析—Very Deep Convolutional Networks for Large-Scale Image Recognition

VGG论文解析—Very Deep Convolutional Networks for Large-Scale Image Recognition -2015 研究背景 大规模图像识别的深度卷积神经网络 VGG(牛津大学视觉几何组) 认识数据集:ImageNet的大规模图像识别挑战赛 LSVRC-2014:Image…

生产制造边角料核算说明及ODOO演示

今天群里有伙伴提到边角料的处理问题,我们梳理了一下,在生产过程中,如果产生了边角料,核算产成品的投料成本时需要考虑边角料的价值,以确保成本核算的准确性。以下是注意的几点: 一、边角料的入账价值 在生…

「云渲染课堂」3dmax地砖材质参数怎么让画面更加真实?

在3DMAX中,地砖材质的渲染需要细致的调整,因为不同材质的地砖在反射和折射参数上各不相同。为了使地砖材质更加逼真,以下简要说明了一些设置方法,希望对大家有所帮助! 3dmax地砖材质参数如何设置 1、打开材质编辑器&a…

修改uniapp内置组件checkbox的样式

默认情况下 <view style"margin-bottom: 20rpx;"><label style"display: flex;align-items: center;width: fit-content;" click"handleCheck(cxm4s)"><checkbox /><text>车信盟出险4S维保</text></label>…

STC8增强型单片机开发——C51版本Keil环境搭建

一、目标 了解C51版本Keil开发环境的概念和用途掌握C51版本Keil环境的安装和配置方法熟悉C51版本Keil开发环境的使用 二、准备工作 Windows 操作系统Keil C51 安装包&#xff08;可以从Keil官网下载&#xff09;一款8051单片机开发板 三、搭建流程 环境搭建的基本流程&#xf…

VMware ESXi 兼容性查询

官网兼容性查询地址&#xff1a;https://www.vmware.com/resources/compatibility/search.php

衍生品赛道的 UniSwap:SynFutures 或将成为行业领军者

经过一个周期的发展&#xff0c;DeFi 已经成为基于区块链构建的最成功的去中心化应用&#xff0c;并彻底改变了加密市场的格局。加密货币交易开始逐步从链下转移到链上&#xff0c;并从最初简单的 Swap 到涵盖借贷、Staking、衍生品交易等广泛的生态系统。 在 DeFi 领域&#x…

【软件设计师】——9.UML建模

目录 9.1概述 9.2 结构图 9.2.1 对象图 9.2.2 类图 9.2.3 构件/组件图 9.2.3 部署图 9.2.4 制品图 9.2.5 组合结构图 9.3 行为图 9.3.1 用例图 9.3.2 协作图 9.3.3 顺序/序列/时序图 9.3.4 活动图 9.3.5 状态图 9.3.6 通信图 9.4 交互图 9.1概述 基本概念 UML统…

kali基本扫描工具(自带)

免责声明:本文仅做技术交流与学习...请勿非法破坏... 详细用法: 命令 -h/百度/翻译 fping 用法 hostlist 文件里面为ip fping -a -q -f hostlist -a 只看存活的 fping -g 202.100.1.1 202.100.1.255 -a -q > Ahost 输出到Ahost文件上 nping nping -c 1 201.100.2.155-244 …

下载Junit4的jar包和在eclipse下完成配置

​ 题外话&#xff1a; 本篇是新人小白搜索帖子&#xff0c;摸索学习如何下载和导入Junit的jar包并在eclipse下完成配置与使用&#xff0c;是自用的傻瓜式教程&#xff0c;文中如果出现错误或者值得改进的地方&#xff0c;非常欢迎各位提出&#xff01;&#xff01;&#xff01…

C# --- 浮点数类型 float, double, decimal

C# --- 浮点数类型 float, double, decimal float, double, decimaldecimal float, double, decimal decimal double 和 float 的采用base 2, 不能精确的表示浮点数, 进行加减乘除的操作的时候会出现精度丢失的问题decimal 采用base 10&#xff0c;可以精确的表示浮点数&#x…

判断dom元素是否滚动到底、是否在可视区域

概览 我们日常开发中&#xff0c;在面对懒加载、虚拟列表需求时&#xff0c;经常需要判断dom元素是否滚动到底、是否在可视区域。但是由于涉及的属性太多了&#xff0c;比如scrollTop、clientHeight、scrollHeight、getBoundingClientRect()等属性&#xff0c;现根据这两个场景…

【实战JVM】-基础篇-02-类的声明周期-加载器

【实战JVM】-基础篇-02-类的声明周期-加载器 3 类的生命周期3.1 生命周期的概述3.2 加载阶段3.2.1 查看内存中的对象 3.3 连接阶段3.3.1 验证阶段3.3.1.1 验证是否符合jvm规范3.3.1.2 元信息验证3.3.1.3 验证语义3.3.1.4 符号引用验证 3.3.2 准备阶段3.3.3 解析阶段 3.4 初始化…

利用Anaconda+Pycharm配置PyTorch完整过程

说在前面&#xff1a;这篇是记录贴&#xff0c;因为被配置环境折磨了大半天&#xff0c;所以记录下来下次方便配置&#xff0c;有点像流水账&#xff0c;有不懂的地方可以评论问。 参考文章&#xff1a; https://blog.csdn.net/m0_48609250/article/details/129402319 环境&…

【数据结构】链式二叉树(超详细)

文章目录 前言二叉树的链式结构二叉树的遍历方式二叉树的深度优先遍历前序遍历(先根遍历)中序遍历(中根遍历)后序遍历(后根遍历) 二叉树的广度优先遍历层序遍历 二叉树链式结构接口实现二叉树结点个数二叉树叶子结点个数二叉树的深度&#xff08;高度&#xff09;二叉树第k层结…

el-switch自动触发更新事件

比如有这样一个列表&#xff0c;允许修改单条数据的状态。希望在更改el-switch状态时能够有个弹框做二次确认&#xff0c;没问题&#xff0c;el-switch已经帮我们想到了&#xff0c;所以它提供了beforeChange&#xff0c;根据beforeChange的结果来决定是否修改状态。一般确认修…

Java入门-java的集合框架

集合概念 集合&#xff0c;有时也称作容器(Container), 是对象的持有者&#xff0c;它们可以有助于高效访问的方式存储的组织对象。以生活中的案例为例&#xff1a; 集合就像装衣服的柜子&#xff0c;衣服就是集合中的元素。 集合框架图 Collection中每次操作的都是一个对象&a…

android-mvp模式

mvvm可以理解成使用databing的mvp模式&#xff0c;modleview 通过接口让view和Presenter层解耦 从图中就可以看出&#xff0c;最明显的差别就是view层和model层不再相互可知&#xff0c;完全的解耦&#xff0c;取而代之的presenter层充当了桥梁的作用&#xff0c;用于操作view…

56. UE5 RPG 给敌人添加AI实现跟随玩家

在这一篇里&#xff0c;我们要实现一下敌人的AI&#xff0c;敌人也需要一系列的行为&#xff0c;比如朝向英雄攻击&#xff0c;移动&#xff0c;在满足条件时施放技能。这些敌人的行为可以通过使用UE的内置的AI系统去实现。 在UE里&#xff0c;只要是基于Character类创建的蓝图…