CH32驱动16位ADC——ADS1118


前言

CH32硬件SPI驱动16位ADS1118,采集内部温度传感器,单端,差分采集外部电压。


一、ADS1118?

ADS1118 数据转换速率最高可达每秒 860 次采样(SPS)。PGA 的输入范围为 ±256mV 至 ±6.144V,能够以高分辨率测量大信号和小信号。该器件通过输入多路复用器 (MUX) 测量双路差分输入或四路单端输入。高精度温度传感器用于系统级温度监控或对热电偶进行冷结点补偿。ADS1118,工

1、ADS1118推荐操作环境

ADS1118供电范围:VDD电压范围2-5.5V。
ADS1118模拟输入范围:VIN输入范围GND~VDD。
在这里插入图片描述

二、使用步骤

1.硬件SPI

ADS1118,SPI读写有32位,16位模式。32位模式相较于16位模式可以读取配置ADS1118寄存器配置。本程序不读取ADS1118配置,使用16位模式。硬件SPI使用16位数据模式。ADS1118读写为SPI模式1,(CPOL = 0, CPHA = 1)。

#include "SPI.h"
#include "CH32f10x.h"                  // Device header
#include "DEBUG.h"
void MySPI_W_SS(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);
}

void MySPI_Init()
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};//初始化结构体
	SPI_InitTypeDef SPI_InitStruct = {0};//初始化结构体
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);
	
	GPIO_InitStruct.GPIO_Mode =GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin =GPIO_Pin_5|GPIO_Pin_7;//SPI_MOSI.SPI_SCLK
	GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode =GPIO_Mode_Out_PP;    //SPI_NSS
	GPIO_InitStruct.GPIO_Pin =GPIO_Pin_4;
	GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode =GPIO_Mode_IPU;        //SPI_MISO
	GPIO_InitStruct.GPIO_Pin =GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
	SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; 
	SPI_InitStruct.SPI_Mode = SPI_Mode_Master;//主机模式
	SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
	SPI_InitStruct.SPI_DataSize = SPI_DataSize_16b;//十六位数据   
	SPI_InitStruct.SPI_Direction =SPI_Direction_2Lines_FullDuplex;//双线全双工
	SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_InitStruct.SPI_CRCPolynomial = 7;
	SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
	SPI_Init(SPI1,&SPI_InitStruct);
	SPI_Cmd(SPI1,ENABLE);
	MySPI_W_SS(1);
	//MySPI_W_SCK(0);///mode0 and mode1
	//MySPI_W_SCK(1);//mode2 and mode3
}
uint16_t MySPI_SwapByte(uint16_t ByteSend)
{
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);
	
	SPI_I2S_SendData(SPI1, ByteSend);
	
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);
	
	return SPI_I2S_ReceiveData(SPI1);
}

void MySPI_Start()//拉低片选脚开始通信
{
	MySPI_W_SS(0);
}
void MySPI_STOP()//拉高片选脚结束通信
{
	MySPI_W_SS(1);
}

SPI.h

#ifndef __SPI_H
#define __SPI_H
#include "ch32f10x.h"
//SPI 端口定义

void MySPI_W_SS(uint8_t BitValue);
void MySPI_W_SCK(uint8_t BitValue);
void MySPI_W_MOSI(uint8_t BitValue);
void MySPI_W_16bit_MOSI(uint16_t BitValue);
uint8_t MySPI_R_MISO();
void MySPI_Init();
void MySPI_Start();//拉低片选脚开始通信
void MySPI_STOP();//拉高片选脚结束通信
uint8_t MySPI_exchange_Data_mode0(uint8_t Btye);//mode=0,sck low,first SCK send data and recevie data
uint8_t MySPI_exchange_Data_mode1(uint8_t Btye);//mode=1,sck low,first SCK send data second recevie data
uint8_t MySPI_exchange_Data_mode2(uint8_t Btye);//mode=2,sck high,first SCK send data second recevie data
uint8_t MySPI_exchange_Data_mode3(uint8_t Btye);//mode=3,sck high,first SCK send data second recevie data
uint16_t MySPI_exchange_Data_mode1_16bit(uint16_t Btye);//mode=1,sck low,first SCK send data second recevie data
uint16_t MySPI_SwapByte(uint16_t ByteSend);


2.ADS1118配置模式

ADS1118,16位读写模式。首先对ADS111816位寄存器写数据进行配置,拉高片选重置ADS1118,在下一次拉低片选,开始读去ADS1118数据,其中ADS1118数据转换完成,DOUT会从高变低,DOUT拉低后在开始读取数据。
单次模式每次读取ADC先配置ADS1118寄存器后,在下一次通信读取ADC数据.
连续模式配置一次ADS1118寄存器后,等待DOUT下降沿后读取ADC数据,无需每次读数据前配置ADS1118寄存器。
在这里插入图片描述

#include "ADS1118.h"
#include "SPI.h"
#include "debug.h"
//ADS1118 supply voltage 2 - 5.5V
//analog input voltage max VDD+0.3V.    VIN<VDD!!!!!
//(VDD-->3v3,PGA-->4096,)无法获得满量程ADC输出代码,这种意味着一些动态范围的丢失.
//单次模式调用ADS1118_Get_ADC_SIGLE_SHOT_Data(),
//连续模式先调用ADS1118_ADC_Init()初始化,在调用ADS1118_Get_ADC_Continuous_Data()
void ADS1118_ADC_Init(uint16_t channel,uint16_t PGA,uint16_t SPS)
{
	MySPI_Init();
	ADS1118_ENABLE;//拉低CS开始通信
	Delay_Us(5);
	MySPI_SwapByte(ADS1118_SS_START|channel|PGA|ADS1118_Continuous_MODE
					|SPS|ADS1118_Temp_MODE|ADS1118_PUUP_EN|ADS1118_NOP_UPDATA);//发送寄存器命令,交换数据

	Delay_Us(15);
	ADS1118_DISABLE;//拉高CS复位ADS1118结束通信
	Delay_Ms(1);
	
}
/*************************************
		读取内部传感器温度
*************************************/
float ADS1118_Get_Tempture_Data()//单次获取ADC内部Temp温度
{
	uint16_t ADC_Data = 0;
	float Tempture_data= 0;
	ADS1118_ENABLE;//拉低CS开始通信
	Delay_Us(5);
	ADC_Data = MySPI_SwapByte(ADS1118_SS_START|ADS1118_MUX_AIN0|ADS1118_PGA_4096|ADS1118_Sigle_SHOT_MODE
							|ADS1118_DR_8SPS|ADS1118_Temp_MODE|ADS1118_PUUP_EN|ADS1118_NOP_UPDATA);//发送寄存器命令,交换数据

	Delay_Us(5);
	ADS1118_DISABLE;//拉高CS复位ADS1118结束通信
	
	Delay_Ms(1);
	
	ADS1118_ENABLE;//拉低CS开始通信
	Delay_Us(5);
	while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6));//DOUT拉低ADC1118数据更新准备完毕

	ADC_Data = MySPI_SwapByte(ADS1118_SS_START|ADS1118_MUX_AIN0|ADS1118_PGA_4096|ADS1118_Sigle_SHOT_MODE
							|ADS1118_DR_8SPS|ADS1118_Temp_MODE|ADS1118_PUUP_EN|ADS1118_NOP_UPDATA);//发送寄存器命令,交换数据
	Delay_Us(5);
	ADS1118_DISABLE;//拉高CS复位ADS1118结束通信
	if(ADC_Data&0X8000)//MSB=1
	{
		ADC_Data = (~ADC_Data)+1 ;
	}
	else Tempture_data = (ADC_Data >> 2)*0.03125;
	return Tempture_data;	
}
/*********************************************************************
 * @fn      ADS1118_Get_ADC_SIGLE_SHOT_Data
 *
 * @brief  获取ADC数据
 *
 * @param   channel - ADC通道选择        
 *	        ADS1118_MUX_AINX_AINX           //more than ref ADS1118.h
 *          ADS1118_MUX_AINX        
 *          PGA - 	ADC 测量范围选择
 *			ADS1118_PGA_XXXX                //more than ref ADS1118.h
 *			SPS - ADC 数据传输率        
 *			ADS1118_DR_XSPS                 //more than ref ADS1118.h
 * @return  Voltage(mv)
 */
float ADS1118_Get_ADC_SIGLE_SHOT_Data(uint16_t channel,uint16_t PGA,uint16_t SPS)//单次获取AD电压值
{
	uint16_t ADC_Data = 0;
	float Tempture_data= 0;
	ADS1118_ENABLE;//拉低CS开始通信
	Delay_Us(15);
	ADC_Data = MySPI_SwapByte(ADS1118_SS_START|channel|PGA|ADS1118_Sigle_SHOT_MODE
							|SPS|ADS1118_ADC_MODE|ADS1118_PUUP_EN|ADS1118_NOP_UPDATA);//发送寄存器命令,交换数据

	Delay_Us(15);
	ADS1118_DISABLE;//拉高CS复位ADS1118结束通信
	
	Delay_Ms(1);
	
	ADS1118_ENABLE;//拉低CS开始通信
	Delay_Us(15);
	while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6));//DOUT拉低ADC1118数据更新准备完毕

	ADC_Data = MySPI_SwapByte(ADS1118_SS_START|channel|PGA|ADS1118_Sigle_SHOT_MODE
							 |SPS|ADS1118_ADC_MODE|ADS1118_PUUP_EN|ADS1118_NOP_UPDATA);//发送寄存器命令,交换数据

	Delay_Us(15);
	ADS1118_DISABLE;//拉高CS复位ADS1118结束通信
	if(ADC_Data&0X8000)//MSB=1
	{
		ADC_Data = (~ADC_Data)+1 ;
		if(PGA == ADS1118_PGA_6144)Tempture_data=ADC_Data*0.1875;
		else if(PGA == ADS1118_PGA_6144)Tempture_data=ADC_Data*0.1875;
		else if(PGA == ADS1118_PGA_4096)Tempture_data=ADC_Data*0.125;
		else if(PGA == ADS1118_PGA_2048)Tempture_data=ADC_Data*0.0625;
		else if(PGA == ADS1118_PGA_1024)Tempture_data=ADC_Data*0.03125;
		else if(PGA == ADS1118_PGA_0512)Tempture_data=ADC_Data*0.015625;
		else Tempture_data=ADC_Data*0.0078125;
		return Tempture_data;
	}
	else if(PGA == ADS1118_PGA_6144)Tempture_data=ADC_Data*0.1875;
	else if(PGA == ADS1118_PGA_6144)Tempture_data=ADC_Data*0.1875;
	else if(PGA == ADS1118_PGA_4096)Tempture_data=ADC_Data*0.125;
	else if(PGA == ADS1118_PGA_2048)Tempture_data=ADC_Data*0.0625;
	else if(PGA == ADS1118_PGA_1024)Tempture_data=ADC_Data*0.03125;
	else if(PGA == ADS1118_PGA_0512)Tempture_data=ADC_Data*0.015625;
	else Tempture_data=ADC_Data*0.0078125;
	return Tempture_data;	
}
/*********************************************************************
 * @fn      ADS1118_Get_ADC_Continuous_Data
 *
 * @brief  连续模式获取ADC数据,使用前初始化 ADS1118_ADC_Init()
 *
 * @param   channel - ADC通道选择        
 *	        ADS1118_MUX_AINX_AINX           //more than ref ADS1118.h
 *          ADS1118_MUX_AINX        
 *          PGA - 	ADC 测量范围选择
 *			ADS1118_PGA_XXXX                //more than ref ADS1118.h
 *			SPS - ADC 数据传输率        
 *			ADS1118_DR_XSPS                 //more than ref ADS1118.h
 * @return  Voltage(mv)
 */
float  ADS1118_Get_ADC_Continuous_Data(uint16_t channel,uint16_t PGA,uint16_t SPS)
{
	uint16_t ADC_Data = 0;
	float Tempture_data= 0;
	ADS1118_ENABLE;//拉低CS开始通信
	Delay_Us(1);
	while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6));//DOUT拉低ADC1118数据更新准备完毕

	ADC_Data = MySPI_SwapByte(ADS1118_SS_START|channel|PGA|ADS1118_Continuous_MODE
							 |SPS|ADS1118_ADC_MODE|ADS1118_PUUP_EN|ADS1118_NOP_UPDATA);//发送寄存器命令,交换数据

	Delay_Us(1);
	ADS1118_DISABLE;//拉高CS复位ADS1118结束通信
	if(ADC_Data&0X8000)//MSB=1
	{
		ADC_Data = (~ADC_Data)+1 ;
		if(PGA == ADS1118_PGA_6144)Tempture_data=ADC_Data*0.1875;
		else if(PGA == ADS1118_PGA_6144)Tempture_data=ADC_Data*0.1875;
		else if(PGA == ADS1118_PGA_4096)Tempture_data=ADC_Data*0.125;
		else if(PGA == ADS1118_PGA_2048)Tempture_data=ADC_Data*0.0625;
		else if(PGA == ADS1118_PGA_1024)Tempture_data=ADC_Data*0.03125;
		else if(PGA == ADS1118_PGA_0512)Tempture_data=ADC_Data*0.015625;
		else Tempture_data=ADC_Data*0.0078125;
		return Tempture_data;
	}
	else if(PGA == ADS1118_PGA_6144)Tempture_data=ADC_Data*0.1875;
	else if(PGA == ADS1118_PGA_6144)Tempture_data=ADC_Data*0.1875;
	else if(PGA == ADS1118_PGA_4096)Tempture_data=ADC_Data*0.125;
	else if(PGA == ADS1118_PGA_2048)Tempture_data=ADC_Data*0.0625;
	else if(PGA == ADS1118_PGA_1024)Tempture_data=ADC_Data*0.03125;
	else if(PGA == ADS1118_PGA_0512)Tempture_data=ADC_Data*0.015625;
	else Tempture_data=ADC_Data*0.0078125;
	return Tempture_data;
}

ADS1118.h

#ifndef __ADS1118_H
#define __ADS1118_H
#include "ch32f10x.h"
#include "SPI.h"
#include "debug.h"

#define ADS1118_ENABLE           MySPI_Start()  //PULL DOWM CS START ADC
#define ADS1118_DISABLE          MySPI_STOP()  //PULL UP CS STOP ADC

#define ADS1118_SS_START        0X8000    //0--》NO effect,1-->start ADC

#define ADS1118_MUX_AIN0_AIN1   0X0000    //000 = AINP is AIN0 and AINN is AIN1 (default)
#define ADS1118_MUX_AIN0_AIN3   0x1000    //001 = AINP is AIN0 and AINN is AIN3
#define ADS1118_MUX_AIN1_AIN3   0X2000    //010 = AINP is AIN1 and AINN is AIN3
#define ADS1118_MUX_AIN2_AIN3   0X3000    //011 = AINP is AIN2 and AINN is AIN3
#define ADS1118_MUX_AIN0        0X4000    //100 = AINP is AIN0 and AINN is GND
#define ADS1118_MUX_AIN1        0X5000    //101 = AINP is AIN1 and AINN is GND
#define ADS1118_MUX_AIN2        0X6000    //110 = AINP is AIN2 and AINN is GND
#define ADS1118_MUX_AIN3        0X7000    //111 = AINP is AIN3 and AINN is GND

#define ADS1118_PGA_6144        0X0000    //000 = FSR is ±6.144 V
#define ADS1118_PGA_4096        0X0200    //001 = FSR is ±4.096 V
#define ADS1118_PGA_2048        0X0400    //010 = FSR is ±2.048 V (default)
#define ADS1118_PGA_1024        0X0600    //011 = FSR is ±1.024 V
#define ADS1118_PGA_0512        0X0800    //100 = FSR is ±0.512 V
#define ADS1118_PGA_0256        0X0A00    //101 = FSR is ±0.256 V

#define ADS1118_Continuous_MODE 0X0000    //0->Continuous
#define ADS1118_Sigle_SHOT_MODE 0X0100    //1->SIGNEL ADC

#define ADS1118_DR_8SPS         0X0000    //000 = 8 SPS
#define ADS1118_DR_16SPS        0X0020    //001 = 16 SPS
#define ADS1118_DR_32SPS        0X0040    //010 = 32 SPS
#define ADS1118_DR_64SPS        0X0060    //011 = 64 SPS
#define ADS1118_DR_128SPS       0X0080    //100 = 128 SPS (default)
#define ADS1118_DR_250SPS       0X00A0    //101 = 250 SPS
#define ADS1118_DR_470SPS       0X00C0    //110 = 475 SPS
#define ADS1118_DR_860SPS       0X00E0    //111 = 860 SPS

#define ADS1118_ADC_MODE        0x0000    //ADC MODE
#define ADS1118_Temp_MODE       0X0010    //Temperature sensor mode

#define ADS1118_PUUP_DIS        0X0000    //inside pullup disabled
#define ADS1118_PUUP_EN         0x0008    //inside pullup enabled

#define ADS1118_NOP_UPDATA      0X0002    //update the Config register
void ADS1118_ADC_Init(uint16_t channel,uint16_t PGA,uint16_t SPS);
void ADS1118_Temp_Init();
float ADS1118_Get_Tempture_Data();
float ADS1118_Get_ADC_SIGLE_SHOT_Data(uint16_t channel,uint16_t PGA,uint16_t SPS);
float  ADS1118_Get_ADC_Continuous_Data(uint16_t channel,uint16_t PGA,uint16_t SPS);
#endif


总结

读取情况。
在这里插入图片描述

在这里插入图片描述
https://download.youkuaiyun.com/download/hhhhwdnmd/88344063

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咕咕鸟bird

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值