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工作模式:设置为主SPI
	SPI_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;		//定义波特率预分频的值:波特率预分频值为256
	SPI_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位,对应10Bit
	ABSCSN_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();	
         }

    }
}

抓取时序:

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

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

相关文章

算法设计第七周(应用哈夫曼算法解决文件归并问题)

一、【实验目的】 (1)进一步理解贪心法的设计思想 (2)掌握哈夫曼算法的具体应用 (3)比较不同的文件归并策略,探讨最优算法。 二、【实验内容】 设S{f1,…,fn}是一组不同的长度的有序文件构…

【测评】OrangePi AIPro环境配置与基础应用

1.介绍 官网:http://www.orangepi.cn/ 社区:http://forum.orangepi.cn/ 昇腾社区:https://www.hiascend.com/ OrangePi AIPro 是一款基于昇腾AI技术的开发板,它采用华为昇腾910E AI芯片,集成4核64位CPU和AI处理器&am…

CRMEB多门店的门店后台首页路由

如何在输入 http://localhost:8080/、http://localhost:8080/store/、http://localhost:8080/custom-store/ 这三个中任意一个链接都能正确跳转到 http://localhost:8080/store/home/index 。要实这个要求,有两种方式: 重定向const router new VueRout…

恒创科技:Linux 服务器和 Windows 服务器哪个更好?

选择正确的服务器系统至关重要,目前广泛使用的选项是 Windows 服务器 和 Linux 服务器,它们各有优缺点。本文将比较 Linux 与 Windows 服务器,让我们来看看它们的主要区别,然后再决定哪种操作系统适合使用。 主要区别:…

几种流行的并行方法了解

几种流行的并行方法: 数据并行(data parallel)模型并行(model parallel) tensor并行pipeline并行sequence并行Zero Redundancy Data Parallelism(ZeRO) Data parallelism (DP) 经典的数据并行…

基本Java语法和语义 (Reading 2)

(1)Java和C在变量类型命名和使用 基本数据类型 对象类型与引用类型 特殊类型 关键字和修饰符 (2)快照图: IDE调试工具: 许多IDE(如Eclipse、IntelliJ IDEA)提供了调试功能,可以…

智慧水坝:科技变革的里程碑

在曾经的水利工程领域,水坝只是为了水资源的调配和控制,提供一定的安全储备。然而,随着现代科技的不断发展,传统的水坝已经不再是单一的水源控制工程,而是变成了一个充满智慧与创新的生态系统。智慧水坝的概念已经超越…

远大阀门集团携创新产品亮相南京,展现石化行业新风采

2024年5月22日,备受瞩目的第八届中国石油和化工行业采购大会在江苏省南京市盛大开幕。作为石化行业物资采购领域极具影响力的年度盛会,本次大会吸引了众多国内外能源化工企业、化工新材料企业、工程公司以及相关领域的供应商参加。远大阀门集团作为特邀优…

Python筑基之旅专栏(导航)

目录 一、Python筑基之旅专栏博文清单及链接 二、推荐阅读 一、Python筑基之旅专栏博文清单及链接 01、溯源及发展 02、变量和数据类型 03、搭建Python开发环境及库 04、两个重要函数/列表/元组 05、字符串(一) 06、字符串(二) 07、字符串(三) 08、字典 09、集合 10…

看汽车冲压件的工厂,如何做PFMEA分析?

为了确保冲压件的质量稳定,提高生产效率,PFMEA(过程潜在失效模式及影响分析)分析成为了汽车冲压件工厂不可或缺的重要工具。本文将带您走进汽车冲压件工厂,一探PFMEA分析的奥秘与实践。 PFMEA分析,作为一种…

I.MX6ULL的蜂鸣器实验

系列文章目录 I.MX6ULL的蜂鸣器实验 I.MX6ULL的蜂鸣器实验 系列文章目录一、前言二、有源蜂鸣器简介三、硬件原理分析四、程序编写五、编译下载验证5.1编写 Makefile 和链接脚本5.2编译下载 一、前言 在 I.MX6U-ALPHA 开发板上有一个有源蜂鸣器,通过 IO 输出高低电…

git中忽略文件的配置

git中忽略文件的配置 一、在项目根目录下创建.gitignore文件二、配置规则如果在配置之前已经提交过文件了,要删除提交过的,如何修改,参考下面的 一、在项目根目录下创建.gitignore文件 .DS_Store node_modules/ /dist# local env files .env…

设计模式基础——设计原则介绍

1.概述 ​ 对于面向对象软件系统的设计而言,如何同时提高一个软件系统的可维护性、可复用性、可拓展性是面向对象设计需要解决的核心问题之一。面向对象设计原则应运而生,这些原则你会在设计模式中找到它们的影子,也是设计模式的基础。往往判…

电脑由于ntdll.dlI丢失导致exe崩溃有什么解决办法?解决ntdll.dll丢失问题

相信有一些用户正在面临一个叫做“ntdll.dll丢失”的问题,这种情况多半发生在试图运行某个程序时,系统会提示一条错误消息:“程序无法启动,因为计算机中丢失了ntdll.dll”。那么,为何ntdll.dll文件会丢失,又…

全能集成开发平台Team·IDE

三甲医院的床位太难等了。反正也是小手术,老苏周五在附近找了家二甲医院,幸运的是,门诊迅速为我开具了入院证。周六早晨就接受了手术,周日挂了一天水,周一下午就出院了。准备在家先休息两天。 2~4 周之后把支架取出来…

Pytorch深度学习实践笔记9(b站刘二大人)

🎬个人简介:一个全栈工程师的升级之路! 📋个人专栏:pytorch深度学习 🎀CSDN主页 发狂的小花 🌄人生秘诀:学习的本质就是极致重复! 《PyTorch深度学习实践》完结合集_哔哩哔哩_bilibi…

YOLOv10:全面的效率-准确性驱动模型设计

YOLOv10:全面的效率-准确性驱动模型设计 提出背景精细拆分解法双重标签分配一致的匹配度量以效率为导向的模型设计 YOLO v10 总结1. 双重标签分配策略2. 一致匹配度量策略 论文:https://arxiv.org/pdf/2405.14458 代码:https://github.com/T…

【源码】java + uniapp交易所源代码/带搭建教程java交易所/完整源代码

java uniapp交易所源代码/带搭建教程java交易所/完整源代码 带简洁教程,未测 java uniapp交易所源代码/带搭建教程java交易所/完整源代码 - 吾爱资源网

数据结构第二篇【关于java线性表(顺序表)的基本操作】

【关于java线性表(顺序表)的基本操作】 线性表是什么?🐵🐒🦍顺序表的定义🦧🐶🐵创建顺序表新增元素,默认在数组最后新增在 pos 位置新增元素判定是否包含某个元素查找某个…

HTTP 与 HTTPS 对比

HTTP:HTTPS:超文本传输协议 超文本传输安全协议加入SSL/TLS协议,依靠证书来验证服务器的身份需要到CA申请证书,需要一定费用TCP 协议 80 端口 TCP 协议 443 端口更耗费服务器资源