STM32CubeMX驱动ADS1118模块

1. 前言

本篇中ADS1118模块的驱动是代码实现的SPI时序驱动,不是使用STM32单片机内部集成的SPI外设驱动。换句话说,使用时只需将驱动源码添加到HAL库或标准库工程中,就可以像使用库函数中的函数一样使用这个源码中的函数。本篇使用STM32CubeMX实现。

2. ADS1118模块简介

ADS1118模块是一款基于德州仪器(Texas Instruments)ADS1118芯片的高精度、超小型、低功耗模拟/数字转换器模块。该模块具有四个单端或两个差分输入通道,可通过SPI接口进行配置和控制。

该模块的输入通道可以选择不同的增益配置,从2/3 V/V到16 V/V,以适应不同的传感器信号幅值。此外,它还配备了内部参考电压源和温度传感器(这个温度传感器用来监测芯片的温度,确保系统正常的运行),并具有自动数据速率调整功能,可以根据应用程序要求自动调整采样速率以最大程度地降低功耗。

ADS1118模块还包含了额外的功能,如可编程比较器、数字滤波器和内部振荡器。这些功能可以通过SPI接口进行配置和控制,使得该模块可以满足各种应用的需求。例如,使用可编程比较器可以监视传感器输入并产生中断以触发系统操作。

此外,该模块还具有超小的尺寸和低功耗特点,使其非常适合嵌入式系统和便携式设备中使用。它的工作电压范围为2.0 ~ 5.5V,最大功耗为150μA,可以在电池供电的环境下长时间工作。

总之,ADS1118模块是一款高性能、灵活可配置、超小型和低功耗的模拟/数字转换器模块。它具有优秀的精度和实时响应特性,并且适用于各种需要高精度和低噪声的应用。

ADS1118正反面实物图:
在这里插入图片描述
在这里插入图片描述

3. 移植源码到工程

提前创建一个文件夹,用来存放工程(文件夹路径建议全英文)
打开STM32CubeMX,选择芯片(这里选择STM32F103ZET6),配置Debug,ST-LINK选择Serial Wire。
在这里插入图片描述
使能HSE和LSE,配置时钟频率为72M。
在这里插入图片描述
在这里插入图片描述
由于要使用OLED模块显示采集到的电压值,因此配置硬件IIC,这里使能IIC1,对应STM32F103ZET6引脚为PB6和PB7。
对STM32CubeMX驱动OLED有疑问的点击这里(内含OLED驱动源码提取方式)
在这里插入图片描述
创建工程名,配置编译环境。
在这里插入图片描述
这里用keil5编译,因此选择MDK-ARM-V5。
点击配置代码生成器并生成代码。
在这里插入图片描述
点击GENERATE CODE即可生成代码。
打开工程存放的位置。
移植ads1118相关的.h和.c文件到工程中。

相关文件提取方式:
关注微信公众号:码上芯路人
私信:模块驱动

说明:ads1118.h中是一些宏定义和ad相关的函数声明,ads1118.c中是ad相关函数的定义。
将ads1118.h、oled.h和oledfont.h文件复制到工程文件目录Ads1118_test\Core\Inc中
在这里插入图片描述
将oled.c和ads1118.c文件复制到工程文件目录Ads1118_test\Core\Src中
在这里插入图片描述
双击打开Ads1118_test\MDK-ARM目录中UVPROJX文件,按下图提示操作。
在这里插入图片描述
在这里插入图片描述
编译后oled.h和oledfont.h将被包含在oled.c目录下,ads1118.h将被包含在ads1118.c目录下。
在这里插入图片描述
在这里插入图片描述
下面介绍驱动函数。

4. 驱动源码中函数介绍

4.1 us延时函数

由于HAL库中没有延时微秒的函数,因此自己定义一个us延时函数。
函数声明如下:

void delay_us(uint32_t us);		 				    
  • uint32_t us:需要延时的微秒数。

4.2 写入和读取ADS1118配置寄存器

函数声明如下:

int16_t Write_ADS1118(uint16_t config,uint8_t discardData)
  • uint16_t config:一个16位无符号整数,表示要写入到ADS1118配置寄存器中的值。
  • uint8_t discardData:一个8位无符号整数,如果为0,则在读取之前将之前读取的数据丢弃;如果不为0,则会保留之前的数据。
  • 返回值为一个16位有符号整数,如果discardData为0,则为此次读取得到的结果;如果discardData不为0,则为0。

4.3 初始化ADS1118

函数声明如下:

void ADS1118_Init(void);

先将一些配置信息用位运算写入配置寄存器变量中(这些配置信息见ADS1118相关资料)。然后,配置硬件连接的若干个引脚和CS、MISO、SCLK和DIN引脚的初始状态,最后,使用int16_t Write_ADS1118函数向ADS1118写入初始配置信息。

4.4 测量电压函数

函数声明如下:

int16_t ADS_SEL_Read(uint8_t road,uint8_t Ref,uint8_t mode);  
  • uint8_t road:要测量的路数,取值范围为 0~7,分别代表了不同的电路连接方式。
    0:AINP = AIN0 and AINN = AIN1 (默认)
    1:AINP = AIN0 and AINN = AIN3
    2:AINP = AIN1 and AINN = AIN3
    3:AINP = AIN2 and AINN = AIN3
    4:AINP = AIN0 and AINN = GND
    5:AINP = AIN1 and AINN = GND
    6:AINP = AIN2 and AINN = GND
    7:AINP = AIN3 and AINN = GND
  • uint8_t Ref:参考电压的大小,其取值范围为 0~7,代表了不同的参考电压大小。
    0:FS = ±6.144V(1)
    1:FS = ±4.096V(1)
    2:FS = ±2.048V(1)
    3:FS = ±1.024V(1)
    4:FS = ±0.512V(1)
    5、6、7:FS = ±0.256V(1)
  • uint8_t mode:转换模式,其取值为 0 或 1,分别代表单次转换和连续转换两种模式。
  • 返回值为16位的有符号整数,由于可以读取负电压,因此有效取值范围为:-2 ^ 15——+2 ^ 15。

5. 实验

说明:实验用到的ADS1118的源码中,配置的寄存器都是芯片手册上的默认值,如需修改配置的默认寄存器,参照芯片手册修改。

5.1 单通道采样

采集AIN1—CND和AIN2—GND两个通道的电压,这两个通道分别接两路直流电源输出的3V—GND和2V—GND,将采集的电压示数显示在OLED上,并调整两路直流电源输出的电压后再次观察OLED屏上采集的电压示数。
主函数内容如下:

#include "main.h"
#include "i2c.h"
#include "gpio.h"
#include "oled.h"
#include "ads1118.h"
#include "stdio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	float Volt_Value[2]={0,0};

    unsigned  char str_buff1[16];       
    unsigned  char str_buff2[16];
        
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  /* USER CODE BEGIN 2 */
    OLED_Init();
    OLED_Clear();
    ADS1118_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */    
      //AN1
      Volt_Value[0] = ADS_SEL_Read(5,1,0)*ADS1118_CONST_4_096V_LSB_mV/1000;
      /*说明:由于采集一个通道时,ADS1118模块的采样率最高达到860次/s,默认值为128次/s,
      采集两个通道时采样率会大打折扣,因此不能不间断的采样,切换通道采样时要延时合适的时间再切换通道采样*/
      HAL_Delay(15);    
      //AN2
      Volt_Value[1] = ADS_SEL_Read(6,1,0)*ADS1118_CONST_4_096V_LSB_mV/1000; 
      HAL_Delay(15);
      
      //显示
      sprintf((char*)str_buff1,"AIN1=%.3fV",Volt_Value[0]);
      OLED_ShowString(0,0,str_buff1,16);
      //显示
      sprintf((char*)str_buff2,"AIN2=%.3fV",Volt_Value[1]);
      OLED_ShowString(0,2,str_buff2,16);
      
	}
  /* USER CODE END 3 */
}

效果如下:

ADS1118_实验1_效果

5.2 差分通道采样

采集AIN0—AIN1和AIN2—AIN3两个通道的电压差值,这两个差分通道接线是AIN0—3V,AIN1—GND;AIN2—2V,AIN3—GND,最后将采集的差值电压示数显示在OLED上,并调整两路直流电源输出的电压后再次观察OLED屏上采集的差值电压示数。
主函数内容如下:

#include "main.h"
#include "i2c.h"
#include "gpio.h"
#include "oled.h"
#include "ads1118.h"
#include "stdio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	float Ain0_1=0;
	float Ain2_3=0;

    unsigned  char str_buff1[16];       
    unsigned  char str_buff2[16];
        
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  /* USER CODE BEGIN 2 */
    OLED_Init();
    OLED_Clear();
    ADS1118_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      //AIN0-AIN1
      Ain0_1 = ADS_SEL_Read(0,1,0)*ADS1118_CONST_4_096V_LSB_mV/1000;
      //这里与单端采样相同,仍需要延时
      HAL_Delay(15); 
      //AIN2-AIN3
      Ain2_3 = ADS_SEL_Read(3,1,0)*ADS1118_CONST_4_096V_LSB_mV/1000;
      HAL_Delay(15); 
      //显示
      sprintf((char*)str_buff1,"AIN0_1=%.3fV",Ain0_1);
      OLED_ShowString(0,0,str_buff1,16);
      //显示
      sprintf((char*)str_buff2,"AIN2_3=%.3fV",Ain2_3);
      OLED_ShowString(0,2,str_buff2,16);
      
	}
  /* USER CODE END 3 */
}

效果如下:

ADS1118_实验2_效果

5.3 芯片温度监测

通过与芯片接触,监测芯片的温度变化。
主函数内容如下:

#include "main.h"
#include "i2c.h"
#include "gpio.h"
#include "oled.h"
#include "ads1118.h"
#include "stdio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
    int16_t value = 0;
    float temp=0;
    unsigned  char str_buff[16];
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  /* USER CODE BEGIN 2 */
    OLED_Init();
    OLED_Clear();
    ADS1118_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      //向ADS1118写入0x409B命令,这个命令表示读取ADS1118芯片的温度(具体见芯片手册),将读取结果存储在value变量中。
      value=Write_ADS1118(0x409B,0);//读取内部温度
      /*由于ADS1118芯片返回的温度数据占用了16个比特(从最高位开始占用),
      但实际有效数据只有14个比特,因此需要将其右移两位来获取正确的温度数据。*/
      value>>=2;
      //温度可能为负数,负数以补码形式存储,那么将其转换为负数
      if(value&0x20000) value=-(~(value-1));
      //转换为温度值。ADS1118_CONST_C_PER_BIT表示每个比特对应的温度值
      temp = value*ADS1118_CONST_C_PER_BIT; 
      sprintf((char*)str_buff,"temp=%.3f",temp);
      OLED_ShowString(0,0,str_buff,16);
      OLED_ShowCHinese(89,0,2);
    }
  /* USER CODE END 3 */
}

效果如下:

ADS1118_实验3_效果

说明:当两个物体温度不同时,会发生热传递,热量会从高温物体流向低温物体,高温物体降温,低温物体逐渐升温,直到两者达到热平衡。到达平衡的过程需要一定时间。

  • 8
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值