ADS1118 作为常用温度测量芯片被越来越多的开发者熟知,TI官方给出的是基于 MSP430 的驱动测试程序,由于 STM32 的普及,闲暇中移植了 MSP430 的 ADS1118 驱动程序到 STM32F103 平台下,并进行了测试,特在此记录,以飨读者。

使用 STM32F103 的 SPI2 接口连接 ADS1118 的通信接口:

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

ADS1118 手册建议数据线之间接一个50欧电阻,实际测试可不接。ADS1118 电源接3.3V并加滤波电容。

SPI 配置

ADS1118 接口的时序要求如图:

DIN 接口接收控制器送过来的配置数据,并且在 SCLK 的下降沿将数据锁存读入 ADS1118 内部,并且在 SCLK 的上升沿中将数据送出到 DOUT。基于此将 STM32F103 的 SPI 接口做如下配置,CPOL=0,CPHA = 1;
  

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 的配置:
  

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);
}

另外记得使能端口时钟:
  

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模式:

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官方公布的精度,在硬件电路方面有待进一步提高。全部源码后续会放出。

STM32F103驱动ADS1118的更多相关文章

  1. STM32F103驱动GT911

    0x00 引脚连接: // SCL-------PB10 // SDA-------PB11 // INT--------PB1 // RST--------PB2 IIC的SCL与SDA需要接上拉电 ...

  2. 电赛总结(四)——波形发生芯片总结之AD9834

    一.特性参数 1.2.3V~5.5V供电 2.输出频率高达37.5MHz 3.正弦波.三角波输出 4.提供相位调制和频率调制功能 5.除非另有说明,VDD = 2.3 V至5.5 V,AGND = D ...

  3. FLASH 存储学习-串行SPI NOR FLASH

    1.1 SST25VF080B简介1.1.1 主要特性 关键点:容量.速度(时钟速度.读写速度).功耗. l 容量:8MBit: l 最高SPI时钟频率:50MHz: l 低功耗模式下电流消耗:5uA ...

  4. FLASH 存储学习-串行SPI nor

    1.1 SST25VF080B简介 1.1.1 主要特性 关键点:容量.速度(时钟速度.读写速度).功耗. 容量:8MBit: 最高SPI时钟频率:50MHz: 低功耗模式下电流消耗:5uA,正常读模 ...

  5. STM32-串行SPI nor

    源:FLASH 存储学习-串行SPI nor 1.1 SST25VF080B简介1.1.1 主要特性 关键点:容量.速度(时钟速度.读写速度).功耗. l 容量:8MBit: l 最高SPI时钟频率: ...

  6. 从FPGA搞定OV7670 VGA显示 移植到 STM32F10x TFT显示 总结及疑问(高手请进)

    OV7670不愧是最便宜的摄像头了最大显示像素:640*480(在VGA显示器上显示效果还不赖,用usb模块采集显示依然显著) 第一步:VGA显示 视频图像(实时)FPGA+SDRAM+OV7670= ...

  7. STM32F103 USB虚拟串口 驱动例程移植

    1)驱动下载及安装.目前ST公司支持WIN7版本号为:VCP_V1.3.1_Setup.exe (在官网上搜索stsw-stm32102即是了):先安装驱动后再插入USB不然安装不成功. 2)固件下载 ...

  8. 如何为编程爱好者设计一款好玩的智能硬件(八)——LCD1602点阵字符型液晶显示模块驱动封装(中)

    六.温湿度传感器DHT11驱动封装(下):如何为编程爱好者设计一款好玩的智能硬件(六)——初尝试·把温湿度给收集了(下)! 七.点阵字符型液晶显示模块LCD1602驱动封装(上):如何为编程爱好者设计 ...

  9. STM32F103的11个定时器详解(转)

    源:STM32F103的11个定时器详解 STM32F103系列的单片机一共有11个定时器,其中:2个高级定时器4个普通定时器2个基本定时器2个看门狗定时器1个系统嘀嗒定时器 出去看门狗定时器和系统滴 ...

随机推荐

  1. Scipy优化算法--scipy.optimize.fmin_tnc()/minimize()

    scipy中的optimize子包中提供了常用的最优化算法函数实现,我们可以直接调用这些函数完成我们的优化问题. scipy.optimize包提供了几种常用的优化算法. 该模块包含以下几个方面 使用 ...

  2. dynamic用法

    https://www.cnblogs.com/lgx5/p/9650203.html https://www.cnblogs.com/gygtech/p/9915367.html

  3. 容斥原理的(二进制思想和质因子分解+模板)hdu4135+ecf81.D

    题:http://acm.hdu.edu.cn/showproblem.php?pid=4135 题意:求[A,B]与N互质的数的个数 #include<iostream> #includ ...

  4. tesseract系列(4) -- tesseract训练问题总结

    1. 每次训练模型删除目录下,上述重复的名字 2. 生成inttemp.pffmtable文件的时候,如果下述命令(1)不行的话,或者报错,使用命令(2) (1)mftraining -F font_ ...

  5. 在Orcl中通过SQL语句修改创建表

    1.创建表时定义唯一性约束 CREATE TABLE table_name ( column1 datatype null/not null, column2 datatype null/not nu ...

  6. addEventListener和onclick的区别

    onclick只出现一次alert:我是click2[很正常第一次click事件会被第二次所覆盖],但是addEventListener却可以先后运行,不会被覆盖[正如:它允许给一个事件注册多个监听器 ...

  7. 01-Java 教程

    一.我的第一个 java 程序 创建文件 HelloWorld.java(文件名需与类名一致), 代码如下: public class HelloWorld { public static void ...

  8. hibernate多表查询sql,以及所得对象的处理

    String sql ="SELECT id FROM tea WHERE tea.name=? "; SQLQuery query = this.getSession().cre ...

  9. Leetcode_开篇碎碎念

    已经计划写leetcode3天了,但是到目前为止一道题还没有写,执行力我太差了. 写leetcode的原因有两个,一是锻炼自己代码水平,提高实力:二是考研据了解到的都会有上机考试,基本是c++,jav ...

  10. python语法基础-函数-迭代器和生成器-长期维护

    ###############    迭代器    ############## """ 迭代器 这是一个新的知识点 我们学习过的可以迭代的对象有哪些? list str ...