关于ADS1118的调试笔记(基于STM32)

最近调试了ADS1118芯片,单片机用的是STM32ZET6,用IO口模拟SPI通信,连接两片1118AD采集芯片,讲采集到的八通道数据在串口显示界面打印出来。 下面是.c代码

#include "ADS1118.h"
#include "sys.h"
#include "usart.h"
#include "led.h"
#include "delay.h"

/*
32-Bit模式下CS引脚可以一直保持为低,节省一个IO口。
32-Bit模式可以细分为两种,一种是把设置寄存器(16bit)写入两次,一种是写入一次后第二次(后16bit)写0。

16-Bit模式要求在每两次通信之间CS(片选)引脚要拉高一次。
每次通信可写入16bit的配置寄存器值和读取到16bit的转换寄存器值。
*/
#define INPUT  	PAin(4)				// 数据输入 , 连接芯片的OUT		
#define OUTPUT	PAout(5)			// 数据输出 , 连接芯片的DIN
#define CS  	PAout(6)			// 片选信号
#define SCK  	PAout(7)			// 时钟信号

#define CS1  	PAout(1)			// 片选1信号

u16 Conversion ;			// 存储从芯片读取的数据
float Voltage ;    			// 存储需要显示的测量电压值
float BaseV ;				// 采集电压的压基
u8 firstflag ;				// 第一次进入标志
u8 collect ;				// 每次采集的数据位置
float DP[8] ;				// 显示处理后的八通道数据

ConfigDef Config ;


void ADS1118GPIOInit(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;		// PA6作为片选输出信号,设置为推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
	GPIO_Init(GPIOA , &GPIO_InitStructure) ;
	GPIO_SetBits(GPIOA,GPIO_Pin_6);							// 片选初始化为高
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;		// PA5作为数据输出信号,初始设置为推挽输出		
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;
	GPIO_Init(GPIOA , &GPIO_InitStructure) ;
	GPIO_ResetBits(GPIOA,GPIO_Pin_5);						// 数据输出口初始化为低
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;		// PA7作为时钟信号,设置为推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;
	GPIO_Init(GPIOA , &GPIO_InitStructure) ;
	GPIO_ResetBits(GPIOA,GPIO_Pin_7);						// 时钟初始化为低
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;		// PA1作为片选1输出信号,设置为推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
	GPIO_Init(GPIOA , &GPIO_InitStructure) ;
	GPIO_SetBits(GPIOA,GPIO_Pin_1);							// 片选初始化为高
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD ;			// PA4作为数据输入信号,设置为下拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ;
	GPIO_Init(GPIOA , &GPIO_InitStructure) ;
	
}
											
// 当新数据准备好检索时,此引脚变为低电平
// 在连续转换模式下,如果未从器件中检索到任何数据,则DOUT / DRDY在下一个数据就绪信号(DOUT / DRDY为低电平)之前的8 μs再次变为高电平
/**********************************************************
函数名称:RWByte
函数功能:SPI发送接收数据
函数参数:需要配置的寄存器数据
函数返回:采集到的16位数据
函数隶属:Display
创建日期:2020/04/17  14:23
作    者:Jerry
注    解:
**********************************************************/
u16 RWByte(u16 DATA)
{
	u8 t ;
	u16 returndata ;
	delay_ms(1);
	for(t=0;t<16;t++)										
	{
		if(DATA&0x8000)				// 每次向从机写八位数据,芯片在时钟下降沿锁存DIN数据
		{
			OUTPUT = 1 ;
		}
		else
		{
			OUTPUT = 0 ;
		}
		DATA<<=1;
		SCK = 1 ;
		delay_ms(1);
		returndata<<=1;
		if(INPUT == 1)					// 每次读取从机中的八位数据,芯片在时钟上升沿将数据移出
		{
			returndata|=0x0001 ;
		}
		SCK = 0 ;
		delay_ms(1);
	}
	SCK = 0 ;
	delay_ms(1);
	OUTPUT = 0 ;
	
	return returndata ;
}

/**********************************************************
函数名称:ADS1118Init
函数功能:初始化时配置一些不常改变的寄存器值
函数参数:单次转换,工作模式,传输速率,上拉使能,更新数据
函数返回:无
函数隶属:main
创建日期:2020/04/17  14:23
作    者:Jerry
注    解:
**********************************************************/
void ADS1118Init(u8 ss,u8 mode ,u8 dr,u8 pue,u8 nop)
{
	Config.ConfigDef_T.SS = ss ;				// 设置为无效果
	Config.ConfigDef_T.MODE = mode ;			// 设置为连续转换模式
	Config.ConfigDef_T.DR = dr ;				// 设置转换速率为128 SPS
	Config.ConfigDef_T.PULL_UP_EN = pue ;		// 设置DOUT上拉使能
	Config.ConfigDef_T.NOP = nop ;				// 设置有效数据,更新配置寄存器
	Config.ConfigDef_T.CNV_RDY_FL = 0x01 ;		// 保留位,始终写1	
	
	Conversion = 0  ;			
	Voltage = 0  ;    			
	BaseV = 0  ;
	firstflag = 0 ;
}

/**********************************************************
函数名称:Getdata
函数功能:配置寄存器值并连续采集五次数据求平均值
函数参数:通道选择,工作模式,传输速率,上拉使能,更新数据
函数返回:无
函数隶属:main
创建日期:2020/04/17  14:23
作    者:Jerry
注    解:
**********************************************************/
void Getdata(u8 mux,u8 pga,u8 tsmode,u8 choose)
{
	float FV[10] ;			// 存储连续的五次转换数据
	u8 t ;
	float displaydata ;
	
	Config.ConfigDef_T.MUX = mux ;				// 设置为AIN0和GND
	Config.ConfigDef_T.PGA = pga ;				// 设置FSR=±4.096V
	Config.ConfigDef_T.TS_MODE = tsmode ;		// 设置温度传感器模式为ADC模式	
								
	switch (pga)
	{
		case 0 :
			BaseV = 187.5 ;						// 压基单位为uV
			break ;
		case 1 :
			BaseV = 125 ;
			break ;
		case 2 :
			BaseV = 62.5 ;
			break ;
		case 3 :
			BaseV = 31.25 ;
			break ;
		case 4 :
			BaseV = 15.625 ;
			break ;
		case 5 :
			BaseV = 7.8125 ;
			break ;
	}
	for(t=0;t<5;t++)
	{
		switch(choose)
		{
			case CS_0 :
				CS = 0 ;
				CS1 = 1 ;
				break;
			case CS_1 :
				CS = 1 ;
				CS1 = 0 ;
				break;
		}
		delay_ms(1);
		if((INPUT == 0)||(firstflag == 0))									// CS需要周期性拉低来检测是否有新的数据产生(检测INPUT引脚是否有低电平)							
		{
			Conversion = RWByte(Config.Bytes);
			Voltage = (BaseV*Conversion)/1000000 ;			// 转换单位:uV→V	
			Conversion = 0 ;							// 数据显示之后清零	
			firstflag = 1 ;
		}

		CS = 1 ;
		CS1 = 1 ;
		FV[t] = Voltage ;
		delay_ms(15);									// 延迟时间不能低于15ms
	}
	displaydata = (FV[1]+FV[2]+FV[3]+FV[4] )/4;
	if(choose == CS_0)
	{
		switch(mux)
		{
			case ADS1118_MUX_0G:
				DP[0] = displaydata ;
				break ;
			case ADS1118_MUX_1G:
				DP[1] = displaydata ;
				break ;
			case ADS1118_MUX_2G:
				DP[2] = displaydata ;
				break ;
			case ADS1118_MUX_3G:
				DP[3] = displaydata ;
				break ;
		}
	}
	else if(choose == CS_1)
	{
		switch(mux)
		{
			case ADS1118_MUX_0G:
				DP[4] = displaydata ;
				break ;
			case ADS1118_MUX_1G:
				DP[5] = displaydata ;
				break ;
			case ADS1118_MUX_2G:
				DP[6] = displaydata ;
				break ;
			case ADS1118_MUX_3G:
				DP[7] = displaydata ;
				break ;	
		}
	}

}

void dayin(void)
{
	u8 x ;
	printf("采集到的数据为 =  ");
	for(x=0;x<8;x++)
	{
		printf("%3.3f ",DP[x]);
	}
	printf("\r\n");
}

/*********************************************/
下面是.h代码

#ifndef __ADS1118_H
#define __ADS1118_H

#include "sys.h"


/**单次转换启动**/
#define ADS1118_SS_NONE  0		// 无效
#define ADS1118_SS_ONCE  1		// 启动单次转换

/**输入多路复用器配置**/
#define ADS1118_MUX_01	0		// 000 = AINP 为 AIN0 且 AINN 为 AIN1(默认)
#define ADS1118_MUX_03	1		// 000 = AINP 为 AIN0 且 AINN 为 AIN3
#define ADS1118_MUX_13	2		// 000 = AINP 为 AIN1 且 AINN 为 AIN3
#define ADS1118_MUX_23	3		// 000 = AINP 为 AIN2 且 AINN 为 AIN3
#define ADS1118_MUX_0G	4		// 000 = AINP 为 AIN0 且 AINN 为 GND
#define ADS1118_MUX_1G	5		// 000 = AINP 为 AIN1 且 AINN 为 GND
#define ADS1118_MUX_2G	6		// 000 = AINP 为 AIN2 且 AINN 为 GND
#define ADS1118_MUX_3G	7		// 000 = AINP 为 AIN3 且 AINN 为 GND

/**可编程增益放大器配置**/
#define ADS1118_PGA_61  0		// 000 = FSR 为 ±6.144V
#define ADS1118_PGA_40  1		// 001 = FSR 为 ±4.096V
#define ADS1118_PGA_20  2		// 010 = FSR 为 ±2.048V(默认)
#define ADS1118_PGA_10  3		// 011 = FSR 为 ±1.024V
#define ADS1118_PGA_05  4		// 100 = FSR 为 ±0.512V
#define ADS1118_PGA_02  5		// 101 = FSR 为 ±0.256V

/**器件工作模式配置**/
#define ADS1118_MODE_LX  0		// 连续转换模式
#define ADS1118_MODE_DC  1 		// 断电并采用单次转换模式(默认)

/**数据传输速率**/
#define ADS1118_DR_8      0		// 000 = 8SPS
#define ADS1118_DR_16     1		// 001 = 16SPS
#define ADS1118_DR_32     2		// 010 = 32SPS
#define ADS1118_DR_64     3		// 011 = 64SPS
#define ADS1118_DR_128    4		// 100 = 128SPS(默认)
#define ADS1118_DR_250    5		// 101 = 250SPS
#define ADS1118_DR_475    6		// 110 = 475SPS
#define ADS1118_DR_860    7		// 111 = 860SPS

/**温度传感器模式**/
#define ADS1118_TS_MODE_ADC		0		// 0 = ADC 模式(默认)
#define ADS1118_TS_MODE_T		1		// 1 = 温度传感器模式

/**上拉使能**/
#define ADS1118_PULL_UP_EN_N	0		// 禁用 DOUT/DRDY 引脚的上拉电阻
#define ADS1118_PULL_UP_EN_E	1		// 使能 DOUT/DRDY 引脚的上拉电阻(默认)

/**控制数据是否写入配置寄存器**/
#define ADS1118_NOP_N	0		// 00 = 无效数据, 不更新配置寄存器内容
#define ADS1118_NOP_W	1		// 01 = 有效数据, 更新配置寄存器(默认)

/**保留**/
#define ADS1118_CNV_RDY_FL    1		    // 始终写入 1h


/***************************定义ADS1118中的四个16位寄存器********************************/
typedef union
{
	struct
	{
		u16 CNV_RDY_FL 	: 1 ; 			// [0]		转换完成标志
		u16 NOP			: 2 ; 			// [1:2]	无操作
		u16 PULL_UP_EN 	: 1 ; 			// [3]		上拉使能
		u16 TS_MODE 	: 1 ; 			// [4]		温度传感器模式
		u16 DR 			: 3 ;      		// [7:5]	数据传输速率
		u16 MODE 		: 1 ;     		// [8]		设备运行模式
		u16 PGA 		: 3 ;     		// [11:9]	可编程增益放大器配置
		u16 MUX 		: 3 ;     		// [14:12]	输入多路复用器配置
		u16 SS 			: 1 ;     		// [15]		操作状态或单次转换开始
	}
	ConfigDef_T ;
	u16 Bytes ;
}
ConfigDef ;

typedef enum
{
	CS_0 = 0 ,
	CS_1
}
chipselect;

/***************************声明ADS1118中的四个16位寄存器********************************/
extern ConfigDef Config ;




void ADS1118GPIOInit(void);
void ADS1118Init(u8 ss,u8 mode ,u8 dr,u8 pue,u8 nop) ;
void Getdata(u8 mux,u8 pga,u8 tsmode,u8 choose) ;
void dayin(void);

#endif

/*********************************************/
最后是main函数代码

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "ADS1118.h"




int main(void)
{	
	delay_init();	    //延时函数初始化	  
	LED_Init();		  	//初始化与LED连接的硬件接口
	 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	uart_init(115200);
	 
	ADS1118GPIOInit();
	ADS1118Init(ADS1118_SS_NONE,ADS1118_MODE_LX,ADS1118_DR_128,ADS1118_PULL_UP_EN_E,ADS1118_NOP_W);	
	
	while(1)
	{
		Getdata(ADS1118_MUX_0G,ADS1118_PGA_40,ADS1118_TS_MODE_ADC,CS_0);
		
		Getdata(ADS1118_MUX_1G,ADS1118_PGA_40,ADS1118_TS_MODE_ADC,CS_0);
		
		Getdata(ADS1118_MUX_2G,ADS1118_PGA_40,ADS1118_TS_MODE_ADC,CS_0);
		
		Getdata(ADS1118_MUX_3G,ADS1118_PGA_40,ADS1118_TS_MODE_ADC,CS_0);
		
		Getdata(ADS1118_MUX_0G,ADS1118_PGA_40,ADS1118_TS_MODE_ADC,CS_1);
		
		Getdata(ADS1118_MUX_1G,ADS1118_PGA_40,ADS1118_TS_MODE_ADC,CS_1);
		
		Getdata(ADS1118_MUX_2G,ADS1118_PGA_40,ADS1118_TS_MODE_ADC,CS_1);
		
		Getdata(ADS1118_MUX_3G,ADS1118_PGA_40,ADS1118_TS_MODE_ADC,CS_1);
//		LED1 = !LED1 ;
		dayin();
		
	}
}

关于ADS1118的调试笔记(基于STM32)_第1张图片
只给了第一芯片的2引脚和第二芯片的3引脚外接了电位器,其余引脚都为悬空状态。。。。。。。。。。。。。。。。。。。。。。。。
说明:
1,芯片OUT引脚到单片机的输入引脚接的是1K电阻,其余三个引脚都是按照参考手册给的50Ω限流电阻
2,ADS1118.c里面采集数据里有个延时15ms,改小的话会出现错码,不晓得啥原因
3,写与读同时进行的情况下,读到的是上一次配置的数据,所以我在程序里遍历了五遍,摘除第一次的数据后,取后四次的数据求平均值输出显示。。。。。。。。。。。。。。。。。。。。。。。。
第一次发博,格式什么的不管了,希望有用。。。。。。。反正读别人的程序跟吃X一样。。。。

你可能感兴趣的:(关于ADS1118的调试笔记(基于STM32))