STM32F103驅動ADS1118

ADS1118 做爲經常使用溫度測量芯片被愈來愈多的開發者熟知,TI官方給出的是基於 MSP430 的驅動測試程序,因爲 STM32 的普及,閒暇中移植了 MSP430 的 ADS1118 驅動程序到 STM32F103 平臺下,並進行了測試,特在此記錄,以饗讀者。函數

使用 STM32F103 的 SPI2 接口鏈接 ADS1118 的通訊接口:測試

STM32F103|ADS1118
—|—|—|
PB12|CS
PB13|SCLK
PB14|DOUT
PB15|DINui

ADS1118 手冊建議數據線之間接一個50歐電阻,實際測試可不接。ADS1118 電源接3.3V並加濾波電容。spa

SPI 配置

ADS1118 接口的時序要求如圖:
設計

DIN 接口接收控制器送過來的配置數據,而且在 SCLK 的降低沿將數據鎖存讀入 ADS1118 內部,而且在 SCLK 的上升沿中將數據送出到 DOUT。基於此將 STM32F103 的 SPI 接口作以下配置,CPOL=0,CPHA = 1;
  3d

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void SPI_config(void){
SPI_Cmd(SPI_MASTER, DISABLE);//配置以前先關閉SPI接口

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//主模式
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//8bits
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;// CPOL=0
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//CPHA=1
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//CS設置爲軟件配置
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;//通訊速率
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//高位在前
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI_MASTER, &SPI_InitStructure);

SPI_Cmd(SPI_MASTER, ENABLE);//配置完成使能SPI接口
}

對應 GPIO 的配置:
  code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void SPI_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

/* Configure SPI_MASTER pins-*/

// Pin PB13 (SCLK) must be configured as as 50MHz push pull
GPIO_StructInit(
GPIO_InitStructure.GPIO_Pin = SPI_MASTER_PIN_SCK;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPI_MASTER_GPIO,

// Pin PB14 (MISO) must be configured as as input pull-up
GPIO_StructInit(
GPIO_InitStructure.GPIO_Pin = SPI_MASTER_PIN_MISO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(SPI_MASTER_GPIO,

// Pin PB15 (MOSI) must be configured as as 50MHz push pull
GPIO_StructInit(
GPIO_InitStructure.GPIO_Pin = SPI_MASTER_PIN_MOSI;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPI_MASTER_GPIO, &GPIO_InitStructure);

//SPI1 NSS
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = SPI_MASTER_PIN_NSS;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(SPI_MASTER_GPIO, &GPIO_InitStructure);

GPIO_SetBits(SPI_MASTER_GPIO, SPI_MASTER_PIN_NSS);
}

另外記得使能端口時鐘:
  blog

1
2
3
4
5
6
void (void){
/* Enable GPIO clock for SPI_MASTER */
RCC_APB2PeriphClockCmd(SPI_MASTER_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);
/* Enable SPI_MASTER Periph clock */
RCC_APB1PeriphClockCmd(SPI_MASTER_CLK, ENABLE);
}

讀寫實現

ADS1118 在發送寄存器配置的同時會傳輸轉換結果,手冊中提到既支持16bits 模式也支持32bits模式。接口

16bits模式:ip

32bits模式:

DIN 接口接收寄存器配置的同時DOUT接口輸出轉換結果,在32bits模式下發送完寄存器配置後第二次能夠發送數據0,具體可參考手冊。基於此設計數據發送讀取函數:
  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//讀寫寄存器16bits模式
uint16_t SPI_read_write_Reg(uint16_t CofigReg)
{

getdata1=SPI_send_Byte((uint8_t)(CofigReg>>8));
getdata2=SPI_send_Byte((uint8_t)CofigReg);

getdata= (uint16_t)getdata2|((uint16_t)getdata1<<8);

return getdata;
}
uint8_t SPI_send_Byte(uint8_t byte)
{

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET){}

SPI_I2S_SendData(SPI2, byte);

while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET){}

return SPI_I2S_ReceiveData(SPI2);
}

獲取 ADS1118 的片內溫度須要將 ADS1118 的寄存器的第4bit修改成1,啓動單次轉換將第15bit寫1便可:
  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
< 大專欄  STM32F103驅動ADS1118/pre>
float ads1118_get_temperature(void)
{
uint16_t adc=0;
float value=0;
adsConfigReg.stru.NOP = DATA_VALID;
adsConfigReg.stru.TS_MODE = TEMPERATURE_MODE;
adsConfigReg.stru.DR = DR_8_SPS;
adsConfigReg.stru.MODE = SIGNLE_SHOT;
adsConfigReg.stru.OS = SINGLE_CONVER_START;

ADS1118_ENABLE;

adc = SPI_read_write_Reg(adsConfigReg.word);

//conver to temperture
if(adc&0x8000)
{
//-xx.xxx c
adc>>=2;
value=(0x3fff-adc+1)*(-0.03125);
}
else
{
//+xx.xxx c
adc>>=2;
value=adc*0.03125;
}
ADS1118_DISABLE;
return value;
}

ADS1118默認開啓ADC模式,經過配置寄存器的12-14bit能夠選擇開啓哪一個通道,具體可參考手冊。另外關於片內溫度模式時,使用的是14bit左對齊模式。並且ADS1118的轉換結果中,負數使用二進制補碼格式,所以須要作一個轉換,每一個值表明0.03125℃,測試中的SPI通訊數據:

熱電偶

ADS1118 可使用差分方式鏈接兩路熱電偶溫度傳感器,本篇也是參考了TI官方文檔 使用ADS1118進行精密熱電偶測量。冷端溫度讀取片內溫度便可,將片內溫度轉換成熱電偶對應的電壓,而後加上熱端獲取的電壓值,反向查表便可獲取熱電偶溫度值。實際測試時使用的是K型熱電偶,從網上查到K型熱電偶的溫度電壓對應表,進行查表:
  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type_k_thermo_lookup_table type_k_thermo_lookup[16] = {
{-200,-5.891},
{-100,-3.554},
{0,0},
{100,4.096},
{200,8.138},
{300,12.209},
{400,16.397},
{500,20.644},
{600,24.905},
{700,29.129},
{800,33.275},
{900,37.326},
{1000,41.276},
{1100,45.119},
{1200,48.838},
{1300,52.410}
};

測試時冷端溫度通常高於室內溫度2攝氏度左右,由於芯片內部發熱所致,獲取差分輸入的代碼設置以下:
  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
uint16_t ads1118_get_differential_0_1(uint8_t PGA)
{
uint16_t adc=0;

ADS_InitTypeDef ConfigReg;

ConfigReg.stru.NOP = DATA_VALID;
ConfigReg.stru.TS_MODE = ADC_MODE;
ConfigReg.stru.DR = DR_860_SPS;
ConfigReg.stru.PGA = PGA;
ConfigReg.stru.MODE = SIGNLE_SHOT;
ConfigReg.stru.OS = SINGLE_CONVER_START; //high
ConfigReg.stru.MUX = AINPN_0_1;
ConfigReg.stru.PULLUP = PULL_UP_EN;
ConfigReg.stru.RESV = CONFIG_BIT_RESV;
ADS1118_ENABLE;
delay_us((uint32_t)1);
adc = SPI_read_write_Reg(ConfigReg.word);

ADS1118_DISABLE;
delay_ms(1);
ADS1118_ENABLE;
ConfigReg.stru.NOP = DATA_INVALID;
ConfigReg.stru.TS_MODE = ADC_MODE;
ConfigReg.stru.DR = DR_860_SPS;
ConfigReg.stru.PGA = PGA;
ConfigReg.stru.MODE = SIGNLE_SHOT;
ConfigReg.stru.OS = SINGLE_CONVER_START; //high
ConfigReg.stru.MUX = AINPN_0_1;
ConfigReg.stru.PULLUP = PULL_UP_EN;
ConfigReg.stru.RESV = CONFIG_BIT_RESV;
delay_us((uint32_t)1);

//等待Dout給出數據有效信號--從高變低
while(GPIO_ReadInputDataBit(SPI_MASTER_GPIO,SPI_MASTER_PIN_MISO));
adc = SPI_read_write_Reg(ConfigReg.word);
delay_us(1);
ADS1118_DISABLE;
return adc;
}

實際測試時,溫度精度在2攝氏度左右,並無達到TI官方公佈的精度,在硬件電路方面有待進一步提升。所有源碼後續會放出。

相關文章
相關標籤/搜索