基於STM32的LTC6804驅動代碼解析

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

  下面總結一下本身的使用心得。函數

 

  ------------------------------------------------------------------------------------------------ui

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

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

  除開硬件鏈接以外,這兩種型號的操做都是大同小異,基本能夠視爲同樣,本文以6804-1爲例進行講解。code

  

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

 

  驅動代碼能夠從官網下載:https://www.analog.com/cn/products/ltc6804-1.htmlblog

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

  首先修改後綴名,改爲C文件,而後打開LTC6804.c文件。io

  

第一步進行驅動的移植:

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(),試着把喚醒時間設置的長一些。

 

最後:能夠看出來,精度仍是不錯的~

 

 本文結束!

相關文章
相關標籤/搜索