1. 程式人生 > >STM32操作24位AD晶片ADS1246

STM32操作24位AD晶片ADS1246

    ADS1246是TI公司大致在2009年中期推出的24位ADC,最高取樣速率可達2Ksps,其為單通道器件,與之相對應的還有ADS1247和ADS1248三通道器件,但特性並非完全一致。據TI資料介紹,ADS1246在ADS1247/ADS1248功能上做出簡化,保留了其部分特性。本次設計,需要用到24位單通道轉換器件,於是考慮用到ADS1246,主控制器用STM32L系列。以下為ADS1246的引腳圖:

    上圖顯示ADS1246引腳圖,其CS/SCLK/DIN/DUT為SPI通訊介面,RESET/START/DRDY為控制與狀態腳,AVDD/AVSS以及DVDD/DGND分別為模擬/數字電源供電端,REFP/REFN為基準源輸入腳,AINP/AINN為模擬訊號輸入端。其中,DRDY忙訊號指示功能可以附加到DOUT引腳上,這樣DRDY腳可以留空。在實際使用中發現,START腳做為ADC的啟動腳,還必須得接出來,因我還未找到有通過軟體能啟動ADS1246轉換的方法,但其DS中有提到START訊號和SLEEP/WAKEUP相類似的功能,暫未深研究。順便 提一下,TI關於ADS1246的文件是改自於另一顆ADC器件的文件,所以極其爛……

    ADS1246的SPI時序,這個是需要提一下的,一般來說,SPI協議在上升沿鎖存資料,下降沿更新資料,這是一般SPI協議的作法。但ADS1246需要在下降沿鎖存資料,上升沿更新資料,在設定SPI暫存器的時候需要注意一下,當我採用一般性設定的時候,發現通訊不正常。以下是STM32L的SPI設定,用的是SPI2。

[cpp] view plain copy  print?
  1. //SPI2配置
  2.     RCC->APB1ENR|=RCC_APB1ENR_SPI2EN;      
  3.     SPI2->CR1=SPI_CR1_MSTR|SPI_CR1_BR|SPI_CR1_SSM|SPI_CR1_SSI|SPI_CR1_CPHA;          //8位模式  
  4.     SPI2->CR1|=SPI_CR1_SPE;    

SPI2的驅動:


[cpp] view plain copy  print?
  1. //SPI2寫資料
  2. void SPI2_WriteBytes(uint8 *TxBuffer,uint16 TxLenth)  
  3. {  
  4.     uint8 i;  
  5.     while(TxLenth--){  
  6.         while( (SPI2->SR & SPI_SR_TXE) == 0 );  
  7.         SPI2->DR=*TxBuffer++;                  
  8.         while((SPI2->SR&SPI_SR_RXNE)==0);  
  9.         i=SPI2->DR;  
  10.     }  
  11.     i++;      
  12. }  

   上程式中i++的引入在於避免keil-MDK產生編譯警告。

[cpp] view plain copy  print?
  1. //SPI2讀資料
  2. void SPI2_ReadBytes(uint8 *RxBuffer,uint16 RxLenth)  
  3. {  
  4.     while(RxLenth--){             
  5.         while((SPI2->SR&SPI_SR_TXE)==0);  
  6.         SPI2->DR=*RxBuffer;  
  7.         while((SPI2->SR&SPI_SR_RXNE)==0);  
  8.         *RxBuffer++=SPI2->DR;          
  9.     }  
  10. }  

    以上驅動程式碼,能保證SPI在最後一個位元組完全傳送完成之後退出,如果沒有等待SPI_SR_RXNE,則僅僅只是把資料轉移到SPI移位暫存器,並未完全送出,不詳述。

    以下介紹我的驅動過程,在驅動ADS1246的時候,主要參考那個網方的58頁的極爛文件,上面沒有明確提到整個上電過程以及初始化過程,至於那個相當重要的自校準過程及操作方法也沒有提到,所以本人摸索了一整天時間,在此整理。

    ADS1246採用SPI通訊 ,其所有通訊引腳(SCK/DIN/DOUT)都在CS腳為低電平的時候有效,在CS為高時均為三態,當DRDY繫結到DOUT腳時,只有在CS為低時才能正確的指示忙狀態,若DRDY採用單獨的引腳,則不受CS控制。ADS1246的所有通訊過程被分為若干個命令組,有的需要帶引數,有的不需要帶引數,其實我也不明白它為什麼要搞那麼麻煩,感覺本來可以很簡單的處理,結果弄的很亂。以下為其命令分組:

    

    大致分為命令類(不帶引數),讀暫存器,寫暫存器三類,以下分別分其實現:

[cpp] view plain copy  print?
  1. //ADS1246命令碼列表
  2. #define ADC_CMD_WAKEUP      0x00            //退出睡眠模式
  3. #define ADC_CMD_SLEEP       0x02            //進入睡眠模式
  4. #define ADC_CMD_SYNC        0x04            //同步ADC轉換
  5. #define ADC_CMD_RESET       0x06            //晶片復位
  6. #define ADC_CMD_NOP     0xFF            //空操作
  7. #define ADC_CMD_RDATA       0x12            //單次讀取資料
  8. #define ADC_CMD_RDATAC      0x14            //連續讀取資料
  9. #define ADC_CMD_SDATAC      0x16            //停止連續讀取
  10. #define ADC_CMD_RREG        0x20            //讀暫存器
  11. #define ADC_CMD_WREG        0x40            //寫暫存器
  12. #define ADC_CMD_SYSOCAL     0x60            //系統偏移校準
  13. #define ADC_CMD_SYSGCAL     0x61            //系統增益校準
  14. #define ADC_CMD_SELFOCAL    0x62            //系統自校準
  15. #define ADC_CMD_RESTRICTED  0xF1            //
[cpp] view plain copy  print?
  1. /*--------------------------------------------------------- 
  2.  寫命令 
  3. ---------------------------------------------------------*/
  4. void ADS1246_WriteCmd(uint8 Cmd)  
  5. {  
  6.     ADC_SPI_CS_CLR  
  7.     ADC_WriteBytes(&Cmd,1);  
  8.     ADC_SPI_CS_SET  
  9. }  
  10. /*--------------------------------------------------------- 
  11.  讀暫存器 
  12. ---------------------------------------------------------*/
  13. void ADS1246_ReadReg(uint8 RegAddr,uint8 *Buffer,uint8 Length)  
  14. {  
  15.     uint8 Cmd[2];  
  16.     ADC_SPI_CS_CLR  
  17.     Cmd[0]=ADC_CMD_RREG|RegAddr;  
  18.     Cmd[1]=Length-1;  
  19.     ADC_WriteBytes(Cmd,2);  
  20.     ADC_ReadBytes(Buffer,Length);  
  21.     Cmd[0]=ADC_CMD_NOP;  
  22.     ADC_WriteBytes(Cmd,1);  
  23.     ADC_SPI_CS_SET  
  24. }  
  25. /*--------------------------------------------------------- 
  26.  寫暫存器 
  27. ---------------------------------------------------------*/
  28. void ADS1246_WriteReg(uint8 RegAddr,uint8 *Buffer,uint8 Length)  
  29. {  
  30.     uint8 Cmd[2];  
  31.     ADC_SPI_CS_CLR  
  32.         Cmd[0]=ADC_CMD_WREG|RegAddr;  
  33.     Cmd[1]=Length-1;  
  34.     ADC_WriteBytes(Cmd,2);  
  35.     ADC_WriteBytes(Buffer,Length);  
  36.     ADC_SPI_CS_SET  
  37. }  

    在寫讀存器時,一定要注意,根據其DS文件第32頁說明,其後發一個NOP命令可以強制DOUT引腳輸出高電平,這樣可以隨後判斷DOUT是否為低進而知道是否處於忙狀態,否則會得到一個脈衝。其實在任何的讀操作完成後,發一個位元組的NOP命令即可將DOUT強制輸出高電平。當DRDY繫結到DOUT的時候,這個是非常重要的。

    在弄清楚以上命令讀寫方法之後,需要實現其忙狀態判別,這個在很多晶片驅動時都會遇到,它直接提示了其內部的工作狀態,只有在不忙時才能繼續執行下一條指令。

[cpp] view plain copy  print?
  1. /*--------------------------------------------------------- 
  2.   忙狀態判斷,最長等待時間,200 X 10 ms=2S 
  3. ---------------------------------------------------------*/
  4. uint8 ADS1246_WaitBusy()  
  5. {  
  6.     uint16 i;  
  7.     ADC_SPI_CS_CLR  
  8.     i=0;  
  9.     while(ADC_RDY_DAT>0){  
  10.         Wrtos_TaskDelay(10);  
  11.         i++; if(i>200)return 1;  
  12.     }  
  13.     ADC_SPI_CS_SET  
  14.     return 0;  
  15. }  

    ADS1246的校準。在ADS1246內部,其前端是一個獨立的多路複用器,其每路輸入跟據功能的不同分別接到了相應的電平上,之後是一個能配置為1/2/4/8/16/32/64/128倍的可變增益放大器,之後是ADC轉換核心,最後是數字濾波器和資料介面部分。對於本器件,它通過MUX複用器的配置能進行PGA增益和系統偏移的校正。

       >. 對於系統偏移校正,指當AIN0-AIN1=0時,在指定的PGA倍率下,ADC的量化輸出,此時理論上應該輸出為0,但往往達不到0。
       >.對於PGA增益校正,指當AIN0-AIN1=VREFP-VREFN時,在PGA=1時,ADC的量化輸出,此時理論上應該輸出為滿量程,但有些設計也達不到。
       以上兩點,是ADS1246的定義,在DS的35頁下方有一個表格,類似以上表述,但這可能和一般性描述有所出入,特別是PGA校正,可能在這裡面它自己還進行了一些未表述出來的工作。以下是其校正實現:   

[cpp] view plain copy  print?
  1. /*--------------------------------------------------------- 
  2.  執行校準---系統校準->偏移校準->增益校準 
  3. ---------------------------------------------------------*/
  4. uint8 ADS1246_Calibrate(uint8 Gain)  
  5. {  
  6.     uint8 R=0,Cmd;  
  7. 相關推薦

    STM32操作24AD晶片ADS1246

        ADS1246是TI公司大致在2009年中期推出的24位ADC,最高取樣速率可達2Ksps,其為單通道器件,與之相對應的還有ADS1247和ADS1248三通道器件,但特性並非完全一致。據TI資料介紹,ADS1246在ADS1247/ADS1248功能上做出簡

    利用電錶SOC晶片RN7211低成本實現三路高精度24AD採集(帶PGA功能)

          RN7211為一款ARM Cortex-M0核心的電錶SOC晶片,整合有3通道用於測量計量的高精度差分輸入Σ-ΔADC,更新速率7.2KHz,具有128KByte FLASH、16KByte SRAM與32KByteEEPROM,2個DMA,具備硬體自動溫補的R

    STM32操作加密晶片原始碼

    STM32操作SMEC98SP加密晶片的事例程式碼,如果需要完整程式碼(包括加密晶片程式碼),請到中巨偉業 http://www.sinormous.com/download.html下載 #include “stm32f10x.h” #include “stdio.h” #includ

    STM32-24AD7799驅動之手冊程式碼詳解,支援模擬SPI和硬體SPI

    1.AD7799介紹 AD7799結構圖如下所示:   其中REFIN參考電壓建議為2.5V, REFIN電壓低於0.1V時,則差分輸入ad值就無法檢測了,如下圖所示:   注意: 如果REG_CONFIG的REF_DET開啟的話,那麼輸入AD值電壓低於0.5V時,則差分輸入a

    MATLAB讀取黑白圖像顯示卻是黑色,24深轉8深黑白圖像解決方法

    com 問題 欺騙 alt width 圖. 如果 技術分享 src 1、24位深轉8位深: ps將24位深原圖.png保存為GIF圖256即為8位,再將8位gif圖轉為需要的.png,即轉為8位深png圖。 2、MATLAB讀取黑白圖像顯示幾乎全為黑色: 這是最近處理圖像

    MD5值轉換(Hex 32 <-> base64 24)

    tom 長度 值轉換 u+ 結果 adc 互轉 markdown nta 關於MD5值的原理本文不在介紹,本文主要介紹MD5值的兩種編碼的相互轉換(32位和BASE64編碼的24位),實際應用過程中經常會涉及到兩種編碼的相互轉換。快熟使用工具tomeko.net。 C#

    ES8388自由聆聽24,8千赫到96千赫取樣頻率

    ES8388高效能、低功耗、低成本的音訊編解碼器。它由兩路ADC,2通道DAC,話筒放大器、耳機放大器、數字音效、模擬混合和增益功能。 該裝置採用先進的多位Δ∑調製技術實現數字與模擬之間的資料轉換。多位元Δ∑調製器使器件對時鐘抖動和低帶外噪聲的靈敏度低。它應用於:MID,MP3, MP4, PM

    24bmp影象的資料讀取&儲存

    24位bmp檔案的讀取&儲存 我採用的方法是將影象檔案讀取,儲存到一維陣列中,以便後期的操作。    void checkFileExist(FILE * fpbmp) {     //開啟圖片檔案 按照二進位制讀取  

    stm32驅動16ADC(ADS1113)

    相關原理圖: 其中VDD:     引腳定義: /* * I2C1 * @ADC_SDA PB7 * @ADC_SCL PB6 * @CU_BE_EN PC8 (1 : ON , 0: OFF) * @CU_BE_SELE

    Python將8的圖片轉為24的圖片

    用的pytorch來訓練deeplabv3+ 在做deeplabv3+的過程中,我的訓練圖片是8位的,如下圖: 8位的: 24位的: 這樣雖然在訓練過程中能夠正常訓練。但是在評估過程中會出錯,所以決定將訓練圖片轉成24點陣圖,重新訓練。最後結果也表明了,只要

    24bmp影象旋轉

    當前僅實現了bmp影象的90°旋轉 以下為旋轉的關鍵程式碼: void rotate_90_shun(char *data_original, FILE *bfOut1, int l_width1, int l_width2, int original_height, i

    STM32 Option Bytes 重置為出廠設定

    TM32 Option Bytes位 重置為出廠設定 JLINK 按照說明,在IAR安裝目錄下找到指定的執行程式JLinkSTM32.exe(D:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin

    BMP影象的處理(24轉16

    // BMP_24-16.cpp : 定義控制檯應用程式的入口點。 // ///24位bmp影象轉16位bmp影象 #include "stdafx.h" #include "iostream" #include "fstream" using namespace st

    c語言實現24彩色影象二值化

    // huiduhua.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include<stdio.h> #include<windows.h> int _tmain(int argc, _TCHAR*

    c 語言實現24bmp圖片載入,讀寫,放大縮小 .

    發現好多人網上查詢c 語言版本的bmp影象讀取,儲存,放大,縮小程式,很難找到完整的。 現在將自己寫的貼出來 供大家學習參考交流。轉載請標明出處,尊重作者勞動成果。 /**********************************************************            

    讀取24 BMP 影象並生成 JPG 縮圖(一)

                //對24位BMP進行解析     if(nbitcount==24){         int npad=(nsizeimage/nheight)-nwidth*3;         int ndata[]=new int[nheight*nwidth];         byte

    純java操作登錄檔,支援指定操作32的還是64的登錄檔

     java 寫出來的允許從一個 64位 jvm 訪問32位機器登錄檔的程式碼,反過來也可以。 這個是我在網上找到最厲害的一種方式,完全不用dll,並且支援指定作業系統位數,不論你 jdk是多少位的。 /** * Pure Java Windows Registry

    影象處理之(24)BMP旋轉以及映象演算法

      在影象處理,圖形學、計算機視覺中,我們經常能夠見到bmp這種格式的圖片;那麼對於我們來說想要處理這種圖片,首先就應當瞭解這種圖片,知己知彼方能百戰不殆。   那麼首先我們來了解一下bmp格式的圖片: 一、瞭解BMP (一)概述   BMP(全稱B

    Java實現24真彩轉換為8灰度圖片

             Windows下的點陣圖檔案即我們通常所熟悉的BMP圖片,其儲存結構的格式可以在WINGDI.h檔案中找到定義。BMP檔案大體上分為四個部分: 1.      點陣圖檔案頭(BITMAPFILEHEADER) 2.      點陣圖資訊頭(BITMAPIN

    MFC-Toolbar(24真彩色)

    先準備一個24位的真彩色工具欄BMP圖片 如圖所示: 然後新增到Bitmap資源裡 接著上一篇16位工具欄的程式碼,進行稍微修改即可 //建立Toolbar m_toolbar.CreateEx(this, TBSTYLE_FLAT,