使用STM32F407VET6,通过SPI串行总线读取GMR(磁编码器)的相关数据(速度、角度绝对值等)

使用了PC10(SCK)、PC11(MISO)、PC12(MOSI)、PA15(CS)四个GPIO,将其与编码器对应连接

程序中使用了延时函数,需要包含系统滴答定时器延时函数使用的头文件delay.h

头文件spi.h

#ifndef __SPI_H__
#define __SPI_H__
#include "sys.h"#define SPI3_PORT             GPIOC
#define SPI3_PIN             (GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12)
#define SPI3_PORT_RCC         RCC_AHB1Periph_GPIOCvoid SPI3_Init(void); //初始化SPI3
uint16_t SPI3_ReadWriteByte(uint16_t TxData); //SPI3总线读写一个字节#endif

源文件spi.c

#include "spi.h"void SPI3_Init()
{GPIO_InitTypeDef GPIO_InitStructure;SPI_InitTypeDef  SPI_InitStructure;RCC_AHB1PeriphClockCmd(SPI3_PORT_RCC, ENABLE);      //使能GPIO时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);//使能SPI3外设时钟(SPI3挂载于内部低速总线APB1,最高84MHz)//GPIO初始化设置GPIO_InitStructure.GPIO_Pin = SPI3_PIN;            //PC10~12使用复用功能输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;       //复用功能GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;     //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;       //上拉GPIO_Init(SPI3_PORT, &GPIO_InitStructure);         //初始化//GPIO复用功能设置GPIO_PinAFConfig(SPI3_PORT, GPIO_PinSource10, GPIO_AF_SPI3); //PC10复用为 SPI3_SCKGPIO_PinAFConfig(SPI3_PORT, GPIO_PinSource11, GPIO_AF_SPI3); //PC11复用为 SPI3_MISOGPIO_PinAFConfig(SPI3_PORT, GPIO_PinSource12, GPIO_AF_SPI3); //PC12复用为 SPI3_MOSIRCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, ENABLE); //复位SPI3RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI3, DISABLE);//停止复位SPI3//SPI相关参数设置SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置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信号由软件(使用SSI位)管理,内部NSS信号由SSI位控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值为256SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;   //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始SPI_InitStructure.SPI_CRCPolynomial = 7;          //CRC值计算(若有)的多项式SPI_Init(SPI3, &SPI_InitStructure);                 //根据SPI_InitStruct中指定的参数初始化外设SPI3寄存器SPI_Cmd(SPI3, ENABLE);     //使能SPI3外设SPI3_ReadWriteByte(0xffff);//发送全"1",启动传输
}//SPI3读写数据
//TxData:要写入的数据
//返回值:读取到的数据
uint16_t SPI3_ReadWriteByte(uint16_t TxData)
{while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET) {} //等待发送区空SPI_I2S_SendData(SPI3, TxData);   //通过外设SPI3发送一个16bit数据while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET) {}//等待16bit数据接收完成return SPI_I2S_ReceiveData(SPI3); //返回通过SPI3最近接收的数据
}

头文件gmr.h

#ifndef __GMR_H__
#define __GMR_H__
#include "sys.h"#define CS_PORT             GPIOA
#define CS_PIN             (GPIO_Pin_15)
#define CS_PORT_RCC         RCC_AHB1Periph_GPIOA#define SPI3_CS PAout(15)/* SPI command for TLE5012 */
#define READ_STATUS             0x8001          //8000
#define READ_ANGLE_VALUE        0x8021          //8020
#define READ_SPEED_VALUE        0x8031          //8030#define WRITE_MOD1_VALUE      0x5060                          //0_1010_0_000110_0001
#define MOD1_VALUE  0x0001#define WRITE_MOD2_VALUE      0x5080                          //0_1010_0_001000_0001
#define MOD2_VALUE  0x0801#define WRITE_MOD3_VALUE      0x5091                          //0_1010_0_001001_0001
#define MOD3_VALUE  0x0000#define WRITE_MOD4_VALUE      0x50E0                          //0_1010_0_001110_0001
#define MOD4_VALUE  0x0098      //9bit 512#define WRITE_IFAB_VALUE      0x50B1
#define IFAB_VALUE 0x000D
/* Functionality mode */
#define REFERESH_ANGLE      0void GMR_Init(void);
uint16_t ReadAngle1(void);
float Conversion_Speed1(void);
short ReadSpeed1(void);
uint16_t ReadValue1(uint16_t u16RegValue);#endif

源文件gmr.c

#include "gmr.h"
#include "spi.h"GPIO_InitTypeDef GPIO_InitStructure_SPI;void GMR_Init()
{GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量RCC_AHB1PeriphClockCmd(CS_PORT_RCC, ENABLE);GPIO_InitStructure.GPIO_Pin = CS_PIN;              //要设置的IO口GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;      //普通输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;     //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;       //上拉GPIO_Init(CS_PORT, &GPIO_InitStructure);          /* 初始化GPIO */GPIO_SetBits(CS_PORT, CS_PIN);  //将片选端口拉高/* 以下代码初始化SPI接口的读写 */GPIO_InitStructure_SPI.GPIO_Pin = GPIO_Pin_12;   //PC12复用功能输出GPIO_InitStructure_SPI.GPIO_Mode = GPIO_Mode_AF; //使用复用功能GPIO_InitStructure_SPI.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure_SPI.GPIO_PuPd = GPIO_PuPd_UP;      //上拉
}uint16_t ReadValue1(uint16_t u16RegValue)
{uint16_t u16Data;SPI3_CS = 0;SPI3_ReadWriteByte(u16RegValue);//SPI_TX_OFF;将主设备数据输出,从设备数据输入(MOSI)配置成开漏--输入模式GPIO_InitStructure_SPI.GPIO_OType = GPIO_OType_OD;//开漏输出GPIO_Init(SPI3_PORT, &GPIO_InitStructure_SPI);//初始化//发送 0xFFFF 是无用的,可能是为了有时钟u16Data = (SPI3_ReadWriteByte(0xffff) & 0x7FFF);//0x12/0xff*100kSPI3_CS = 1;//SPI_TX_ON;将主设备数据输出,从设备数据输入(MOSI)配置成推挽--输出模式GPIO_InitStructure_SPI.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_Init(SPI3_PORT, &GPIO_InitStructure_SPI);//初始化return(u16Data);
}short ReadSpeed1()
{short Data;Data = (short)(ReadValue1(READ_SPEED_VALUE) << 1) >> 1;return Data;
}float Conversion_Speed1()
{float Speed;Speed = ((float)(ReadSpeed1() * 360) / 65535) / (2 * 0.0000213); //单位°/s;return (Speed / (float)360.0); //返回每秒的转数
}uint16_t ReadAngle1()
{return ((ReadValue1(READ_ANGLE_VALUE) << 1) * 360 / 0x10000);
}

使用实例如下:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "spi.h"
#include "gmr.h"int main(void)
{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2delay_init(168);     //初始化延时函数uart_init(115200);   //初始化串口波特率为115200GMR_Init();SPI3_Init();while (1){delay_ms(5);printf("speed:%d\r\n", ReadSpeed1());printf("angle:%d\r\n", ReadAngle1());}
}

效果如下:

硬件探索——STM32F4通过SPI总线读取GMR(磁编码器)相关推荐

  1. 关于使用SPI总线读取并转串(74HC165)发生数据移位的问题

    背景: 使用STM32H743主控,通过SPI读取74HC165的数据,74HC165接了7个按键. 现象: 在所有按键都没按下的时候读取到的数据应该为0x00,按下某个按键对应的bit应该变成1.实 ...

  2. 硬件探索——STM32F4控制74HC595数码管

    使用STM32F407VET6,通过串行方式驱动74HC595控制的4位数码管 使用了PD0(DIO).PD1(RCLK).PD2(SCLK)三个GPIO,将其与数码管模块对应连接 程序中使用了延时函 ...

  3. IIC读取AS5600磁编码器并计算相对角度与圈数代码移植

    芯片F103CBT6,使用cubeide+hal库,驱动部分源码移植于: (22条消息) STM32使用模拟I2C读取AS5600(深入讲解:带波形图)_yizeni的博客-CSDN博客_as5600 ...

  4. AS5047P磁编码器ESP32驱动程序、硬件电路设计、SPI通信时序、逻辑波形分析、注意事项

    1.AS5047P硬件设计 1.1 简介.性能参数 AS5047P 是一种款高分辨率旋转位置传感器,用于在整个 360 度范围内进行高速(高达 28krpm)角度测量.这种新型位置传感器配备了革命性的 ...

  5. SPI总线的原理与Verilog实现

    一. 软件平台与硬件平台 软件平台: 1.操作系统:Windows-8.1 2.开发套件:ISE14.7 3.仿真工具:ModelSim-10.4-SE 硬件平台: 1. FPGA型号:Xilinx公 ...

  6. 【硬件通讯协议】SIP总线协议以及模拟(软件)SPI

    参考资料 NXP 官方网站提供的 SPI 总线规范 S12SPIV4.pdfhttps://www.nxp.com/files-static/microcontrollers/doc/ref_manu ...

  7. 嵌入式硬件基础之SPI总线详解

    目录 SPI(ISerial Peripheral Interface)简介 基本协议 SPI协议概括 协议举例 用户逻辑 SPI原理 时序图 同步串行口 硬件示意图 性能特点 协议举例 性能补充 协 ...

  8. 【STM32F429开发板用户手册】第33章 STM32F429的SPI总线应用之驱动DAC8563(双通道,16bit分辨率,正负10V)

    最新教程下载:http://www.armbbs.cn/forum.php?mod=viewthread&tid=93255 第33章       STM32F429的SPI总线应用之驱动DA ...

  9. 【STM32F429开发板用户手册】第34章 STM32F429的SPI总线应用之驱动DAC8501(双路输出,16bit分辨率,0-5V)

    最新教程下载:http://www.armbbs.cn/forum.php?mod=viewthread&tid=93255 第34章       STM32F429的SPI总线应用之驱动DA ...

  10. STM32F4-SPI

    SPI 简介 SPI 是英语 Serial Peripheral interface 的缩写,顾名思义就是串行外围设备接口.是 Motorola首先在其 MC68HCXX 系列处理器上定义的.SPI ...

最新文章

  1. Object-C代码练习【自定义对象的归档】
  2. linux监听9080,基于UPnP发现与组播技术的IPTV终端实现
  3. print (“{0:<10}{1:>5}“.format(word, count))
  4. cygwin nginx php mysql_Windows 下 Nginx + PHP5 的安装与配置
  5. 自学python要看哪些书籍-学习机器学习应该看哪些书籍?
  6. nginx 启动问题:nginx (pid ) already running.
  7. bytebuf池_图文分析ByteBuf是什么
  8. 做一枚精致的程序猿,Fighting!
  9. Mac版的DjVu格式文件阅读工具
  10. iframe中加载html页面,jQuery - 动态创建iframe并加载页面
  11. 关于计算机信息管理的照片,2021年10月青海自考计算机科学与技术(计算机信息管理方向)专业报名照片要什么格式...
  12. HTML+CSS大作业——动画漫展学习资料电影模板(6页) 网页设计作业 _ 动漫网页设计作业,网页设计作业 _ 动漫网页设计成品,网页设计作业 _ 动漫网页设计成品模板下载
  13. 大牛教你这样阅读android源码
  14. Git runner安装
  15. 计算机计算公式单组数据求乘法,(excel表格全部数据怎么乘以一个数啊)
  16. 正则表达式/\$\{id\}/gi详解
  17. 常见开放api平台-OpenAPI
  18. 电影《少年的你》影评分析
  19. hadoop订单项目实战
  20. 正大国际:期货交易为什么小止损大止盈还是无法获利呢?

热门文章

  1. pywifi 破解WiFi密码
  2. 计算机网络工程师多久过期,软考网络工程师证书有效期
  3. 历年软考网络工程师考试真题及答案
  4. 工业机器人云监控与运维方案
  5. usb转ttl测试软件,usb转ttl驱动
  6. html周报模板,工作周报模板(标准)
  7. html5双日期时间选择控件,bootstrap daterangepicker双日历时间段选择控件详解
  8. Tableau 学习 区分软件功能
  9. NPDP产品经理认证:精益画布使用六步法
  10. 计算机毕业论文降重,湖南计算机专业毕业论文英文摘要,财务管理专业硕士毕业论文降重...