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

【经验分享】基于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线通信,不过我没有用)
! ]. O1 C* E6 ~5 A, @4 s4 K* D
8 z* K! W& R8 `
  下载下来的代码是C++文件,不能直接在STM32上使用,需要进行一些修改。
  首先修改后缀名,改成C文件,然后打开LTC6804.c文件。

; j# a6 i: q# a8 V2 }) J, K- ^4 I
第一步进行驱动的移植:
  1. void spi_write_array(uint8_t len, // Option: Number of bytes to be written on the SPI port
    6 g# q3 [9 Q/ |$ c0 R1 D3 J
  2.                      uint8_t data[] //Array of bytes to be written on the SPI port
    7 J' i! F' A* L* ^' o
  3.                      ). p3 z5 z. ~8 ~8 s
  4. {) f/ }3 w* x5 v' J7 N; ^
  5.     uint8_t i;' L9 D+ b& D# {; ~9 C
  6. $ q& P# K) V5 f6 t1 _
  7.     for(i = 0; i < len; i++)8 M6 A8 [  K, J9 m
  8.     {" J; L. E5 h1 H% p2 R/ p
  9.         SPI2_Send_byte((int8_t)data[i]);! \% W. Y% G4 S9 z, A, C' ]
  10.     }; R* ]' z" }! A) Z( @9 g
  11. }
复制代码
  1. void spi_write_read(uint8_t tx_Data[],//array of data to be written on SPI port
    * w0 r+ ?! E& V
  2.                     uint8_t tx_len, //length of the tx data arry: y8 B8 s$ ?: D0 g, c( u. I
  3.                     uint8_t *rx_data,//Input: array that will store the data read by the SPI port& I8 X1 U8 [+ z% M4 c
  4.                     uint8_t rx_len //Option: number of bytes to be read from the SPI port/ W/ d4 Y3 Y- s$ ~. W+ x
  5.                     )* d1 p6 ~! E( a
  6. {
    ( Y6 Z9 o: t; o) h% L
  7.     uint8_t i;
    : F$ _) X% b( U8 {
  8. , J2 i( E* v: O' w; K
  9.     for(i = 0; i < tx_len; i++)( v# G: E+ F  r* j$ a
  10.     {$ k, ?7 X4 `8 m* I+ S( Z5 I' P
  11.         SPI2_Send_byte(tx_Data[i]);) E' [& y- I2 z/ d/ I0 r
  12.     }3 m4 y) t. y1 U- X+ P+ v
  13. : w; h0 O9 ^, a6 ^2 m* E5 c
  14.     for(i = 0; i < rx_len; i++)3 E5 N4 G4 v7 }5 \, f4 X
  15.     {
    ( D3 r7 A4 Q5 P! `8 X& d
  16.         rx_data[i] = (uint8_t)SPI2_Receive_byte();+ q1 o: M2 [* G3 g9 `5 q$ t$ p0 r
  17.     }9 t; p7 |3 q5 D  F, I% I- E
  18. 7 m0 X4 v3 J0 D; Q' ~( W' \
  19. }
复制代码

- a  @( _/ V& J4 I+ \
只需要把自己的SPI驱动替换上去就可以了。
3 |, n6 Q1 Z- [
  1. void wakeup_idle()
    5 t$ o: G0 @. ?; p4 ^
  2. {, z, b9 H* r2 m
  3.   output_low(LTC6804_CS);7 F9 w0 P+ x* r: E' ?
  4.   delayMicroseconds(2); //Guarantees the isoSPI will be in ready mode
    0 X/ H1 D/ }( P/ O+ N
  5.   output_high(LTC6804_CS);
    - d) ]0 s6 \! b
  6. }
复制代码

3 G+ Z; Z7 J/ b$ [) x% f
自己把这个函数中间的部分实现,或者替换成自己的函数:
  1. void wakeup_idle(void)
    & ]5 ?5 {2 A& V+ B! q8 i
  2. {9 p5 N4 k! N1 E5 K( ^
  3.   output_low(LTC6804_CS);+ J% o. ^  Y. p& z5 P
  4.   delay_ms(4); //Guarantees the isoSPI will be in ready mode) G  e6 P3 S) }# y* B: D) N6 S" T8 f
  5.   output_high(LTC6804_CS);
    ( _7 L& g! n, A( O: H6 I/ M  a. ^: r
  6. }
复制代码

8 r: F' D6 h7 s  J
下面是原版的初始化函数:
  1. void LTC6804_initialize()! e: c# \& Y/ s1 Q9 H
  2. {
    ; a$ P3 ^9 m  Q, h, @% h5 c9 f$ j
  3.   quikeval_SPI_connect();
    9 q$ H: p. c( w& z
  4.   spi_enable(SPI_CLOCK_DIV16); // This will set the Linduino to have a 1MHz Clock
    % }; Y3 p4 c- \
  5.   set_adc(MD_NORMAL,DCP_DISABLED,CELL_CH_ALL,AUX_CH_ALL);
    , r9 d! h5 P4 c9 ?. t: J1 x
  6. }
复制代码
' m- Z) @5 v$ o5 Q) M: q
我把它根据自己的实际情况修改一下 :
  1. void LTC6804_initialize(void)" ^9 q" t4 u0 _3 I! b! ^
  2. {
    % E: Z/ G1 o  v' z" w8 C7 O0 H8 W
  3.     Drive_LTC6804_Spi_Init();//SPI外设初始化$ _" O( s" O# y- F* E
  4.     init_cfg();        //配置LTC6804的寄存器7 ]3 ]  t- _1 T: X3 ~
  5.     set_adc(MD_FILTERED,DCP_DISABLED,CELL_CH_ALL,AUX_CH_GPIO1);//设置转换方式等
    8 u* z; I0 p4 T7 `4 u/ K
  6.     wakeup_sleep();//唤醒芯片; L( f+ }: R, @" j7 X& o* Y+ S9 q$ H+ L
  7.     LTC6804_wrcfg(TOTAL_IC,tx_cfg);//把上面的设置写入芯片& R, L$ [; T) N+ H
  8.     if (LTC6804_rdcfg(TOTAL_IC,rx_cfg) == -1)  //检查一下到底有没有配置成功
    9 V, j8 Z( p: ^; f* ], J
  9.     {
    : }" r) d: A2 Y; I9 k  s  X; F( S! P
  10.         printf("LTC6804_MODULAR INIT NG!\n\r");
    & |& Q  C& j. k
  11.     }9 [0 h& V5 z! A, j/ t$ u
  12.     else
    2 C, _- U4 n. E! d$ _4 z7 W
  13.     {
    ; ?! o  n9 A6 v( k. b7 M; r
  14.         printf("LTC6804_MODULAR INIT OK!\n\r");1 r" F/ ?# o# f  J
  15.     }$ V* N4 V, ~4 }0 k/ x( O
  16. 0 b9 T2 p5 v' p
  17. }
复制代码
  1. //手册第49页1 l' t4 a# g8 A
  2. /* 寄存器               8         7          6         5         4         3         2        1        */
    . }2 z' \8 k7 B' [* y' ?
  3. //CFGR0       RD/WR   GPIO5     GPIO4      GPIO3     GPIO2     GPIO1     REFON     SWTRD    ADCOPT. i7 k) w* M' G$ d" u2 K
  4. //CFGR1       RD/WR   VUV[7]    VUV[6]     VUV[5]    VUV[4]    VUV[3]    VUV[2]    VUV[1]   VUV[0]+ P  I4 w5 P! f  C/ X
  5. //CFGR2       RD/WR   VOV[3]    VOV[2]     VOV[1]    VOV[0]    VUV[11]   VUV[10]   VUV[9]   VUV[8], E  X' {. c+ L' p& W8 A8 a
  6. //CFGR3       RD/WR   VOV[11]   VOV[10]    VOV[9]    VOV[8]    VOV[7]    VOV[6]    VOV[5]   VOV[4]
    * X' F/ E  Z6 C4 e* w0 v& q$ m' I( K
  7. //CFGR4       RD/WR   DCC8      DCC7       DCC6      DCC5      DCC4      DCC3      DCC2     DCC1( y2 ~- e) K: t" {, M0 n4 {
  8. //CFGR5       RD/WR   DCTO[3]   DCTO[2]    DCTO[1]   DCTO[0]   DCC12     DCC11     DCC10    DCC9
    + ?$ S6 `3 `  ?- A  c
  9. void init_cfg(void)3 Q" D$ b6 i2 q- @% d. F; w
  10. {
    7 j& X/ c0 g6 F
  11.     int i;  q4 l. Q4 X. Z8 i0 I5 U" s

  12. ( U3 R# _) y3 Y3 i, X8 [( T
  13.     for(i = 0; i<TOTAL_IC;i++)
    % y8 d/ o4 N# S+ O3 {( F
  14.     {$ X" s7 a$ \. c! T
  15.         tx_cfg[i][0] = 0xFE ;   //GPIO引脚下拉电路关断(bit8~bit4) | 基准保持上电状态(bit3) | SWTEN处于逻辑1(软件定时器) | ADC模式选择为0
    $ N- r% n. d( B) [0 C- {
  16.         tx_cfg[i][1] = 0x00 ;   //不使用欠压比较功能5 o6 V) Y& J* R- Z
  17.         tx_cfg[i][2] = 0x00 ;   //不使用过压比较功能
    1 k/ I: B% _& G1 y1 M  O8 N
  18.         tx_cfg[i][3] = 0x00 ;! t( X9 F% }! T, L
  19.         tx_cfg[i][4] = 0x00 ;   //不使用电池放电功能
    ) ]" |/ E1 R- K; o; K) O* F
  20.         tx_cfg[i][5] = 0x00 ;   //放电超时时间6 z' j% S6 Y6 J! Q& H  _
  21.     }9 [, V. w9 i) G  _: L7 }8 c
  22. }
复制代码

6 }! Z$ h" Z6 u/ m' J1 L8 ]  U5 l7 b" w: O% W2 g; R* {. D
这里只使用了最基本的电压采集,其他的功能都没有用。
上面的代码里面有一个宏 :TOTAL_IC。
这个宏是用来定义一共有几片LTC6804-1的,比如我这次使用了2片,那么它的值就是2.
上面的寄存器设置,可以参考手册:
1050425-20190403172123490-1539331691.png
比如需要追加一些别的功能,便可以根据手册的寄存器进行设置,比如设置报警,设置均衡,设置其他的功能。
以上初始化部分就完成了,或者说移植就完成了,然后便不必对代码文件进行任何修改就可以直接使用,接下来是采集部分:
我是把采集放在main中进行。
  1. /* 唤醒6804 */
    " r3 g( D+ h" }! f& J  ~0 c2 R
  2.         wakeup_sleep();& ~. ], y! P8 P) x
  3.         /* 启动电压采集 */9 ?) A& Z9 x: J4 N, [0 S; J+ E% l
  4.         LTC6804_adcv();! l4 W1 ]: Y% |9 B
  5.         delay_ms(50);
    ; `4 e6 c8 Y" q- C% X
  6.         /* 读取电压 */# S8 [+ {  c8 {) l
  7.         res = LTC6804_rdcv(0, TOTAL_IC, vol_buff);
复制代码
& B8 ^3 B2 q; _* b# e* }( e. T# I/ [
以上便可以采集出电压了。

" z6 c4 j4 H# E+ V4 O" S- N
※如果发现几个级联起来的6804,有些片子可以运行正常通信,有些又不可以运行甚至无法通信,在排除硬件的原因以后,可以查看一下这个地方:wakeup_sleep(),试着把唤醒时间设置的长一些。
1 W+ ~: T4 D  }  I2 R
最后:可以看出来,精度还是不错的~
. @. m( ?* S# e* z
收藏 评论0 发布时间:2022-1-18 22:27

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版