你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于stm32平台上的IC-MU磁绝对值编码器SPI通讯和码盘数据处理

[复制链接]
STMCU小助手 发布时间:2023-2-25 17:59
前言" y7 X1 R+ {4 z: b5 |+ |
ic-mu基本情况介绍4 e9 d, M( s' z6 U" i

& Y5 l4 a& {# t  s/ P, @# N+ f% NIC_MU是一款离轴的1.28mm磁编码器,主要用于电机控制居多,当作磁编码器,优势是能使用多种通讯协议(SPI,BISS,SSI),但是目前中文网上使用资料较少,因此我自己写一篇关于IC_MU的SPI通讯读取方式的文章,读取芯片为stm32G4系列,然后代码在stm32G4和stm32F1系列基本通用。4 d$ B0 b) ]6 L
芯片基本介绍如下$ e3 k" T' _* N% t9 c- @( {
- i6 `' c7 ?' b. Z
325acfd031684154a51541ebaf3bc1f5.png ; n- \. b* X9 F1 n% I0 \

0 M% h/ z# w" j7 \提示:以下是本篇文章正文内容,下面案例可供参考
: \/ x7 ~$ T  o( d
1 S2 K: _* |! H! u
一、硬件连接
; P/ R( O/ f) P4 a; s5 C
按最小系统连接。IC-mu需连接eeprom存储角度,供电为5V7 A# x' S; r0 |8 `3 A( F
% B/ W$ ]6 f- W7 m! F. q: \2 l
二、STM32 cubmx配置模式
! H4 s, N3 {  o3 ]STM32G491配置cubemx+ s+ a! o4 z$ m7 {& D" }( p- i

) R8 t! v7 X: y" n  g! U$ b
b31de8a144684fd8815c3aea74271bba.png
" Y% ]9 D" V: c1 T+ }; k# Z
) V2 a, d/ {7 P) ^3 H! u. K

1 ~! k& N0 h+ V1 p& R如图几个关键点
; w$ T- ^1 Z* B$ `2 k1数值格式:可以选8bit,但是我觉得16比特配置更方便,如果要配8bit只需将数据拆分即可
/ b; B* w3 _6 T8 @4 p% F; y5 |2波特率 没有明确要求,12M以下都可以9 {5 Z  @7 z4 H7 Q- [9 ?
3SPI模式,SPI一共4种模式2 l# {1 d( _- J8 @
' k3 s. \* \* M3 S* R
896f63f11e5f4a62b6e64e9527c395a0.png
0 J( w! c* N9 Q% R# e  O
& n, m  d$ n: \% f  }
IC_MU只支持模式0和模式3,如上图所示采用模式3 CPOL选择High CPHA选择2Edge, R# N9 s/ q. V' S

! v! E" M+ d2 }6 S; W7 i. z
2e692f827e4048f38f0a6020450c06ec.png   L8 t+ z' p5 D( C' |
" T0 N+ l2 G/ W+ F7 {
0 e+ y% W- X) a* h/ U
SPI通道要设置为高速' f* {" X, x# X8 q( h) k
除此之外还需要设置片选信号,默认为高电平
  h$ e" _2 b. \! i( G; v; S
8 K6 o- A5 y" Y- f. i; u
e8715427ead043cd984ccaaf608c5208.png
" _3 F- E+ M" k( X3 m- _3 y: I3 u) w8 Y6 s
三、软件代码及思路6 M4 t. d  k- R: i" _) a* x
首先需要对整体进行说明,需要将编码器激活,配置在SPI通讯模式
% n! c8 @1 h+ @) c9 C& L: E7 L4 o8 s( ?: r# g5 b
1.寄存器指令介绍- x6 F4 }6 r- X, O9 {8 W
0xB083 Activate,激活; b) C3 m2 c; j5 s
0xA6FF Position Read 位置读取命令
% W( H1 ^( o0 [  L) h0x8A Register Read (Continuous) 寄存器读取(连续)
/ h8 Y+ h& Z, K- q6 T4 W+ @0xCF Register Write(Continuous) 寄存器写入(连续)
. U/ G3 \0 B# E+ }. C# K: f9 d9 I" i0x9C Read Status 读取状态寄存器 指令  ]- n7 e7 V$ }& p
0x97 Register Read(Single) 寄存器读取(单次)
  @3 P/ S7 K8 M$ g2 V0 j0xD2 Register Write(Single) 寄存器写入(单次)
/ U1 V' y! R0 s4 j8 ^
, g' w& m( E1 p' p4 v7 b+ _5 o

2 b3 X  K" {+ L2.代码介绍
2 s# X# {" z% y, z+ t+ U  C& L对片选进行宏定义,然后对SPI数据传输底层函数进行定义- B: s" \  c* U( t& i# b& d7 X
+ `0 k' K0 c: A- I3 e) o
1初始声明和定义
  1. #define    SPI_IC_MU_CS_LOW();       HAL_GPIO_WritePin(ABS_ENCODER_CSN_GPIO_Port, ABS_ENCODER_CSN_Pin, GPIO_PIN_RESET);8 m7 i0 p1 g: U0 H* U; m
  2. #define          SPI_IC_MU_CS_HIGH() ;     HAL_GPIO_WritePin(ABS_ENCODER_CSN_GPIO_Port, ABS_ENCODER_CSN_Pin, GPIO_PIN_SET);7 y7 q8 A! Z1 B4 e* k2 ?

  3. $ h. L3 F! v6 @6 [; c6 c% y
  4. uint16_t SPI_SendHalfWord(uint16_t HalfWord)1 f  x" C7 {. A4 p
  5. {
    6 ^0 r2 P, d( S
  6.   8 `% W) g  h2 u
  7.   SPITimeout = SPIT_LONG_TIMEOUT;5 E7 k  ?. I0 R. H
  8.   /* Loop while DR register in not emplty */# V; F; W& x( r; V" F3 Q" Y
  9.   while (__HAL_SPI_GET_FLAG( &hspi1,  SPI_FLAG_TXE ) == RESET)4 B0 j( j9 Q$ e7 w1 D: A$ ~
  10.   {% E0 t+ d9 @' g5 ~, a
  11.     if((SPITimeout--) == 0) return 0;. T. V, w& ^! C% T" b
  12.   }
    1 j8 T: T& Y* I6 @$ i, o1 K" q5 \. D
  13.   /* Send Half Word through the SPIx peripheral */0 u, z8 E% x; z$ E# Z  W( Y2 s" v
  14.   WRITE_REG(hspi1.Instance->DR, HalfWord);
    # @/ E% E  k- }- J+ r, U+ z0 Q* Q
  15. 3 {' z% K1 c6 t& Q' ^
  16.   SPITimeout = SPIT_LONG_TIMEOUT;
    ! Z2 {- U- l! c; c
  17.   /* Wait to receive a Half Word */* L* m# F7 _' l5 z
  18.   while (__HAL_SPI_GET_FLAG( &hspi1, SPI_FLAG_RXNE ) == RESET)
    $ ~* }3 O5 }. f) u+ R$ J
  19.    {
    1 A, V9 x/ f$ f. \5 k
  20.     if((SPITimeout--) == 0) return 0;
    2 W" q, r3 J* b
  21.    }8 }5 F& H- `6 v& w  z
  22.   /* Return the Half Word read from the SPI bus */, z. y. _, ]: k  h
  23.   return READ_REG(hspi1.Instance->DR);
      K3 o: O) O7 H3 q* s! J* ?
  24.   
    ! k% b( [2 S( f, H
  25. }
    ) z1 Z8 g& ]  V8 H
复制代码
7 K/ O# x" `2 E3 D3 I
2激活寄存器
, I# h8 `, A1 p$ P激活后才能对寄存器有操作% G/ ~6 ?7 A; L' ~: E3 ~; Q! s
  1. void ACTIVATE_FUN(void)
    ' r9 m) @$ I7 o* l
  2. {
    4 d) _$ N; B" y# C  }5 d
  3.   uint32_t ICMU_Temp = 0;
    4 A( S1 c/ s6 a& A
  4.   SPI_IC_MU_CS_LOW();. y! E% T4 w" l3 c  e! k
  5.   ICMU_Temp= SPI_SendHalfWord(0xB083);1 z( d- C9 b! p$ Q4 a
  6.   SPI_IC_MU_CS_HIGH();; D; _4 f" d3 x4 u/ l
  7.    Delay(100);' {) e( G5 K" x
  8. }
    ) [/ M& w1 Q1 M/ F3 }' ~# t6 M
复制代码

+ B" e+ F8 {% e+ P3编码器初始化函数
' R( T8 e( L. C2 L; w初始化发送0xB083激活编码器,编码器配置为单圈14位,具体见数据手册0 ]7 E( J- }9 ^/ R, e3 B
初始化完成后可删除函数,状态会固化在配套eeprom种,不会丢失! B! x1 U- y9 k) m& e: N1 b
  1. void Init_ICMU(void)$ F2 N" [3 [; g. E( t8 w* j
  2. {
    $ u- r4 r) l/ M. {# S: i# D3 ^
  3.    ACTIVATE_FUN();: Y4 j# S$ [1 T, E$ o
  4.   uint32_t ICMU_Temp = 0, ICMU_Temp1=0;
    . v0 L$ b+ J( M  ^$ ?/ w
  5.   SPI_IC_MU_CS_LOW();/ y* a0 c- o7 {& O
  6.   ICMU_Temp= SPI_SendHalfWord(0xCF00);( C  T4 j" Z; g/ F7 q& o
  7. ICMU_Temp1= SPI_SendHalfWord(0x8E20);0 }' k- `" n# V2 V
  8.   SPI_IC_MU_CS_HIGH();
    6 f- Q6 e3 X8 V# p
  9.    Delay(100);! y2 U3 Y' F& V; j% A
  10. }. ?; V- Z5 d& U1 s4 q1 G
复制代码
0 }" o6 u! i, S  C. L' m
4数据读取
/ f7 H6 [) X4 K- T3 ~+ F编码器数据读取,读取指令为0xA6
6 s2 h: }2 C6 V
  1. uint32_t SPI_SDAD_transmission_Fun ( void)  F: ?% H7 P9 |
  2. {4 O& S( [, C$ H9 _9 l- x# @3 N  _$ ~
  3.         ) F3 s3 p/ g3 z% t
  4.         uint32_t Temp = 0 , Temp1 = 0, Temp2 = 0 , Temp3 = 0 ;1 B" N  ^* }6 J: @$ j
  5.   ACTIVATE_FUN();
    $ N2 E1 H; k3 o7 r# z
  6.         2 \$ b/ b4 \8 M2 j
  7.    /* 开始通讯:CS低电平 */, W  ]. m* g' V% h: B
  8.    SPI_IC_MU_CS_LOW();
    # ~# I# l) G* G0 @
  9.         Temp1=SPI_SendHalfWord(0xA6FF);
    1 P2 f- p. v- H% L+ K6 ?
  10.         Temp2=SPI_SendHalfWord(0xFFFF);4 L6 ]; C, f( h( y
  11.        
    ' e, C& S6 i7 n: |
  12.         3 q. e) @1 X0 ^* h/ ?
  13.          /* 结束通讯:CS高电平*/
    8 S) L+ [6 `) `$ f* c
  14.    SPI_IC_MU_CS_HIGH();
    4 _$ x4 S: e* o0 v
  15.      
    ; y: a0 F# D2 n7 s3 w. y* P
  16. //  Temp = (  (Temp1 << 16) | (Temp2 << 8) | Temp3  )>> 5 ; //读出数据,右移5位,共24位,有效位为19位  
    2 a8 z3 V# L5 [. A8 T9 T  ]) s6 b
  17.    Temp=  (Temp1 << 16| Temp2) >> 13;   //总体32位 19位的话需右移13位
    5 s* k9 p. p" y9 @6 Z
  18.           Delay(1000);: e' |7 E  k3 J  U
  19.          return Temp;- ^: H7 @* [  w* P9 l  P
  20. }
    # r/ s. S0 |0 v
复制代码
4 H0 b. }$ Z* S  r8 p
5角度计算  T. D7 o6 U1 S* v; V, V: V$ [- y& e
角度我用了11位,初始默认存在一个数值因此将他减掉了,然后按照360度进行划分* ~( [4 {/ K& R. Y% q6 @
  1. float Position_Calce()
    , b! F" Z5 T; R6 U7 _1 h# L
  2. {% A- ^3 B  }; ~8 \8 G
  3.     uint32_t  a ;8 ?4 i0 X3 w8 Q0 z, {4 B6 _
  4.           double b;7 L7 k' b! d/ J3 y: D
  5.           float  c ;
    8 m9 {; w% @1 [$ B8 j
  6.                 uint32_t  www ;! x5 T3 s7 H2 \+ J3 v; k0 u* I
  7.                 double  n ;' G; j, y3 t6 n
  8.      a=SPI_SDAD_transmission_Fun ();" ?% M( V9 D1 I: K- Y0 ]
  9.       n=((a-0x00053000)/2047);//计算角度  X! ?4 j- H- Y$ }* ]# E; y! B
  10.        b= 360.000* ((double)(a-0x53000)/2047);
    : b( g; F2 \! a- Y" G6 W
  11.       
    5 Q: D4 W7 I$ C* K% M
  12.                         return b;                       
    7 v4 H; |2 a& D) c$ {4 }
  13.   
    , H' o  U7 Q$ m8 H) q2 C6 b, D
  14. }
复制代码
6 V6 ~! \6 v, m, F1 d: t
6主函数读取角度
6 b: |2 e: k1 b, U6 p8 N0 b
  1. float position_fk_f=0;  //位置计算
    - K1 h! ~0 ^* S! i5 e
  2.        
    ( L- T$ J* L1 H
  3. while (1)# l+ t  P" `& n& H+ f
  4.     {
    4 _- |! |+ _8 b8 c; D# ~; M
  5.                   position_fk_f=        Position_Calce();" ^3 b3 \$ k2 A. j' [# C" r
  6.                   }3 p1 i2 o3 X3 M9 ~" F# k5 e
复制代码

+ ~( w/ {! L! y% i1 R总结
" K" Q4 ]0 [& |! ]. }
当你转动电机轴能通过SPI发送0xA6读取到数值变化,基本就算成功了,剩下的就无非是处理一下/ ?3 C) r& Q0 n) X6 u7 Z
————————————————
* l4 j, s3 X9 H2 N版权声明:超级馒头神
, e- j# q% d$ z* N0 d( U, Z3 [, \6 w* P/ Z, s( z3 H& _9 N

, j, O* ]7 M* P( v

点评

磁铁距离芯片的距离应该是多少啊  发表于 2026-5-15 15:22
赞 收藏 评论2 发布时间:2023-2-25 17:59

举报

2个回答
Dawn_11 回答时间:2026-7-14 14:07:29

可以把完整代码发出来嘛

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版