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

【经验分享】基于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线通信,不过我没有用)

% y# ^! u( c7 V! }) |, S7 r, @/ r" Z1 O* H8 V
  下载下来的代码是C++文件,不能直接在STM32上使用,需要进行一些修改。
  首先修改后缀名,改成C文件,然后打开LTC6804.c文件。
& g0 G* @  j& z) I% h
第一步进行驱动的移植:
  1. void spi_write_array(uint8_t len, // Option: Number of bytes to be written on the SPI port
    6 ^& b! R- Y/ u  s8 F
  2.                      uint8_t data[] //Array of bytes to be written on the SPI port+ O5 R8 K9 {  p# f6 X5 z1 H. x
  3.                      )1 z, D$ C! ?/ ^& m3 N1 Q7 V
  4. {
    * ~+ `) O$ {% E, c
  5.     uint8_t i;5 R1 Y7 W2 B  Q( e! [, b

  6. 6 R4 }% N( X1 j6 n. h
  7.     for(i = 0; i < len; i++)
    5 ^% \7 V# |3 D! X( S) Y5 ^: s
  8.     {
    % R7 c6 f. n7 g4 r: _
  9.         SPI2_Send_byte((int8_t)data[i]);
    2 a3 i" T+ F1 H/ ^
  10.     }: v" {& z- n7 ]( B! q; I" H5 ^
  11. }
复制代码
  1. void spi_write_read(uint8_t tx_Data[],//array of data to be written on SPI port
    - V, m$ u( V9 E, f* ]0 a* f
  2.                     uint8_t tx_len, //length of the tx data arry
    # `; [$ h, c& R* f- o2 s
  3.                     uint8_t *rx_data,//Input: array that will store the data read by the SPI port, P( [4 q! q3 I% ]
  4.                     uint8_t rx_len //Option: number of bytes to be read from the SPI port- I4 _7 `8 Z0 Q
  5.                     )
    " ^! V2 K! b4 e4 Y# ]1 j4 q
  6. {  u7 P" D  v' F. T
  7.     uint8_t i;7 n" J3 s- ]4 x

  8. $ C% Q, S+ E1 C  r' |. N
  9.     for(i = 0; i < tx_len; i++): M. d$ }# R* Y9 L" x+ m4 L
  10.     {' e5 \/ V+ {/ q- t# D
  11.         SPI2_Send_byte(tx_Data[i]);
    3 K$ M! M, O' Z* A/ H# t
  12.     }
    0 k* i* ~, t. l% f6 L3 S- E

  13. 0 u3 t% n* p$ H
  14.     for(i = 0; i < rx_len; i++)
    % R! U7 W. T  {9 b
  15.     {: O- |: Q* {% z0 u, N' V: E
  16.         rx_data[i] = (uint8_t)SPI2_Receive_byte();
    7 r% C+ ^1 a6 k+ I
  17.     }. b; c8 ]- L  ^0 t# N7 r; K% m

  18. 0 ?" `; K  a1 N) ?: K7 t" Q
  19. }
复制代码
( f, e: y# Y) I9 Y) y8 b7 W- b# t6 d5 ?
只需要把自己的SPI驱动替换上去就可以了。

4 E- K) ]; p% @0 n% I
  1. void wakeup_idle()
    3 l$ n6 V5 o1 \- q
  2. {
    5 F" \' w" f# H
  3.   output_low(LTC6804_CS);: J3 d7 Y0 R+ ~) x4 a: \
  4.   delayMicroseconds(2); //Guarantees the isoSPI will be in ready mode
    + V7 q2 c" B* o1 Y0 s
  5.   output_high(LTC6804_CS);
    ) d/ o) |; ]/ G3 t9 Z
  6. }
复制代码

' c% N& C5 g4 h/ W" Z2 R: g, |
自己把这个函数中间的部分实现,或者替换成自己的函数:
  1. void wakeup_idle(void)
    : |$ k  F2 r$ y2 B; ?/ Z
  2. {! W% p0 G0 j; \+ A: p3 \
  3.   output_low(LTC6804_CS);
    , w3 G0 X" n' c- q1 k) y( O
  4.   delay_ms(4); //Guarantees the isoSPI will be in ready mode$ l9 b4 w# P2 c" G: G) ?
  5.   output_high(LTC6804_CS);8 J' d$ \2 M& a2 S# D& `! y
  6. }
复制代码

& p5 z5 n% F$ ?+ u: i3 |4 J) r
下面是原版的初始化函数:
  1. void LTC6804_initialize()
    ' r+ Y( Z- ^& l
  2. {
    ( _; t3 q! v$ r( ]  B+ o1 |
  3.   quikeval_SPI_connect();
    $ l2 s' ^6 X% o2 F3 s# L
  4.   spi_enable(SPI_CLOCK_DIV16); // This will set the Linduino to have a 1MHz Clock
    , N7 [- w( g7 _6 Z, Z7 W. a
  5.   set_adc(MD_NORMAL,DCP_DISABLED,CELL_CH_ALL,AUX_CH_ALL);$ h" T& S7 `: k$ I
  6. }
复制代码

3 S% G4 X9 k( p" d1 o# y
我把它根据自己的实际情况修改一下 :
  1. void LTC6804_initialize(void)
    " Z2 V, a$ |0 D6 q/ U
  2. {& C4 t/ O) Y$ M* a* P
  3.     Drive_LTC6804_Spi_Init();//SPI外设初始化
    0 p- @5 p/ N% h- U
  4.     init_cfg();        //配置LTC6804的寄存器+ H' S- s! _$ f  H( H
  5.     set_adc(MD_FILTERED,DCP_DISABLED,CELL_CH_ALL,AUX_CH_GPIO1);//设置转换方式等8 W0 }/ \, j6 J9 b
  6.     wakeup_sleep();//唤醒芯片
    3 @. `5 I6 h+ Q3 w2 J% `& T0 h9 ?1 B
  7.     LTC6804_wrcfg(TOTAL_IC,tx_cfg);//把上面的设置写入芯片- O# |$ A. c# Q$ r
  8.     if (LTC6804_rdcfg(TOTAL_IC,rx_cfg) == -1)  //检查一下到底有没有配置成功
    * m& V9 ]5 O  j% v! N! N- @' i& [
  9.     {* d  u- \/ P& ?$ h
  10.         printf("LTC6804_MODULAR INIT NG!\n\r");
    1 s1 q, v3 i4 s& T& h$ N8 j0 c
  11.     }& d1 B$ b9 L1 i, Y8 c4 Q! T. A7 j  {
  12.     else$ G* l/ {$ N# V9 S9 ]" c
  13.     {5 g8 a  F1 d" Y
  14.         printf("LTC6804_MODULAR INIT OK!\n\r");! Z3 p- \" {+ W$ o! e, g
  15.     }
    9 X, Q+ X- w  A3 T

  16. . l- L1 l; X( o& J2 I1 Q
  17. }
复制代码
  1. //手册第49页
    : n4 C7 ^1 r( p# _; `- [/ C8 D
  2. /* 寄存器               8         7          6         5         4         3         2        1        */
    0 V5 @4 j5 m/ Z. z8 n: }- @! w
  3. //CFGR0       RD/WR   GPIO5     GPIO4      GPIO3     GPIO2     GPIO1     REFON     SWTRD    ADCOPT
    7 e7 `' L# Y3 d4 M; M5 K% n
  4. //CFGR1       RD/WR   VUV[7]    VUV[6]     VUV[5]    VUV[4]    VUV[3]    VUV[2]    VUV[1]   VUV[0]
    ) K6 u8 M. n% C9 O4 u! u2 U* O7 C- V% j$ Q
  5. //CFGR2       RD/WR   VOV[3]    VOV[2]     VOV[1]    VOV[0]    VUV[11]   VUV[10]   VUV[9]   VUV[8]
    2 U1 f% A5 g6 o% {4 q
  6. //CFGR3       RD/WR   VOV[11]   VOV[10]    VOV[9]    VOV[8]    VOV[7]    VOV[6]    VOV[5]   VOV[4]
    ) w: d4 @- |* v! N
  7. //CFGR4       RD/WR   DCC8      DCC7       DCC6      DCC5      DCC4      DCC3      DCC2     DCC1- p" \4 h- I$ b
  8. //CFGR5       RD/WR   DCTO[3]   DCTO[2]    DCTO[1]   DCTO[0]   DCC12     DCC11     DCC10    DCC9
    ) ?0 w3 K  T7 y& T6 Z
  9. void init_cfg(void)
    / Q; J6 A  n( W7 D2 q1 {8 ^
  10. {
    ' G( J$ \" v6 y1 d5 }. V; R8 K/ ^
  11.     int i;
    * I6 u" X# O5 g; b

  12. 5 s4 Z" J3 F5 t/ _& m
  13.     for(i = 0; i<TOTAL_IC;i++)
    * ~4 n& H# u- W: z0 G& n4 \; V
  14.     {/ J+ S% D' H" F5 ?  {6 N1 Y
  15.         tx_cfg[i][0] = 0xFE ;   //GPIO引脚下拉电路关断(bit8~bit4) | 基准保持上电状态(bit3) | SWTEN处于逻辑1(软件定时器) | ADC模式选择为0
    ) k9 o% Z; U9 X" V4 [9 y! s. E* B
  16.         tx_cfg[i][1] = 0x00 ;   //不使用欠压比较功能* ]0 X7 N: [5 n
  17.         tx_cfg[i][2] = 0x00 ;   //不使用过压比较功能! b0 _. S4 g" y. D
  18.         tx_cfg[i][3] = 0x00 ;
    2 E( R# {: \1 j$ a% @. O
  19.         tx_cfg[i][4] = 0x00 ;   //不使用电池放电功能4 P+ r' N, x7 Q3 I! H/ n: q( O
  20.         tx_cfg[i][5] = 0x00 ;   //放电超时时间$ j! o) R' d# ?6 U4 \6 E
  21.     }
    5 Y& ?! b" F, {( b( n
  22. }
复制代码

  {/ |+ g: O  \1 P, U% H; E/ ]/ e' i1 B& B
这里只使用了最基本的电压采集,其他的功能都没有用。
上面的代码里面有一个宏 :TOTAL_IC。
这个宏是用来定义一共有几片LTC6804-1的,比如我这次使用了2片,那么它的值就是2.
上面的寄存器设置,可以参考手册:
1050425-20190403172123490-1539331691.png
比如需要追加一些别的功能,便可以根据手册的寄存器进行设置,比如设置报警,设置均衡,设置其他的功能。
以上初始化部分就完成了,或者说移植就完成了,然后便不必对代码文件进行任何修改就可以直接使用,接下来是采集部分:
我是把采集放在main中进行。
  1. /* 唤醒6804 */
    1 r$ H4 x1 t0 Q2 C" u
  2.         wakeup_sleep();  r3 L+ o) k: a7 |0 z6 o1 c
  3.         /* 启动电压采集 */
    6 d/ r6 e# G$ I/ p: D0 C. c4 C
  4.         LTC6804_adcv();/ W$ w9 l( m1 B4 L  v, ?4 s; n- z# G8 n
  5.         delay_ms(50);' o( j3 X& v& C3 ~  B. _
  6.         /* 读取电压 */; l) {. m. }  f3 L" h% G, U
  7.         res = LTC6804_rdcv(0, TOTAL_IC, vol_buff);
复制代码

( z' V1 ]3 E4 g+ O; S
以上便可以采集出电压了。
+ U) Y+ U, k9 _4 x! Y  W: N6 w
※如果发现几个级联起来的6804,有些片子可以运行正常通信,有些又不可以运行甚至无法通信,在排除硬件的原因以后,可以查看一下这个地方:wakeup_sleep(),试着把唤醒时间设置的长一些。

# I* L7 _2 c' i
最后:可以看出来,精度还是不错的~
; E+ k, u# w# W
收藏 评论0 发布时间:2022-1-18 22:27

举报

0个回答

所属标签

相似分享

官网相关资源

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