当前位置:   article > 正文

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

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

1.AS5040介绍

2.硬件电路

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

3.配置硬件SPI

查看手册,AS5040时序

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

谢谢此文章作者的分享

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

代码操作:

  1. /*
  2. *********************************************************************************************************
  3. *
  4. * 模块名称 : BSP_AS5040.C
  5. * 文件名称 : 编码器驱动模块
  6. * 版 本 : V0.1
  7. * 说 明 :
  8. 在空闲阶段不发生数据传输的时候时钟(CLK)和数据(DO)都保持高电位(tCLKFE阶段),
  9. 在第一个脉冲的下降沿触发编码器载入发送数据
  10. 然后每一个时钟脉冲的上升沿编码器送出数据,数据的高位在前,低位在后,共发送10个数据(对应其分辨率10BIT
  11. 当传送完所有的位数以后时钟回到高电平,数据也对应回到高电平,直到下一个传输周期到达。
  12. 对比四种模式,只有当CPOL配置成“0”和CPHA配置成“1”的时候 才符合每一个时钟脉冲的上升沿编码器送出数据的情况。
  13. 使用SPI获取AS5040磁性单圈绝对值编码器数据。 10bit+6bit
  14. *********************************************************************************************************
  15. */
  16. #include "bsp.h"
  17. /* GPIO口对应配置 */
  18. //绝对值编码器 CSN引脚 A4 黄色 29 --SPI1_NSS
  19. #define ABSCSN_PORT GPIOA
  20. #define ABSCSN_RCC RCC_APB2Periph_GPIOA
  21. #define ABSCSN_PIN GPIO_Pin_4
  22. //绝对值编码器 CLK引脚 A5 绿色 30 ---SPI1_SCK
  23. #define ABSCLK_PORT GPIOA
  24. #define ABSCLK_RCC RCC_APB2Periph_GPIOA
  25. #define ABSCLK_PIN GPIO_Pin_5
  26. //绝对值编码器 DO引脚 A6 蓝色 31 ---SPI1_MISO
  27. #define ABSDO_PORT GPIOA
  28. #define ABSDO_RCC RCC_APB2Periph_GPIOA
  29. #define ABSDO_PIN GPIO_Pin_6
  30. //时钟线高低电平
  31. #define ABSCLK_H GPIO_SetBits(ABSCLK_PORT,ABSCLK_PIN)
  32. #define ABSCLK_L GPIO_ResetBits(ABSCLK_PORT,ABSCLK_PIN)
  33. //片选高低电平
  34. #define ABSCSN_H GPIO_SetBits(ABSCSN_PORT,ABSCSN_PIN)
  35. #define ABSCSN_L GPIO_ResetBits(ABSCSN_PORT,ABSCSN_PIN)
  36. //数据线读
  37. #define READABS_DO GPIO_ReadInputDataBit(ABSDO_PORT,ABSDO_PIN)
  38. //函数声明
  39. uint16_t SPI1_ReadWriteByte(uint8_t TxData);
  40. void AbsEncoder_Init(void)
  41. {
  42. /*GPIO_InitTypeDef GPIO_InitStructure;
  43. RCC_APB2PeriphClockCmd(ABSCLK_RCC| ABSCSN_RCC | ABSDO_RCC|RCC_APB2Periph_AFIO,ENABLE);
  44. //GPIO_DeInit(GPIOA);
  45. //时钟线 初始化 推挽输出
  46. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  47. GPIO_InitStructure.GPIO_Pin = ABSCLK_PIN;
  48. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  49. GPIO_Init(ABSCLK_PORT,&GPIO_InitStructure);
  50. //片选线 初始化 推挽输出
  51. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  52. GPIO_InitStructure.GPIO_Pin = ABSCSN_PIN;
  53. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  54. GPIO_Init(ABSCSN_PORT,&GPIO_InitStructure);
  55. //数据线 初始化 上拉输入
  56. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  57. GPIO_InitStructure.GPIO_Pin = ABSDO_PIN;
  58. GPIO_Init(ABSDO_PORT,&GPIO_InitStructure);
  59. //先把时钟和片选拉高
  60. ABSCLK_H;
  61. ABSCSN_H;
  62. */
  63. GPIO_InitTypeDef GPIO_InitStructure;
  64. SPI_InitTypeDef SPI_InitStructure;
  65. /* 使能GPIO 时钟 */
  66. RCC_APB2PeriphClockCmd(ABSCSN_RCC, ENABLE);
  67. /* 配置片选口线为推挽输出模式 */
  68. ABSCSN_H; /* 片选置高,不选中 */
  69. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  70. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  71. GPIO_InitStructure.GPIO_Pin = ABSCSN_PIN;
  72. GPIO_Init(ABSCSN_PORT, &GPIO_InitStructure);
  73. /*SPI配置*/
  74. RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE );
  75. //
  76. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;
  77. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
  78. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  79. GPIO_Init(GPIOA, &GPIO_InitStructure);
  80. //
  81. GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6);
  82. //
  83. SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
  84. SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
  85. SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b; //设置SPI的数据大小:SPI发送接收16位帧结构
  86. SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //选择了串行时钟的稳态:低电平
  87. SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //数据捕获于第二个时钟沿
  88. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
  89. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128; //定义波特率预分频的值:波特率预分频值为256
  90. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
  91. SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
  92. //
  93. SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
  94. SPI_Cmd(SPI1, ENABLE); //使能SPI外设
  95. //SPI1_ReadWriteByte(0xff);//启动传输
  96. /**/
  97. }
  98. //SPIx 读写一个字节
  99. //TxData:要写入的字节
  100. //返回值:读取到的字节
  101. uint16_t SPI1_ReadWriteByte(uint8_t TxData)
  102. {
  103. u8 retry=0;
  104. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
  105. {
  106. retry++;
  107. if(retry>200)return 0;
  108. }
  109. SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个数据
  110. retry=0;
  111. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)//检查指定的SPI标志位设置与否:接受缓存非空标志位
  112. {
  113. retry++;
  114. if(retry>200)return 0;
  115. }
  116. return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据
  117. }
  118. /*
  119. *********************************************************************************************************
  120. * 函 数 名:
  121. * 功能说明:
  122. * 形 参: 无
  123. * 返 回 值: 无
  124. *********************************************************************************************************
  125. */
  126. uint16_t SPIDataBuff; //储存SPI采集绝对编码器的数据
  127. void Torque_Read(void)
  128. {
  129. ABSCSN_L;
  130. SPIDataBuff = SPI1_ReadWriteByte(0x00); //SPI采集绝对值,数据只有10
  131. SPIDataBuff = SPIDataBuff >> 6; //将采到的值移6位,对应10Bit
  132. ABSCSN_H;
  133. }
  1. /*
  2. *********************************************************************************************************
  3. * 模块名称 :
  4. * 文件名称 : bsp_encoder.h
  5. * 版 本 : V1.0
  6. * 说 明 :
  7. * 修改记录 :
  8. * 版本号 日期 作者 说明
  9. *********************************************************************************************************
  10. */
  11. #ifndef _BSP_ENCODER_H
  12. #define _BSP_ENCODER_H
  13. //声明
  14. extern uint16_t SPIDataBuff;
  15. void Torque_Read(void);
  16. uint16_t SPI1_ReadWriteByte(uint8_t TxData);
  17. void AbsEncoder_Init(void);
  18. #endif

主函数读取

  1. int main()
  2. {
  3. SYS_Configuration();
  4. RCC_config();
  5. bsp_Init();
  6. /**/
  7. AbsEncoder_Init(); /* AS5040磁编码器 */
  8. /**/
  9. bsp_StartAutoTimer(1, 300); /* 定时器1周期 300毫秒 */
  10. //
  11. while (1)
  12. {
  13. bsp_Idle(); /* 空闲时执行的函数,比如喂狗. 在bsp.c中 */
  14. if (bsp_CheckTimer(1)) /* 定时到 */
  15. {
  16. Torque_Read();
  17. }
  18. }
  19. }

抓取时序:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/602868
推荐阅读
相关标签
  

闽ICP备14008679号