STM32
直播中

周棠亨

7年用户 1038经验值
擅长:可编程逻辑 电源/新能源
私信 关注
[问答]

小白求助,求ADS1118的调试笔记

小白求助,求ADS1118的调试笔记

回帖(1)

何微微

2021-11-18 15:36:33
最近调试了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("rn");
}
#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
#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一样。。。。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分