基於STM32的LTC6804驅動代碼解析


  在上次項目中用到了LTC6804這塊片子,初次使用它的采集精度確實令我驚訝到了,設備用於監測2V的鉛酸電池組,硬件上幾乎沒有加任何濾波,直接讀取數據就能達到3mv以下的精度,片子真的很好用。

  下面總結一下自己的使用心得。

 

  ------------------------------------------------------------------------------------------------

  LTC6804是一款專門用來做多節電池電池組的監測芯片,最高可監測12節電池,官方誤差是低於1.2mv,12 個通道的最快采樣速度可以達到290us。

  芯片分為兩種型號,6804-1和6804-2,區別在於,6804-1采用級聯的形式(級聯控制),6804-2采用並聯形式(分開控制)。

  除開硬件連接之外,這兩種型號的操作都是大同小異,基本可以視為一樣,本文以6804-1為例進行講解。

  

  原理圖和手冊中的推薦一樣,就不貼出來了,MCU與芯片的通信方式采用四線SPI,這種通信方式很常見,各種MCU的驅動也好找。(看了數據手冊,芯片似乎還支持IIC和2線通信,不過我沒有用)

 

  驅動代碼可以從官網下載:https://www.analog.com/cn/products/ltc6804-1.html

  下載下來的代碼是C++文件,不能直接在STM32上使用,需要進行一些修改。

  首先修改后綴名,改成C文件,然后打開LTC6804.c文件。

  

第一步進行驅動的移植:

void spi_write_array(uint8_t len, // Option: Number of bytes to be written on the SPI port
                     uint8_t data[] //Array of bytes to be written on the SPI port
                     )
{
    uint8_t i;

    for(i = 0; i < len; i++)
    {
        SPI2_Send_byte((int8_t)data[i]);
    }
}

 

  

void spi_write_read(uint8_t tx_Data[],//array of data to be written on SPI port
                    uint8_t tx_len, //length of the tx data arry
                    uint8_t *rx_data,//Input: array that will store the data read by the SPI port
                    uint8_t rx_len //Option: number of bytes to be read from the SPI port
                    )
{
    uint8_t i;

    for(i = 0; i < tx_len; i++)
    {
        SPI2_Send_byte(tx_Data[i]);
    }

    for(i = 0; i < rx_len; i++)
    {
        rx_data[i] = (uint8_t)SPI2_Receive_byte();
    }

}

 

只需要把自己的SPI驅動替換上去就可以了。

 

void wakeup_idle()
{
  output_low(LTC6804_CS);
  delayMicroseconds(2); //Guarantees the isoSPI will be in ready mode
  output_high(LTC6804_CS);
}

 

自己把這個函數中間的部分實現,或者替換成自己的函數:

void wakeup_idle(void)
{
  output_low(LTC6804_CS);
  delay_ms(4); //Guarantees the isoSPI will be in ready mode
  output_high(LTC6804_CS);
}

 

 

下面是原版的初始化函數:

void LTC6804_initialize()
{
  quikeval_SPI_connect();
  spi_enable(SPI_CLOCK_DIV16); // This will set the Linduino to have a 1MHz Clock
  set_adc(MD_NORMAL,DCP_DISABLED,CELL_CH_ALL,AUX_CH_ALL);
}

 

我把它根據自己的實際情況修改一下 :

void LTC6804_initialize(void)
{
    Drive_LTC6804_Spi_Init();//SPI外設初始化
    init_cfg();        //配置LTC6804的寄存器
    set_adc(MD_FILTERED,DCP_DISABLED,CELL_CH_ALL,AUX_CH_GPIO1);//設置轉換方式等
    wakeup_sleep();//喚醒芯片
    LTC6804_wrcfg(TOTAL_IC,tx_cfg);//把上面的設置寫入芯片
    if (LTC6804_rdcfg(TOTAL_IC,rx_cfg) == -1)  //檢查一下到底有沒有配置成功
    {
        printf("LTC6804_MODULAR INIT NG!\n\r");
    }
    else
    {
        printf("LTC6804_MODULAR INIT OK!\n\r");
    }

}

 

//手冊第49頁
/* 寄存器               8         7          6         5         4         3         2        1        */
//CFGR0       RD/WR   GPIO5     GPIO4      GPIO3     GPIO2     GPIO1     REFON     SWTRD    ADCOPT
//CFGR1       RD/WR   VUV[7]    VUV[6]     VUV[5]    VUV[4]    VUV[3]    VUV[2]    VUV[1]   VUV[0]
//CFGR2       RD/WR   VOV[3]    VOV[2]     VOV[1]    VOV[0]    VUV[11]   VUV[10]   VUV[9]   VUV[8]
//CFGR3       RD/WR   VOV[11]   VOV[10]    VOV[9]    VOV[8]    VOV[7]    VOV[6]    VOV[5]   VOV[4]
//CFGR4       RD/WR   DCC8      DCC7       DCC6      DCC5      DCC4      DCC3      DCC2     DCC1
//CFGR5       RD/WR   DCTO[3]   DCTO[2]    DCTO[1]   DCTO[0]   DCC12     DCC11     DCC10    DCC9
void init_cfg(void)
{
    int i;

    for(i = 0; i<TOTAL_IC;i++)
    {
        tx_cfg[i][0] = 0xFE ;   //GPIO引腳下拉電路關斷(bit8~bit4) | 基准保持上電狀態(bit3) | SWTEN處於邏輯1(軟件定時器) | ADC模式選擇為0
        tx_cfg[i][1] = 0x00 ;   //不使用欠壓比較功能
        tx_cfg[i][2] = 0x00 ;   //不使用過壓比較功能
        tx_cfg[i][3] = 0x00 ;
        tx_cfg[i][4] = 0x00 ;   //不使用電池放電功能
        tx_cfg[i][5] = 0x00 ;   //放電超時時間
    }
}

 

這里只使用了最基本的電壓采集,其他的功能都沒有用。

 上面的代碼里面有一個宏 :TOTAL_IC。

這個宏是用來定義一共有幾片LTC6804-1的,比如我這次使用了2片,那么它的值就是2.

上面的寄存器設置,可以參考手冊:

比如需要追加一些別的功能,便可以根據手冊的寄存器進行設置,比如設置報警,設置均衡,設置其他的功能。

 以上初始化部分就完成了,或者說移植就完成了,然后便不必對代碼文件進行任何修改就可以直接使用,接下來是采集部分:

我是把采集放在main中進行。

        /* 喚醒6804 */
        wakeup_sleep();
        /* 啟動電壓采集 */
        LTC6804_adcv();
        delay_ms(50);
        /* 讀取電壓 */
        res = LTC6804_rdcv(0, TOTAL_IC, vol_buff);

 

 以上便可以采集出電壓了。

 

※如果發現幾個級聯起來的6804,有些片子可以運行正常通信,有些又不可以運行甚至無法通信,在排除硬件的原因以后,可以查看一下這個地方:wakeup_sleep(),試着把喚醒時間設置的長一些。

 

最后:可以看出來,精度還是不錯的~

 

 本文結束!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM