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

【经验分享】基于STM32的LTC6804驱动代码解析

[复制链接]
STMCU小助手 发布时间:2022-1-18 22:27
 LTC6804是一款专门用来做多节电池电池组的监测芯片,最高可监测12节电池,官方误差是低于1.2mv,12 个通道的最快采样速度可以达到290us。
  芯片分为两种型号,6804-1和6804-2,区别在于,6804-1采用级联的形式(级联控制),6804-2采用并联形式(分开控制)。
  除开硬件连接之外,这两种型号的操作都是大同小异,基本可以视为一样,本文以6804-1为例进行讲解。
  1050425-20190403170526219-977762557.png  
  原理图和手册中的推荐一样,就不贴出来了,MCU与芯片的通信方式采用四线SPI,这种通信方式很常见,各种MCU的驱动也好找。(看了数据手册,芯片似乎还支持IIC和2线通信,不过我没有用)

4 M1 E; Q: F& w8 U5 V$ S0 A3 `, F6 E& x. v: q# p1 ?
  下载下来的代码是C++文件,不能直接在STM32上使用,需要进行一些修改。
  首先修改后缀名,改成C文件,然后打开LTC6804.c文件。
8 l( P; ^6 t; T; Y
第一步进行驱动的移植:
  1. void spi_write_array(uint8_t len, // Option: Number of bytes to be written on the SPI port1 H  K2 n) R/ [, y! I8 @
  2.                      uint8_t data[] //Array of bytes to be written on the SPI port( ^3 }, h1 j) l/ j3 q
  3.                      )6 S2 Z. @, k2 K! R
  4. {
    1 m7 W& U9 o7 g5 Z7 o
  5.     uint8_t i;
    - M2 y! R/ R' P; l, B8 d3 E
  6. 4 {9 z6 \  Z/ f
  7.     for(i = 0; i < len; i++)
    6 E! `) Z" f& L: b7 H) }
  8.     {8 L: r# F+ F- i# y2 \
  9.         SPI2_Send_byte((int8_t)data[i]);% X6 u+ N$ {- X9 Q( Q+ r/ z
  10.     }. V# o9 R! }( w. e, T
  11. }
复制代码
  1. void spi_write_read(uint8_t tx_Data[],//array of data to be written on SPI port
    ' h2 n2 F5 Y; U, N' }4 @
  2.                     uint8_t tx_len, //length of the tx data arry2 O% ?2 v0 F% C. m/ h; @* `& F: Y: P! Z
  3.                     uint8_t *rx_data,//Input: array that will store the data read by the SPI port4 E" Q8 d2 o  \; I. s. U
  4.                     uint8_t rx_len //Option: number of bytes to be read from the SPI port/ t/ t3 V2 \9 P$ v2 S- {
  5.                     )/ c& K& b1 g) I0 h8 \9 r* d: X
  6. {
    ' p$ X; M, ^: P4 ?
  7.     uint8_t i;
    0 [4 {) n9 `: @# z4 L
  8. * y) p7 Y; V2 W5 l) }6 |( B" k
  9.     for(i = 0; i < tx_len; i++)
    # v% Y) G7 _8 H* W" y! y7 a
  10.     {
    0 u2 M- i: H3 L7 u9 `; R( L
  11.         SPI2_Send_byte(tx_Data[i]);. }: M; _" V/ ~$ g4 p7 Y
  12.     }* \0 ^. ~5 W; `

  13. & m) s$ E/ e  G/ }
  14.     for(i = 0; i < rx_len; i++)
    , k& v7 y8 t/ W9 }7 w2 I  ?
  15.     {
    ; w: H/ ]' ~; y: G
  16.         rx_data[i] = (uint8_t)SPI2_Receive_byte();/ i- C. f2 U- M; y5 v
  17.     }6 L9 t+ G9 L% l

  18. * h# f% B% T5 Q# x/ z
  19. }
复制代码
# A. Z6 Y1 [) w$ \$ W
只需要把自己的SPI驱动替换上去就可以了。
% n3 o4 r& M2 F+ |) u. {& f
  1. void wakeup_idle()
    ! |9 ]# Y/ H: U5 x  a% @3 p
  2. {
    9 M8 O& K* L% I  H) F0 Q6 n
  3.   output_low(LTC6804_CS);6 q5 a) G5 S3 g( w% |
  4.   delayMicroseconds(2); //Guarantees the isoSPI will be in ready mode# o+ ~4 h* l) H* d/ k$ Q
  5.   output_high(LTC6804_CS);
    - }5 {; M* q/ `- _5 w: Y
  6. }
复制代码

5 j' q' ]  ^0 x9 `* z
自己把这个函数中间的部分实现,或者替换成自己的函数:
  1. void wakeup_idle(void)3 K  G3 Q" J( h
  2. {  I  F: H) g3 ]' C4 p' k+ {
  3.   output_low(LTC6804_CS);
    3 ^/ s- z0 `4 P* D0 m
  4.   delay_ms(4); //Guarantees the isoSPI will be in ready mode
      {! e. b! \0 S) W, J( O
  5.   output_high(LTC6804_CS);2 z+ s$ [9 B: m3 r  `: _
  6. }
复制代码
' w$ s- y- Z' Q) {: Y; O# C
下面是原版的初始化函数:
  1. void LTC6804_initialize()
    4 r; W3 y" Q3 d4 W4 o( J% u
  2. {" ~& e: }* l+ e" N: d% x9 V9 W
  3.   quikeval_SPI_connect();
    / r- ^# l3 u) a" C" h* ~
  4.   spi_enable(SPI_CLOCK_DIV16); // This will set the Linduino to have a 1MHz Clock' G& V, f% e$ E! ~' N7 h
  5.   set_adc(MD_NORMAL,DCP_DISABLED,CELL_CH_ALL,AUX_CH_ALL);7 O6 ^" a; J$ E, Q* N  t
  6. }
复制代码

$ U& H# [8 V8 n. s
我把它根据自己的实际情况修改一下 :
  1. void LTC6804_initialize(void)
    ( a+ i% ^- F7 O' B
  2. {
    2 D2 a2 n* E' B- u3 A
  3.     Drive_LTC6804_Spi_Init();//SPI外设初始化
    . |6 Q. z) L4 p: C# T- y
  4.     init_cfg();        //配置LTC6804的寄存器8 ^( }& C+ }. m$ o
  5.     set_adc(MD_FILTERED,DCP_DISABLED,CELL_CH_ALL,AUX_CH_GPIO1);//设置转换方式等
    . U' |1 @8 _7 E" n* m+ G
  6.     wakeup_sleep();//唤醒芯片
    # A$ e5 e2 B0 p
  7.     LTC6804_wrcfg(TOTAL_IC,tx_cfg);//把上面的设置写入芯片
    ; o; @8 s, F: _
  8.     if (LTC6804_rdcfg(TOTAL_IC,rx_cfg) == -1)  //检查一下到底有没有配置成功
    # u3 P, Y# ]% C+ v) m
  9.     {
    : a& d# h) P( K1 a. X
  10.         printf("LTC6804_MODULAR INIT NG!\n\r");0 o+ A/ s1 i$ v
  11.     }( t/ k+ k2 x( ]' [
  12.     else! T5 X3 K; J2 |. k
  13.     {$ z! g* N1 f; g/ c' a2 G
  14.         printf("LTC6804_MODULAR INIT OK!\n\r");
      t' R( D9 r: i2 {2 r0 e
  15.     }" K. _7 ~& n( u* r; p

  16. 7 T# w: r  ]$ t4 ^; g1 v
  17. }
复制代码
  1. //手册第49页& e8 x9 J# X7 t, G4 R4 c
  2. /* 寄存器               8         7          6         5         4         3         2        1        */
    3 v9 c/ J  w% L. [2 r& c
  3. //CFGR0       RD/WR   GPIO5     GPIO4      GPIO3     GPIO2     GPIO1     REFON     SWTRD    ADCOPT
    ( L0 O% T: Y# ^0 L% R
  4. //CFGR1       RD/WR   VUV[7]    VUV[6]     VUV[5]    VUV[4]    VUV[3]    VUV[2]    VUV[1]   VUV[0]: h2 u! r% O7 A/ F  F
  5. //CFGR2       RD/WR   VOV[3]    VOV[2]     VOV[1]    VOV[0]    VUV[11]   VUV[10]   VUV[9]   VUV[8]1 c8 J# |# k/ Y% ^' F/ H' h0 ^
  6. //CFGR3       RD/WR   VOV[11]   VOV[10]    VOV[9]    VOV[8]    VOV[7]    VOV[6]    VOV[5]   VOV[4]
    : x3 T$ V& p+ W8 p
  7. //CFGR4       RD/WR   DCC8      DCC7       DCC6      DCC5      DCC4      DCC3      DCC2     DCC1, G" z0 r: \1 d
  8. //CFGR5       RD/WR   DCTO[3]   DCTO[2]    DCTO[1]   DCTO[0]   DCC12     DCC11     DCC10    DCC9
    ) K% U" l9 D! g8 v2 O# m% z
  9. void init_cfg(void)
    1 K: I% D# L0 Z9 Q; h5 w/ u- ]# V2 o
  10. {
    0 }3 F- D1 t; W. u8 N) E$ x1 O
  11.     int i;
    6 X* |/ j, f; \
  12. $ m8 o: B( m' U* P. c3 j9 k
  13.     for(i = 0; i<TOTAL_IC;i++)
    4 }- h1 [' k0 M7 [9 j4 s
  14.     {/ m1 m6 M+ Z/ D6 q- d# e
  15.         tx_cfg[i][0] = 0xFE ;   //GPIO引脚下拉电路关断(bit8~bit4) | 基准保持上电状态(bit3) | SWTEN处于逻辑1(软件定时器) | ADC模式选择为0
    6 R* C9 e, n# C5 w9 r0 |
  16.         tx_cfg[i][1] = 0x00 ;   //不使用欠压比较功能' l  {: ?! \# o; p5 L! N  a
  17.         tx_cfg[i][2] = 0x00 ;   //不使用过压比较功能
    8 g; r- V. c. P  s
  18.         tx_cfg[i][3] = 0x00 ;
    ; Y, I: H0 T' k4 ^$ X
  19.         tx_cfg[i][4] = 0x00 ;   //不使用电池放电功能3 o: U0 i# K3 Z( D& f" V" H
  20.         tx_cfg[i][5] = 0x00 ;   //放电超时时间
    8 I$ k0 ^5 o7 u, s; {$ U; r) {
  21.     }
    & h1 @3 t6 }% u6 Z0 t
  22. }
复制代码

8 ^9 A7 X* @& }0 {* j8 k: c3 R/ i, w3 M4 `" B' M3 `
这里只使用了最基本的电压采集,其他的功能都没有用。
上面的代码里面有一个宏 :TOTAL_IC。
这个宏是用来定义一共有几片LTC6804-1的,比如我这次使用了2片,那么它的值就是2.
上面的寄存器设置,可以参考手册:
1050425-20190403172123490-1539331691.png
比如需要追加一些别的功能,便可以根据手册的寄存器进行设置,比如设置报警,设置均衡,设置其他的功能。
以上初始化部分就完成了,或者说移植就完成了,然后便不必对代码文件进行任何修改就可以直接使用,接下来是采集部分:
我是把采集放在main中进行。
  1. /* 唤醒6804 */
    & z+ h+ P# J! y9 t0 E8 m5 l
  2.         wakeup_sleep();
    / y9 s* z/ P, ?' E, @
  3.         /* 启动电压采集 */: M- i# ?4 e. \9 r
  4.         LTC6804_adcv();7 M7 ^. t3 z$ I: I
  5.         delay_ms(50);
    # U% m; b! h3 A4 m# c. W$ Y2 |% q
  6.         /* 读取电压 */. l6 u5 P. ~7 w. ~& P& A: K5 z
  7.         res = LTC6804_rdcv(0, TOTAL_IC, vol_buff);
复制代码

' @4 L# V. D. \' W' a
以上便可以采集出电压了。
+ z; X( Z8 r3 Y, K
※如果发现几个级联起来的6804,有些片子可以运行正常通信,有些又不可以运行甚至无法通信,在排除硬件的原因以后,可以查看一下这个地方:wakeup_sleep(),试着把唤醒时间设置的长一些。
* y+ f$ i  x$ m2 h5 Y% @8 F
最后:可以看出来,精度还是不错的~
) |; @- v' y  X5 i
收藏 评论0 发布时间:2022-1-18 22:27

举报

0个回答

所属标签

相似技术帖

官网相关资源

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