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

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

[复制链接]
STMCU小助手 发布时间:2023-2-25 17:59
前言! j3 |& F% N" u) V+ y
ic-mu基本情况介绍
' K0 V; W3 x) c: N+ `
9 _9 C, v, }' yIC_MU是一款离轴的1.28mm磁编码器,主要用于电机控制居多,当作磁编码器,优势是能使用多种通讯协议(SPI,BISS,SSI),但是目前中文网上使用资料较少,因此我自己写一篇关于IC_MU的SPI通讯读取方式的文章,读取芯片为stm32G4系列,然后代码在stm32G4和stm32F1系列基本通用。
. U( \7 Q! d5 a芯片基本介绍如下
9 L$ E! M% \$ D0 a, ?2 p- b1 [7 I
325acfd031684154a51541ebaf3bc1f5.png
! r, W1 Q# A. b
$ t* S; g, C' ~: B) v. |提示:以下是本篇文章正文内容,下面案例可供参考2 Y7 s$ w. B1 S
5 J+ [$ f# n3 p7 s
一、硬件连接
/ t& ?4 u0 a2 E0 s
按最小系统连接。IC-mu需连接eeprom存储角度,供电为5V. t% P- s2 |+ X* k' O& X- }; G
' n+ A+ F+ h- K1 f9 @( |8 x# F
二、STM32 cubmx配置模式' a+ S7 p- m. ?# h" U2 S. d
STM32G491配置cubemx8 S$ \+ ^% J. S* Z; p( R
) p4 `  Q0 I3 N9 ~" q# r" B. T
b31de8a144684fd8815c3aea74271bba.png - x' p) r: ?3 S/ U1 t  z, _# m  K1 U

; @; R  [9 Z8 ^. _. m* V

; {$ R5 R2 R2 ?; ?2 j如图几个关键点# a/ T! D6 }8 S9 h) G# F* |9 u
1数值格式:可以选8bit,但是我觉得16比特配置更方便,如果要配8bit只需将数据拆分即可
% i" ^) o" x! ~3 v9 c2波特率 没有明确要求,12M以下都可以
8 z0 W/ v6 N% b5 F4 Y3SPI模式,SPI一共4种模式$ {. d9 ~' ?8 I9 i8 \

/ A& F4 v4 M0 S) Y; F, G- A# ?+ t
896f63f11e5f4a62b6e64e9527c395a0.png ! y( h, G8 ?+ S2 g: A
0 Z8 k, w: e" \3 D- @9 R1 E; q+ ]
IC_MU只支持模式0和模式3,如上图所示采用模式3 CPOL选择High CPHA选择2Edge. ^- h8 c0 h7 p

% q- q( \: g0 ?8 d  i
2e692f827e4048f38f0a6020450c06ec.png
; X$ |2 Y: y5 s! @4 y; @) Q" W- @9 j
, s0 X2 ^6 q( `
# T: s# d- R; u5 r
SPI通道要设置为高速
7 w! Y6 N7 T* v除此之外还需要设置片选信号,默认为高电平# J$ S; i0 Z- D3 d7 u) s
5 K# W, S* \4 \" V2 U( K
e8715427ead043cd984ccaaf608c5208.png + G2 s) T7 [. d* N
7 F" e; j5 U9 G" R& O+ K0 S4 L
三、软件代码及思路
+ |+ b5 e9 ]# l+ N首先需要对整体进行说明,需要将编码器激活,配置在SPI通讯模式
# v0 }5 A$ v; i# ]8 h
( i1 @0 U; x5 c. t. X
1.寄存器指令介绍
9 }8 F5 [9 T5 U# h: X" g* E+ \2 s0xB083 Activate,激活
9 E* C) i6 p1 \" @' I" _, |0xA6FF Position Read 位置读取命令, ^( D1 u! a3 w# y# l* o
0x8A Register Read (Continuous) 寄存器读取(连续)( E! Q$ n# i- e& i& \9 F6 `9 t, r
0xCF Register Write(Continuous) 寄存器写入(连续)
( L0 K0 `1 r1 j% I: ]4 W" S$ ]& q0x9C Read Status 读取状态寄存器 指令
3 U" _3 V6 [' i$ v+ T0x97 Register Read(Single) 寄存器读取(单次)( ^/ I& ]! @/ t+ U
0xD2 Register Write(Single) 寄存器写入(单次)
% D& v9 B- T  E6 j5 {) e) \$ S/ n
% y# k8 A& U- l6 ~) i( [

+ q) ~" c7 ~. i+ z1 B# X; e2.代码介绍
1 Z; d7 w+ _( l: u( s对片选进行宏定义,然后对SPI数据传输底层函数进行定义
0 \6 U9 ?" C# V! `* _5 u, c. v+ h( Y2 X
1初始声明和定义
  1. #define    SPI_IC_MU_CS_LOW();       HAL_GPIO_WritePin(ABS_ENCODER_CSN_GPIO_Port, ABS_ENCODER_CSN_Pin, GPIO_PIN_RESET);  o: b4 Y, v  F0 ]; U
  2. #define          SPI_IC_MU_CS_HIGH() ;     HAL_GPIO_WritePin(ABS_ENCODER_CSN_GPIO_Port, ABS_ENCODER_CSN_Pin, GPIO_PIN_SET);
    ' n* m. c. d8 \5 E

  3. ; z8 J) S4 F6 s6 q3 h+ |( O# k0 ~
  4. uint16_t SPI_SendHalfWord(uint16_t HalfWord)
    $ ^* v$ J* s' B; [
  5. {8 }( c- x6 u! |$ W
  6.   
    - d+ m5 w- p5 g; V6 D
  7.   SPITimeout = SPIT_LONG_TIMEOUT;" `, G% d+ e. m
  8.   /* Loop while DR register in not emplty */4 V8 N7 b2 M2 ~1 d7 }" p! D5 `
  9.   while (__HAL_SPI_GET_FLAG( &hspi1,  SPI_FLAG_TXE ) == RESET)
    & T3 q, o: B& k, T3 C. s
  10.   {
    ) D  N* @/ H0 Y% r
  11.     if((SPITimeout--) == 0) return 0;
    / A0 }8 n/ e/ r9 q3 D
  12.   }# j" T+ f/ x" p4 g+ e; z  E5 i
  13.   /* Send Half Word through the SPIx peripheral */
    . w: ~1 _6 z$ b# W
  14.   WRITE_REG(hspi1.Instance->DR, HalfWord);3 p/ g( z4 u) ^" o0 V( @! k" h3 Q6 ?
  15. * t9 T0 L% @! ]& T. `
  16.   SPITimeout = SPIT_LONG_TIMEOUT;
    4 ~1 t( D; r9 T7 e) t& ~
  17.   /* Wait to receive a Half Word */
    7 m$ N2 E7 U  A* Q
  18.   while (__HAL_SPI_GET_FLAG( &hspi1, SPI_FLAG_RXNE ) == RESET)
    , u2 u5 Z8 a5 M
  19.    {
    ; }# z1 o- I. I+ E% W; H  D
  20.     if((SPITimeout--) == 0) return 0;# ?/ {$ ?. Q# R1 J/ c
  21.    }/ O6 j5 Y" H" n. j8 j/ ?
  22.   /* Return the Half Word read from the SPI bus */+ V7 K5 h1 N0 ?: g9 v5 o7 `& R! Z
  23.   return READ_REG(hspi1.Instance->DR);
    8 [& r; c  t4 A5 @' h4 {
  24.   # A. L2 E( `& b7 j2 U" `
  25. }! B( E6 h- @  G
复制代码

: m( i% N: K. _0 o: f, w  G2激活寄存器
9 f$ L# B. \/ w8 Q) g3 `0 f激活后才能对寄存器有操作1 E- f) q  l) ^
  1. void ACTIVATE_FUN(void); J% G" D7 t. w- t4 b1 p, h
  2. {3 A& b  s; w: h. d! a/ X
  3.   uint32_t ICMU_Temp = 0;* X1 g& W  M7 |) {& c
  4.   SPI_IC_MU_CS_LOW();9 f7 z6 w9 _) C% L
  5.   ICMU_Temp= SPI_SendHalfWord(0xB083);" F& ?  ^5 H/ C! q; I6 D' D$ {  j
  6.   SPI_IC_MU_CS_HIGH();  ?/ N$ O" y2 x  H) j5 j
  7.    Delay(100);
    / n0 h2 P: t( J/ |0 n( J" U
  8. }2 L; e: @1 H  {1 Q
复制代码
; D' E0 _0 E3 p! e8 U
3编码器初始化函数
1 c7 C& N1 @6 R  N- Z: X, j初始化发送0xB083激活编码器,编码器配置为单圈14位,具体见数据手册+ X) d' t( L% I; V9 Q
初始化完成后可删除函数,状态会固化在配套eeprom种,不会丢失
' `% [3 X9 r! O' [# Q7 {& r
  1. void Init_ICMU(void)! J1 ?1 d% G/ }" b
  2. {
    + y. }7 m8 q1 S$ T( ]2 B  N
  3.    ACTIVATE_FUN();
    , o' l* c6 K0 j1 P% n% f7 ]& U
  4.   uint32_t ICMU_Temp = 0, ICMU_Temp1=0;( w) F' w) F$ A. C' M2 H. {$ J4 M
  5.   SPI_IC_MU_CS_LOW();
    % p9 m0 ~9 r) K+ m/ V) n8 J
  6.   ICMU_Temp= SPI_SendHalfWord(0xCF00);
    4 b  n5 u% ^/ V
  7. ICMU_Temp1= SPI_SendHalfWord(0x8E20);9 z' c3 M- W& z1 W0 |( E- }) x
  8.   SPI_IC_MU_CS_HIGH();
    9 ?: R7 U4 [7 s+ p
  9.    Delay(100);
    " X; ]/ d4 X1 H% b. T2 @8 |
  10. }
    ' k6 ^7 ~$ v% K' ^  a% W( a; @$ e
复制代码
# g* o- {/ C; c$ N& p+ G( I& D4 p
4数据读取
6 g; u5 X, R( b& b' O# V- t编码器数据读取,读取指令为0xA6
( o  O. R8 z2 X  F# E3 n
  1. uint32_t SPI_SDAD_transmission_Fun ( void)& N6 y; A9 r1 y! O& V; x& q
  2. {. u2 I1 n& e  \# Q* v
  3.        
    ! ?+ c0 G# G3 L- p$ M
  4.         uint32_t Temp = 0 , Temp1 = 0, Temp2 = 0 , Temp3 = 0 ;, @. @/ X% n! ^5 p( T1 X' q% E) l
  5.   ACTIVATE_FUN();( q% b+ c7 r( V( ?: v
  6.         - y' \$ M+ m6 M1 ]
  7.    /* 开始通讯:CS低电平 */  n* Q: i; j0 s+ O1 R8 i( {0 ^* a
  8.    SPI_IC_MU_CS_LOW();
    , C" |& [7 _/ U3 z: Y# t. K$ w
  9.         Temp1=SPI_SendHalfWord(0xA6FF);8 K* `+ i/ E# L' y/ \& b
  10.         Temp2=SPI_SendHalfWord(0xFFFF);3 o6 |& e3 G" @# W
  11.        
    " P1 n1 i5 x2 d4 T9 g/ y. l, v
  12.         + ?/ W6 w8 x4 c0 w% @* u
  13.          /* 结束通讯:CS高电平*/: p9 Z/ f- W$ s9 I6 [4 x8 ?5 _
  14.    SPI_IC_MU_CS_HIGH();
    - Z4 Q( D( @% Q# s7 [# D
  15.      2 m  S. B6 n- {3 ~) F: U! L# Y
  16. //  Temp = (  (Temp1 << 16) | (Temp2 << 8) | Temp3  )>> 5 ; //读出数据,右移5位,共24位,有效位为19位  % J& E( a4 e/ X
  17.    Temp=  (Temp1 << 16| Temp2) >> 13;   //总体32位 19位的话需右移13位
    # g$ L; Q, U! R2 B
  18.           Delay(1000);; M2 h, }* S& @
  19.          return Temp;1 @( g+ z$ S( ]6 e; h, x1 U# p, Y
  20. }" ]. W/ B$ E4 t$ h$ L
复制代码
2 [! o/ s3 B( X2 P
5角度计算
* {0 W( p8 Y' D: t* C1 t: `! b角度我用了11位,初始默认存在一个数值因此将他减掉了,然后按照360度进行划分  F2 j5 v# F8 H/ ~) W, I/ n3 L2 [' W
  1. float Position_Calce()
    % H4 L2 J  N8 e* f
  2. {
    , N9 d! _# F& t) w/ M5 Z+ Q
  3.     uint32_t  a ;
    $ w' o) g9 x5 v2 V
  4.           double b;
    ! Q: k, f' h1 Y+ d- y) h( o/ y
  5.           float  c ;
    : Y% z( G8 j) C
  6.                 uint32_t  www ;
    4 [* s8 N9 C7 M3 K7 e# A0 p# v
  7.                 double  n ;0 Y8 a+ _, X: j7 g+ n$ {
  8.      a=SPI_SDAD_transmission_Fun ();" a5 c! S1 z6 l+ m9 ?
  9.       n=((a-0x00053000)/2047);//计算角度
    2 J& }' B; F6 e. t, g
  10.        b= 360.000* ((double)(a-0x53000)/2047);
    * C! V: `+ _% y$ @
  11.       
    9 |  ~# K5 N# `
  12.                         return b;                        0 \% V) U4 N- [5 a- H) M. `4 y# I* s
  13.   ; M2 q5 g4 u2 v3 p1 o
  14. }
复制代码

- y' b' z& j8 z6主函数读取角度# K2 e. n) f1 i4 C$ ?/ z6 S2 B5 b
  1. float position_fk_f=0;  //位置计算
    + G- l+ G( r3 A
  2.         3 i5 s) j2 N" {
  3. while (1)
    ! K0 V! g" c$ Y$ A" t1 T
  4.     {  `5 G9 _1 a% p# s% A6 Q! z
  5.                   position_fk_f=        Position_Calce();, T- w, i* F! W, L4 i
  6.                   }
    ! b: ~9 e4 i# Y/ G1 W! |9 b9 A) b2 y
复制代码

% B. X3 N1 ]5 V3 p6 X总结
' F( p% h7 K' h) \- B6 n
当你转动电机轴能通过SPI发送0xA6读取到数值变化,基本就算成功了,剩下的就无非是处理一下9 V; X+ g9 }, c  k
————————————————' K! \  G- O3 K+ `4 \; X- \! Y
版权声明:超级馒头神; F9 N# H" I4 m* S0 E, L

' A6 T0 _, O- h0 r' J
* |( y8 P; Q. @. B: V5 D

点评

磁铁距离芯片的距离应该是多少啊  发表于 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 手机版