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