(文章目錄)
一、ADS1118模塊簡介
ADS111x是一款精密、低功耗、16位DELTA-SIGMA(∆-Σ)模數轉換器(ADC),提供測量採用超小型VSSOP-10封裝的傳感器最常見信號所需的所有功能。ADS111x集成了可編程增益放大器(PGA)、電壓基準、振盪器;其中ADS1115帶數字比較器輸出;ADS1118帶高精度温度傳感器。這些功能以及2V至5.5V的寬電源電壓範圍,使得ADS111x 非常適合功率受限和空間受限的傳感器測量應用。 ADS111x數據轉換速率最高可達每秒860次採樣(SPS)。PGA的 輸入範圍為士256MV至±6.144V,能夠以高分辨率測量大信號和小信號。該器件通過輸入多路複用器(MUX)測量雙路差分輸入或四路單端輸入。ADS1118高精度温度傳感器用於系統級温度監控或對熱電偶進行冷結點補償。
特性
- 模塊供電:2-5.5V
- 通訊接口:SPI串行通訊
- 靜態功耗:<1mA(僅供參考)
- 輸入通道數:4通道單端或2通道差分,分時採樣
- PGA輸入範圍:±256mV至±6.144V,軟件切換量程
- 分辨率:16位
- 最大采樣率:860 SPS
- 模塊特點:內部集成高精度温度傳感器
模塊應用
- 温度測量:熱電偶測量、冷結點補償、熱敏電阻測量
- 便攜式儀表
- 工廠自動化和過程控制
二、模塊引腳説明
| CS | CS片選 |
|---|---|
| SCLK | 串行時鐘輸入 |
| DIN | 串行數據輸入 |
| DOUT | 數據輸出與數據就緒 |
三、功能框圖與讀寫時序分析
ADS1118 的一次“數據傳輸週期”有兩種常見形式:32-bit 週期(同時寫配置並回讀配置)和 16-bit 週期(短讀,僅讀轉換結果)。
32-bit 週期:在一個 32 位數據傳輸週期中,數據由四個字節組成:兩個字節用於轉換結果,另外兩個字節用於讀取配置寄存器。設備始終先讀取最高有效位 (MSB)。如圖 40 所示,在一個傳輸週期內,將相同的配置寄存器設置寫入兩次。如果方便,可以在傳輸週期的前半段寫入一次配置寄存器設置,然後在週期的後半段將 DIN 引腳保持低電平(如圖 41 所示)或高電平。如果不需要更新配置寄存器,則在整個傳輸週期內將 DIN 引腳保持低電平或高電平。在 32 位傳輸週期的前兩個字節中寫入的配置寄存器設置,將在同一週期的最後兩個字節中讀取。
16-bit 週期:如果不需要讀取配置寄存器數據,ADS1118 轉換數據也可以通過一個較短的 16 位數據傳輸週期輸出,如圖 42 所示。因此,在第 16 個 SCLK 週期之後,必須將 CS 置高。將 CS 置高會復位 SPI 接口。下次將 CS 置低時,數據傳輸開始,在第一個 SCLK 上升沿讀取當前緩存的轉換結果。如果在數據讀取開始時 DOUT/DRDY 為低,則轉換緩衝區已更新為新結果。否則,如果 DOUT/DRDY 為高,則讀取上一個數據傳輸週期的結果。
四、ADS1118的寄存器説明
ADS1118 有兩個可通過 SPI 接口訪問的寄存器。轉換寄存器存儲上次轉換的結果。配置寄存器允許用户更改 ADS1118 的工作模式並查詢器件狀態。 轉換寄存器:16 位轉換寄存器以二進制補碼格式存儲上次轉換的結果。上電後,轉換寄存器被清零,並保持為 0,直到第一次轉換完成。 配置寄存器:16 位配置寄存器可用於控制 ADS1118 的工作模式、輸入選擇、數據速率、滿量程範圍和温度傳感器模式。
| 位 | 名字 | 讀寫類型 | 初始值 | 描述 |
|---|---|---|---|---|
| 15 | SS | 讀/寫 | 0h | 單次轉換啓動:此位用於啓動單次轉換。SS 只能在斷電狀態下寫入,轉換進行時無效。寫入時:0 = 無影響;1 = 啓動單次轉換(斷電狀態下);始終讀取為 0(默認值)。 |
| 14~12 | MUX | 讀/寫 | 0h | 輸入多路複用器配置,這些位用於配置輸入多路複用器。 |
| 11~9 | PGA | 讀/寫 | 2h | 可編程增益放大器配置,這些位用於配置可編程增益放大器。 |
| 8 | MODE | 讀/寫 | 1h | 設備工作模式:此位控制 ADS1118 的工作模式。0 = 連續轉換模式 1 = 斷電和單次轉換模式(默認)。 |
| 7~5 | DR | 讀/寫 | 4h | 數據速率:這些位控制數據速率設置。000 = 8 SPS;001 = 16 SPS;010 = 32 SPS;011 = 64 SPS;100 = 128 SPS(默認);101 = 250 SPS;110 = 475 SPS;111 = 860 SPS |
| 4 | TS_MODE | 讀/寫 | 0h | 温度傳感器模式:此位配置 ADC 以轉換温度信號或輸入信號。0 = ADC 模式(默認);1 = 温度傳感器模式 |
| 3 | PULL_UP_EN | 讀/寫 | 1h | 上拉使能位:僅當 CS 為高電平時,此位才啓用 DOUT/DRDY 引腳上的弱上拉電阻。啓用後,一個 400 kΩ 的內部電阻將總線連接到電源。禁用時,DOUT/DRDY 引腳懸空。0 = DOUT/DRDY 引腳上的上拉電阻禁用;1 = DOUT/DRDY 引腳上的上拉電阻啓用(默認值)。 |
| 2~1 | NOP | 讀/寫 | 1h | NOP[1:0] 位控制是否將數據寫入配置寄存器。要將數據寫入配置寄存器,NOP[1:0] 位必須為“01”。任何其他值都會導致 NOP 命令。在 SCLK 脈衝期間,DIN 可以保持高電平或低電平,而不會將數據寫入配置寄存器。01=數據有效,其他為數據無效。 |
| 保留 | 讀 | 1h | 保留位。向此位寫入 0 或 1 均無效。始終讀取為 1。 |
五、數據輸出格式與電壓換算
ADS1118 以二進制補碼格式提供 16 位數據。正滿量程輸入產生 7FFFh 的輸出碼,負滿量程輸入產生 8000h 的輸出碼。對於超過滿量程的信號,輸出將截斷至這些碼值。表 5 總結了不同輸入信號的理想輸出碼。圖 39 顯示了碼轉換與輸入電壓的關係。 採集數據與電壓轉換 ADS1118 輸出 16-bit 有符號整數,範圍 -32768 .. +32767。MSB 為符號位(負數以二補表示),ADC 的物理量程由 PGA/FSR 設置決定(例如 ±6.144V、±2.048V 等),每個 LSB 對應的電壓 = FSR / 32768(注意分母是 32768 = 2^15)。 即電壓 = 16-bit有符號整數 x LSB,LSB大小由設置的量程決定。量程和比例係數如下:
六、STM32F103驅動ADS1118採集信號
準備工作
STM32F103C8T6最小系統板,ADS1118 ADC模塊,OLED顯示屏。
引腳接線
| STM32F103C8T6 | ADS1118 |
|---|---|
| PA0 | SCLK |
| PA1 | DIN |
| PA2 | CS |
| PA3 | DOUT |
| PB8 | SCL |
| PB9 | SDA |
代碼示例
ads1118.c
#include "stm32f10x.h"
#include "ads1118.h"
#include "delay.h"
void ADS1118_Init(void) //ADS1118初始化
{
uint16_t config = ADS1118_CONFIG_SS_START_OFF | //
ADS1118_CONFIG_MODE_CONTIN | //連續轉換模式
ADS1118_CONFIG_DR_128SPS | // 轉換 速率 SPS
ADS1118_CONFIG_TS_MODE_ADC | // 讀取ADC,而不是温度
ADS1118_CONFIG_PULL_UP_ON | //上拉電阻啓用
ADS1118_CONFIG_NOP_VALID | // this is valid data (default)
ADS1118_CONFIG_PGA_6_144V | // FSR is ±6.144 V
ADS1118_CONFIG_MUX_SINGLE_0| //AINP is AIN0 and AINN is GND//單端
ADS1118_CONFIG_RESV; // reserved bits must be set to 1
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能端口時鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
CS_H;
MISO_H;
SCLK_L;
MOSI_L;
Write_ADS1118(config,1);//設置ads1118
}
/*******************************************************************************
//函數名稱:ADS_SEL_Read()
//函數功能:讀取各路電壓,通過兩個switch選擇讀取不同的通道
//輸 入:road:增益放大器兩端的電壓選擇,並選擇測幾路電壓
// Ref: 選擇參考電壓,有6種選擇
// mode: 是否更新讀回數據 0讀回 1不讀回
//輸 出:dat:16位ad轉換數據
//備 注:這一次讀出的轉換數據是上一次的轉換數據,不要混淆.這裏選擇的是單次
轉換電壓值,當然,也可以選擇多次轉換,通過寄存器的第8位可以設置
*******************************************************************************/
int16_t ADS_SEL_Read(uint8_t road,uint8_t Ref,uint8_t mode) //測幾路電壓
{
int dat = 0;
uint16_t config = ADS1118_CONFIG_SS_START_OFF | //
ADS1118_CONFIG_MODE_CONTIN | //連續轉換模式
ADS1118_CONFIG_DR_128SPS | // 轉換 速率 SPS
ADS1118_CONFIG_TS_MODE_ADC | // 讀取ADC,而不是温度
ADS1118_CONFIG_PULL_UP_ON | //上拉電阻啓用
ADS1118_CONFIG_NOP_VALID | // this is valid data (default)
ADS1118_CONFIG_RESV; // reserved bits must be set to 1
switch(road) //選擇有效轉換的路數
{
case 0: config |= ADS1118_CONFIG_MUX_DIFF_0_1;break; //AINP = AIN0 and AINN = AIN1 (default)
case 1: config |= ADS1118_CONFIG_MUX_DIFF_0_3;break; //AINP = AIN0 and AINN = AIN3
case 2: config |= ADS1118_CONFIG_MUX_DIFF_1_3;break; //AINP = AIN1 and AINN = AIN3
case 3: config |= ADS1118_CONFIG_MUX_DIFF_2_3;break; //AINP = AIN2 and AINN = AIN3
case 4: config |= ADS1118_CONFIG_MUX_SINGLE_0;break; //AINP = AIN0 and AINN = GND
case 5: config |= ADS1118_CONFIG_MUX_SINGLE_1;break; //AINP = AIN1 and AINN = GND
case 6: config |= ADS1118_CONFIG_MUX_SINGLE_2;break; //AINP = AIN2 and AINN = GND
case 7: config |= ADS1118_CONFIG_MUX_SINGLE_3;break; //AINP = AIN3 and AINN = GND
default : break;
}
switch(Ref)
{
case 0: config |= ADS1118_CONFIG_PGA_6_144V;break; //000 : FS = ±6.144V(1)
case 1: config |= ADS1118_CONFIG_PGA_4_096V;break; //001 : FS = ±4.096V(1)
case 2: config |= ADS1118_CONFIG_PGA_2_048V;break; //002 : FS = ±2.048V(1)
case 3: config |= ADS1118_CONFIG_PGA_1_024V;break; //003 : FS = ±1.024V(1)
case 4: config |= ADS1118_CONFIG_PGA_0_512V;break; //004 : FS = ±0.512V(1)
case 5: case 6: case 7: config |= ADS1118_CONFIG_PGA_0_256V;break; //005 : FS = ±0.256V(1)
default : break;
}
dat = Write_ADS1118(config,mode);
return dat;
}
/*******************************************************************************
//函數名稱:Write_ADS1118()
//函數功能:設置1118寄存器
//輸 入:config:寄存器配置
// discardData: 是否更新讀回數據 0讀回 1不讀回
//返 回: 16位ad轉換數據
//備 注:
*******************************************************************************/
int16_t Write_ADS1118(uint16_t config,uint8_t discardData)
{
uint8_t i=0;
static int16_t read=0;
CS_L;
if(discardData==0)
{
read=0;
}
delay_us(1);
for(i=0;i<16;i++) // 循環16次
{
if(config & 0x8000)MOSI_H;
else MOSI_L;
config <<= 1;
delay_us(1);
SCLK_H;
delay_us(1);
SCLK_L;
delay_us(1);
if(discardData==0)
{
read<<=1;
if(READ_MISO)read ++;
}else{
delay_us(2);
}
}
CS_H;
delay_us(2);
CS_L;
// SCLK_L;
// MOSI_L;
// MISO_H;
return read;
}
main.c
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "stdlib.h"
#include "oled.h"
#include "ads1118.h"
int main(void)
{
uint8_t i=0;
char showLcd[30];
char infoBackPC[64];
int16_t value[4];
float Volt_Value;
SystemInit();
delay_init(72); //延時初始化
uart_init(9600); //串口初始化
OLED_Init();
delay_ms(100);
ADS1118_Init();//ADS1118初始化
OLED_ShowString(1, 5, "ADS1118");
delay_ms(1000);
OLED_Clear();
while(1)
{
delay_ms(100);
//四單端
if(READ_MISO==0)
{
///循環配置通道並讀取
value[i]=ADS_SEL_Read(i+4,0,0); //讀取通道
if(i==3) ADS_SEL_Read(4,0,1);//配置下一通道
else ADS_SEL_Read(i+5,0,1); //配置下一通道
i++;
}
if(i==4)
{
i=0;
Volt_Value = value[0]*ADS1118_CONST_6_144V_LSB_mV/1000;
sprintf(showLcd, "AIN0=%f",Volt_Value);
OLED_ShowString(1, 1, showLcd);
Volt_Value = value[1]*ADS1118_CONST_6_144V_LSB_mV/1000;
sprintf(showLcd, "AIN1=%f",Volt_Value);
OLED_ShowString(2, 1, showLcd);
Volt_Value = value[2]*ADS1118_CONST_6_144V_LSB_mV/1000;
sprintf(showLcd, "AIN2=%f",Volt_Value);
OLED_ShowString(3, 1, showLcd);
Volt_Value = value[3]*ADS1118_CONST_6_144V_LSB_mV/1000;
sprintf(showLcd, "AIN3=%f",Volt_Value);
OLED_ShowString(4, 1, showLcd);
// sprintf(infoBackPC, "AIN0=%f\r\nAIN1=%f\r\nAIN2=%f\r\nAIN3=%f\r\n\r\n",value[0]*ADS1118_CONST_6_144V_LSB_mV/1000,\
// value[1]*ADS1118_CONST_6_144V_LSB_mV/1000,\
// value[2]*ADS1118_CONST_6_144V_LSB_mV/1000,\
// value[3]*ADS1118_CONST_6_144V_LSB_mV/1000);
// printf("%s",infoBackPC); //串口發送
}
//兩差分,採集差分信號時需把ADS1118_Init函數的ADS1118_CONFIG_MUX_SINGLE_0改為ADS1118_CONFIG_MUX_DIFF_0_1
// if(READ_MISO==0)
// {
// ///循環配置通道並讀取
// value[i]=ADS_SEL_Read(i,0,0); //讀取通道
// if(i==1) ADS_SEL_Read(0,0,1);//配置下一通道
// else ADS_SEL_Read(i+3,0,1); //配置下一通道
// i++;
// }
// if(i==2)
// {
// i=0;
// Volt_Value = value[0]*ADS1118_CONST_6_144V_LSB_mV/1000;
// sprintf(showLcd, "AIN01=%f",Volt_Value);
// OLED_ShowString(1,1,showLcd);
//
// Volt_Value = value[1]*ADS1118_CONST_6_144V_LSB_mV/1000;
// sprintf(showLcd, "AIN23=%f",Volt_Value);
// OLED_ShowString(2,1,showLcd);
//
//// sprintf(infoBackPC, "AIN0=%.6f\r\nAIN1=%.6f\r\n\r\n",value[0]*ADS1118_CONST_6_144V_LSB_mV/1000,value[1]*ADS1118_CONST_6_144V_LSB_mV/1000);
//// printf("%s",infoBackPC); //串口發送
// }
}
}
效果展示
四單端輸入:AIN0接GND,AIN1接3.30V,AIN2接1.81V,AIN3接1.20V 。 兩差分輸入:AIN0接3.30V,AIN1接2.47V,AIN2接1.20V,AIN3接1.81V。 注意:通道懸空不為0。
七、注意事項和常見問題
注意事項
(1)模塊為低功耗模塊,建議供電電源不超過5.5V。 (2)由於模塊是高精度器件,為了避免不必要的干擾,建議使用線性電源供電。 (3)輸出信號線建議儘量短,過長容易引入噪聲信號。接觸不良或劣質的線材可能導致信號衰減或者噪聲過大。 (4)如需簡單測試模塊功能,建議搭配本店控制板使用,正確接線後給控制板供電即可實現信號採集顯示。
常見問題
Q:ADS1115和ADS1118有什麼區別? A:ADS1118是SPI通信,內部集成了高精度温度傳感器;ADS1115 是IIC通信,帶數字比較器輸出。
Q:最大可以測量多少電壓? A:最大測量電壓為供電電壓加0.3V。即理論最大測量電壓為5.8V。
Q:比如給一個電壓:2.1234V的一個電壓讓它去一直採集,它的結果是怎樣的?數值會跳動嗎? A:數據肯定是有跳動的,這個不是單一條件決定的,電源紋波噪聲,線材過長等因素都會對其造成影響。
Q:使用ADS111X和配套的主控板,用USB口供電,無法採集到5V的電壓? A:由於普遍的USB口的電壓都是低於5V的,則ADS1118芯片的供電電壓就會不足5V,這樣就採集不了5V的電壓,建議使用DC接口,5V 以上的供電,但是不可超過5.5V,這樣就可以採集到5V的電壓。
Q:ADS111X採集小電壓信號不準,是什麼情況? A:可能是芯片內部(PGA)放大倍率配置過大,可根據自己要採集的信號範圍合理設置芯片量程範圍(PGA)。
Q:模塊正常驅動後,沒有接電壓的管腳顯示也有電壓,正常嗎? A:模塊默認是4通道一直採集的,在沒有接入電壓的時候也會採集到管腳上的浮空電壓。可將管腳直接接地。即為0電壓。