(文章目錄)


一、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電壓。