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

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

[复制链接]
STMCU小助手 发布时间:2023-2-25 17:59
前言
" R6 E- B4 F$ x6 L$ R) [! Gic-mu基本情况介绍
- k. U1 O. f$ N; q: R. J& M* e+ {* j+ g7 v' `6 {
IC_MU是一款离轴的1.28mm磁编码器,主要用于电机控制居多,当作磁编码器,优势是能使用多种通讯协议(SPI,BISS,SSI),但是目前中文网上使用资料较少,因此我自己写一篇关于IC_MU的SPI通讯读取方式的文章,读取芯片为stm32G4系列,然后代码在stm32G4和stm32F1系列基本通用。
; {/ b, _1 l7 a. A& D4 Q芯片基本介绍如下
$ v! S* h9 H: V/ _* ]7 S" |9 z2 S' u. ^, w7 m' T
325acfd031684154a51541ebaf3bc1f5.png
2 o" b6 B; e; k2 f1 d7 l. x1 o- o; Q% E& c3 ~% \" U  _
提示:以下是本篇文章正文内容,下面案例可供参考
" K9 P+ s1 M  p# ]+ p3 B* d
0 C2 f9 W' }. i; R3 U' u+ R. u
一、硬件连接
" A: U8 n. c1 ?! x% |
按最小系统连接。IC-mu需连接eeprom存储角度,供电为5V! L9 b: C" ~+ `. |
  f* _/ E5 y: x% t# h
二、STM32 cubmx配置模式
  O6 }- B6 q4 QSTM32G491配置cubemx
' m' ], `. a2 }  @, }* M) K& K
$ u9 H, K5 f+ |& s* {- i: h* M* {
b31de8a144684fd8815c3aea74271bba.png   q3 f  [3 Y( u! e1 R

0 Q" d3 m* e% H6 m
5 V2 P+ Q( l# l4 N6 a( ]  l4 l0 q
如图几个关键点
. ]- W5 |4 w* P% A' e1数值格式:可以选8bit,但是我觉得16比特配置更方便,如果要配8bit只需将数据拆分即可
$ r: q# S$ O. [* o, |) c5 k; ]2波特率 没有明确要求,12M以下都可以! `5 H0 H) x" L4 W, a. u
3SPI模式,SPI一共4种模式( O8 V2 a. t& a. E

3 W7 M* T% H5 ^4 |6 [
896f63f11e5f4a62b6e64e9527c395a0.png : m' T3 x8 {# p1 ^- k/ G9 B8 _. h
. a8 ~% H- g7 B1 t
IC_MU只支持模式0和模式3,如上图所示采用模式3 CPOL选择High CPHA选择2Edge$ [5 u  R  \( X5 i* J: S

, f% u( c/ X; u8 u* R* O' H
2e692f827e4048f38f0a6020450c06ec.png 3 b4 |- t6 a3 p

, {# f" _. j. E/ c: G4 h* ]

" |9 d* d& s' x( fSPI通道要设置为高速
, ]6 H1 P7 Y3 `- H) S除此之外还需要设置片选信号,默认为高电平+ I, Y$ d) Q7 o* O& k2 l
: \8 V$ n. @; y, j
e8715427ead043cd984ccaaf608c5208.png , p( g: S9 q5 @" i: m7 e9 f# ]

, d9 s' D% ?7 R& W
三、软件代码及思路
. d4 G2 x( A; e9 R, |7 T0 i首先需要对整体进行说明,需要将编码器激活,配置在SPI通讯模式- ?& I; m/ L- d7 L6 j

! R6 g$ m! C& ]
1.寄存器指令介绍
" c. r% [7 C( {0 t9 ~4 w6 d0xB083 Activate,激活% D0 q5 I/ }* P$ n4 F
0xA6FF Position Read 位置读取命令
( f7 O: f: j- _$ E0x8A Register Read (Continuous) 寄存器读取(连续)
* S2 _8 p! p# q% l. l% d0xCF Register Write(Continuous) 寄存器写入(连续)1 n3 Z5 _! Y5 |8 {8 w. C0 m& j
0x9C Read Status 读取状态寄存器 指令" n1 i, Z$ C! ]" ?
0x97 Register Read(Single) 寄存器读取(单次)
% u) f* e7 W1 R& z% Y. U0xD2 Register Write(Single) 寄存器写入(单次)
) E- b: a2 L2 m" a( m3 I
/ c# X1 l3 p( E3 ?7 W% G( \7 C; U

) b; S& i& W; m# E2.代码介绍
! s% |/ Y2 C; I8 K+ s8 J) s0 P对片选进行宏定义,然后对SPI数据传输底层函数进行定义* W; c3 i0 o% o7 p$ O
" s1 b! _: f  K
1初始声明和定义
  1. #define    SPI_IC_MU_CS_LOW();       HAL_GPIO_WritePin(ABS_ENCODER_CSN_GPIO_Port, ABS_ENCODER_CSN_Pin, GPIO_PIN_RESET);* G) H- F% Z2 f' D! O  N
  2. #define          SPI_IC_MU_CS_HIGH() ;     HAL_GPIO_WritePin(ABS_ENCODER_CSN_GPIO_Port, ABS_ENCODER_CSN_Pin, GPIO_PIN_SET);8 }5 S3 M$ R8 E- i1 ]
  3. ( W$ F9 t1 g% v7 u
  4. uint16_t SPI_SendHalfWord(uint16_t HalfWord)2 O3 p0 c! G( g6 l  {
  5. {; D8 ?/ v; p# c& S5 V* Q# x
  6.   
    : [" h2 r6 h7 E" E
  7.   SPITimeout = SPIT_LONG_TIMEOUT;
    & m1 m9 R# ?' C# f
  8.   /* Loop while DR register in not emplty */$ n8 s3 c* i: G
  9.   while (__HAL_SPI_GET_FLAG( &hspi1,  SPI_FLAG_TXE ) == RESET). C" r' `& |) y: m- ^
  10.   {
    8 g  E1 e) R$ }% j3 a
  11.     if((SPITimeout--) == 0) return 0;
    4 l2 \* ?6 h5 M, @9 o% f2 x- G  F
  12.   }
    0 I: z! e6 v+ x4 |* q
  13.   /* Send Half Word through the SPIx peripheral */
    # t# C. b) x2 m$ s. Y7 K+ l9 N% L0 [
  14.   WRITE_REG(hspi1.Instance->DR, HalfWord);. _' o1 D  c) d7 b3 J$ k, h/ X

  15. ; l2 g1 o9 j# j1 D
  16.   SPITimeout = SPIT_LONG_TIMEOUT;
    + F6 [& ]4 }2 _$ U
  17.   /* Wait to receive a Half Word */
    7 G/ `* Y9 E' ?1 S: s  R8 }
  18.   while (__HAL_SPI_GET_FLAG( &hspi1, SPI_FLAG_RXNE ) == RESET)  u) A" s5 X# ]' M
  19.    {
    & Q2 F7 x% p3 o+ g5 K
  20.     if((SPITimeout--) == 0) return 0;
    7 `; }/ g# j7 R# z1 ]5 k8 C
  21.    }
    % X0 n& w. Y. T8 @/ y0 c
  22.   /* Return the Half Word read from the SPI bus */- a3 q1 s1 H0 i3 }& U! f- w( \$ s
  23.   return READ_REG(hspi1.Instance->DR);
    # D9 m, {0 _6 X4 e* t
  24.   
    : e& t' l5 c3 R. [2 h/ K
  25. }) [' y6 k7 u4 H/ E. N, q6 B
复制代码

3 d& g0 A4 V* K+ W2激活寄存器% v# Q5 P& b# M% Q) o: W& A9 c
激活后才能对寄存器有操作& {" h: Z' |. q, d6 f6 j9 r6 `
  1. void ACTIVATE_FUN(void)
      |$ L: L+ G9 q6 O. r
  2. {
    ( X2 \# |' i1 t7 C, W
  3.   uint32_t ICMU_Temp = 0;
    5 I& C, v. p0 N# W) O6 [
  4.   SPI_IC_MU_CS_LOW();1 d9 t- [1 S. `( j. W
  5.   ICMU_Temp= SPI_SendHalfWord(0xB083);: g" N8 q! d* M" L. d
  6.   SPI_IC_MU_CS_HIGH();; W& T2 h, q5 c' K. }9 n" m5 a, c
  7.    Delay(100);3 l$ S5 M" k9 Z# H
  8. }
    , m  `# A, Z  H8 Q2 i  B* F
复制代码
0 }  s) O, r5 g4 s% f3 Q
3编码器初始化函数. D" \1 O8 |8 e7 l4 ~4 f' {: r
初始化发送0xB083激活编码器,编码器配置为单圈14位,具体见数据手册
2 Y8 j, B. o4 o! W' Z/ @初始化完成后可删除函数,状态会固化在配套eeprom种,不会丢失
2 j, n$ X. V9 g& l, O# N8 q; \
  1. void Init_ICMU(void)
    3 r  j: X' S9 Z" Y7 ^  Y. u7 V
  2. {
    7 z$ O& U& O* v1 l$ N# G& y4 s* D3 l
  3.    ACTIVATE_FUN();
    " b4 b! K1 C$ Q; v8 \/ J2 w9 N
  4.   uint32_t ICMU_Temp = 0, ICMU_Temp1=0;& w, F% D; u$ J1 k) K  f2 ?& X
  5.   SPI_IC_MU_CS_LOW();, ?" q; O. t8 w  |' V8 a4 r" X
  6.   ICMU_Temp= SPI_SendHalfWord(0xCF00);: W: n' ~& a( [+ i" N0 Y/ F6 `9 F9 a
  7. ICMU_Temp1= SPI_SendHalfWord(0x8E20);' v& c5 ~5 |7 ^6 ]
  8.   SPI_IC_MU_CS_HIGH();
    ; n5 X9 E% R" U& T
  9.    Delay(100);
    : \. j2 T% V; [, |* U2 R% t* m5 J
  10. }
    , M5 C  p$ l, t# ?% v
复制代码
7 b2 d: P5 U8 e, X6 C
4数据读取
5 ^7 s/ {0 m  j, W' a) H6 X编码器数据读取,读取指令为0xA6. E7 Q: z. P8 M& K3 i" A6 P
  1. uint32_t SPI_SDAD_transmission_Fun ( void)
    . S( ]; \- g: r4 \
  2. {( k' M. p0 q; E8 V8 ^
  3.         ! k& i, ~" ?2 z5 l- ~5 D  {
  4.         uint32_t Temp = 0 , Temp1 = 0, Temp2 = 0 , Temp3 = 0 ;7 P* k- K7 c' d* Y/ @0 k
  5.   ACTIVATE_FUN();
    5 ^: t8 T+ v) x/ {. V' O0 t
  6.        
    6 \% T% a, v' V) `! c7 ]
  7.    /* 开始通讯:CS低电平 */# t" L  Z7 _6 p* `
  8.    SPI_IC_MU_CS_LOW();; M) Z0 j" D' p( r3 S0 p
  9.         Temp1=SPI_SendHalfWord(0xA6FF);2 S. F. y! C" K; A9 a9 I) _" S" t
  10.         Temp2=SPI_SendHalfWord(0xFFFF);1 g/ X# L/ z' w6 l
  11.         ) ^7 L$ [' q- U5 J/ ?
  12.        
    ; Y, x* V# n; ?' H. ]  ~' r! j8 b1 V
  13.          /* 结束通讯:CS高电平*/
    * g  }* n4 w9 q7 b
  14.    SPI_IC_MU_CS_HIGH();
    - Q& ]2 r% e6 t1 ^1 L; _
  15.      ' |' R" y  G2 E2 K3 f
  16. //  Temp = (  (Temp1 << 16) | (Temp2 << 8) | Temp3  )>> 5 ; //读出数据,右移5位,共24位,有效位为19位  : m2 d% a- [( Z" R, m
  17.    Temp=  (Temp1 << 16| Temp2) >> 13;   //总体32位 19位的话需右移13位
    5 d- B  k6 _4 k7 |+ J7 X6 O
  18.           Delay(1000);
    5 k6 O0 r! S4 ~0 [: {% @
  19.          return Temp;
    / C2 i- k6 e: O1 l0 N! M
  20. }$ @' S/ K+ c! k& y
复制代码

# C4 Z% D8 X. h7 F) \7 D5角度计算# o. v: N- U. Y& X6 y) g& A* |. p
角度我用了11位,初始默认存在一个数值因此将他减掉了,然后按照360度进行划分3 B, W1 P: ^; Z
  1. float Position_Calce()! {) F/ v( T! H* B. Q
  2. {4 J1 s1 o( b& p! O+ f, B" K
  3.     uint32_t  a ;+ I$ R9 J; b7 _% V. @
  4.           double b;) A& q6 O* D. V" X) H
  5.           float  c ;+ z! w+ g% y* E# o
  6.                 uint32_t  www ;
    ! A! ?3 r" z, x7 Q
  7.                 double  n ;% n+ m# @7 @* X* L! V9 n
  8.      a=SPI_SDAD_transmission_Fun ();
    9 X% N9 Q6 Z* t- I" W4 m( Q. w
  9.       n=((a-0x00053000)/2047);//计算角度4 N: f  ^" G: i7 q# u$ ]; g
  10.        b= 360.000* ((double)(a-0x53000)/2047);
    7 j' z% X8 n- q0 y9 s+ ~1 v
  11.        ! V8 T0 `8 V2 r
  12.                         return b;                       
    & S( n: N- T, M7 C0 m
  13.   
    6 ?0 ~$ \8 m% M
  14. }
复制代码
: y* ^. R/ y: f" T
6主函数读取角度8 h2 B: s3 R/ w0 F
  1. float position_fk_f=0;  //位置计算; {0 \& E$ ]8 q% W
  2.         2 C4 d( S& B# V1 m- u! B
  3. while (1)
    9 D4 ^2 o. G$ A$ f5 F
  4.     {
    . T. L3 T  U( f/ d  b
  5.                   position_fk_f=        Position_Calce();
    ! N7 q9 J5 T$ f) i& b! Z! e
  6.                   }
    : t: Y% w7 y7 k( d9 M5 \5 [
复制代码

- [, E' U' P& \  I' a总结

% X8 f1 |- Z. C' k' `当你转动电机轴能通过SPI发送0xA6读取到数值变化,基本就算成功了,剩下的就无非是处理一下
) m* p& K, ~$ y————————————————/ j' x# g& T/ o) B
版权声明:超级馒头神
/ B4 T& B5 T" q! F2 U6 k* H  W! I% s; N: A8 s6 ?
+ [/ W% {& e$ z% q9 d& ~
收藏 评论0 发布时间:2023-2-25 17:59

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版