前言
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