zoukankan      html  css  js  c++  java
  • ADS1115的使用教程(IIC)

    ADS1115可以测量ADC,能够测量单端对地电压和差分对输入的电压,测量范围是0-6V。

    上代码:

    main.c:

    #include "led.h"
    #include "delay.h"
    #include "sys.h"
    #include "usart.h"
    #include "lcd.h"
    #include "key.h"  
    #include "ads1115.h"
    
    float aa;    
    
     int main(void)
     { 
         float t1; 
       u16 t,result;
         u8 key;
         u16 i=0;
    
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
        delay_init();             
        uart_init(9600);         //串口初始化为9600
        LED_Init();                  
         //LCD_Init();    
        KEY_Init();                 
            //IIC初始化 
        ADS1115_Init();
      
        while(1)
        {
            key=KEY_Scan(0);
            if(key==WKUP_PRES)
            {                
              result=lvbo(0xeb,0x82);    //A0 A1为差分输入测试端  低八位+高八位1111 1011,1000 0010
                
                if(result >= 0x8000 && result <= 0xffff)
                    result = 0xffff - result;   //差值为负取绝对值,使得A0 A1正反接都行
                 else if(result >= 0xffff)
                    result = 0;
                
              t1=4.096*2*result/65535;     //转换成电压
        
                printf("量程为4.096V,A0-A1之间电压 = %f V
    ",t1);//打印
                
                    if(result == 0x7fff || result == 0x8000)
                {
                    printf("已超量程!
    
    ");
                }
                else
                {
                    printf("读取正常!
    
    ");
                }    
            }
            
            if(key==KEY0_PRES)
            {                 
              result=lvbo(0xe3,0xb2); //A2 A3为差分输入测试端  低八位+高八位 1111 0011,1011 0010
                
                
                if(result >= 0x8000)
                    result = 0xffff - result; //差值为负取绝对值,使得A2 A3正反接都行
                
                
              t1=4.096*2*result/65535;     //转换成电压
                
                printf("量程为4.096V,A2-A3之间电压 = %f V
    ",t1); //打印
                
                    if(result == 0x7fff || result == 0x8000) //超过最大值或者低于最小值
                {
                    printf("已超量程!
    
    ");
                }
                else
                {
                    printf("读取正常!
    
    ");
                }    
            }    
            
            if(key == KEY1_PRES)
            {
                      result=lvbo(0xe3,0xb4);    //A2 A3为差分输入测试端 低八位+高八位 1111 0011,1011 0100
                
                if((result >= 0x8000) && (result <= 0xffff))
                    result = 0xffff - result;   //差值为负取绝对值,使得A0 A1正反接都行
                 else if(result >= 0xffff)
                    result = 0;
              t1=2.048*2*result/65535;     //转换成电压
                
                printf("量程为2.048V,A0-A1之间电压 = %f V
    ",t1);//打印
                if(result == 0x7fff || result == 0x8000)
                {
                    printf("已超量程!
    
    ");
                }
                else
                {
                    printf("读取正常!
    
    ");
                }
            }
            
            i++;
            delay_ms(10);
            if(i==20)
            {
                LED0=!LED0;//提示系统正在运行    
                i=0;
                }           
        }
    }
    View Code

    ADS1115.c:

    #include "sys.h"
    #include "stm32f10x_i2c.h"
    #include "ads1115.h"
    
    static void ADS1115_delay(u16 D)
    {
        while(--D);
    }
    
    void delay_nms(u16 ms)
    {
        u16 i;
        u32 M = 0;//720W
        for(i = 0;i < ms; i++)
        for(M=12000;M > 0;M--);
    }
    
    void delay_nus(u16 us)
    {
        u16 i;
        u16 M = 0;//720W
        for(i = 0;i < us; i++)
        for(M=72;M > 0;M--);
    }
    
    
    
    /////////////////PA8 SDA////PA9 SCL///////////////////////////////////
    void ADS1115_Init(void)
    {
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC ,ENABLE);
    
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;//A SCL SDA
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
    
        SDA_A1;
        SCL_A1;
        delay_nms(5);
    
    }
    
    //I2C总线启动
    void I2CStart_A(void)
    {
       SDA_A1;
       ADS1115_delay(5);
       SCL_A1;
       ADS1115_delay(5);
       SDA_A0;
       ADS1115_delay(5);//MIN 160ns
       SCL_A0;
       ADS1115_delay(5);
    }
    
    //I2C停止总线
    void I2CStop_A(void)
    {
       SDA_A0;
       ADS1115_delay(5);
       SCL_A1;
       ADS1115_delay(5);
       SDA_A1;
       ADS1115_delay(5);//MIN 160ns
    }
    
    //I2C 写一字节
    void I2CWriteByte_A(u8 DATA)
    {
          u8 i;
          SCL_A0;
          for(i = 0;i < 8; i++)
          {
             if(DATA&0x80)
             {
                  SDA_A1;
             }
             else
             {
                  SDA_A0;
             }
             SCL_A1;//按照手册不需延时
             ADS1115_delay(5);
             SCL_A0;
             ADS1115_delay(5);
             DATA    = DATA << 1;  
          }
          SDA_A1;
          SCL_A1;
          ADS1115_delay(5);
          SCL_A0;
    }
    
    
    //I2C 读一字节
    u8 I2CReadByte_A(void)
    {
        u8 TData=0,i;
        for(i=0;i<8;i++)
        {
            SCL_A1;
            ADS1115_delay(5);
            TData=TData<<1;
            if(SDA_AI)
            {
                TData|=0x01;
            }
            SCL_A0;
            ADS1115_delay(5);
        }
        SCL_A0;
        ADS1115_delay(5);
        SDA_A0;
        ADS1115_delay(5);
        SCL_A1;
        ADS1115_delay(5);
        SCL_A0;
        ADS1115_delay(5);
        SDA_A1;
        return TData;
    }
    
    
    
    /*********************************************************************
    *函数名称:  ADS1115Config
    *描       述: 设置ADS1115包括通道配置,采样时间等等
    *参       数: HCMD :命令字高8位(通道,量程,转换模式)
                LCMD : 命令字低8位(采样率设置 比较模式 有效电平 信号输出锁存)
    *返       回; 无
    ********************************************************************/
    void ADS1115Config_A(u8 LCMD,u8 HCMD)
    {
        u8 i=0;
        u8 Initdata[4];
    
        Initdata[0] = 0x90;  // 地址0x90  器件ADR接地 写寄存器
        Initdata[1] = 0x01;// 配置寄存器
        Initdata[2] = HCMD;    // 配置字高字节
        Initdata[3] = LCMD;    // 配置字低字节
        SCL_A1;
        I2CStart_A();        //开启
        for(i=0;i<4;i++)
        {
            I2CWriteByte_A(Initdata[i]);
            ADS1115_delay(10);
        }
        I2CStop_A();         //关闭
    }
    
    void SetThresHold_A(u16 L_TH,u16 H_TH)        //高低阀门设置
    {
       SCL_A1;
       I2CStart_A();      // 开启
       I2CWriteByte_A(0x90);
       I2CWriteByte_A(0x02);//最低阀值寄存器
       I2CWriteByte_A((L_TH>>8));
       I2CWriteByte_A(L_TH);
       I2CStop_A();       //关闭
    
       I2CStart_A();     //开启
       I2CWriteByte_A(0x90);
       I2CWriteByte_A(0x03);//最高阀值寄存器
       I2CWriteByte_A((H_TH>>8));
       I2CWriteByte_A(H_TH);
       I2CStop_A();      //关闭
    }
    
    
    /*******************************************************************
    *函数名称:  ReadAD_A
    *描       述: 获取AD转换的值
    *参       数: 获取的值为在前面设置的那个通道
    *返       回; 无
    ********************************************************************/
    u16 ReadAD_A(void)
    {
       u16 Data[2]={0,0};
    //转换指向寄存器
       SCL_A1;
       I2CStart_A();
       I2CWriteByte_A(0x90);
       I2CWriteByte_A(0x00);
       I2CStop_A();                        
       
       I2CStart_A();
       I2CWriteByte_A(0x91);
       Data[0] = I2CReadByte_A();
       Data[1] = I2CReadByte_A();
       I2CStop_A();
       
       Data[0] = Data[0]<<8 | Data[1];
       return  (Data[0]);//&0x7fff
    }
    
    u16 getad(u8 LCMD,u8 HCMD)
    {
       u16 value=0;
        ADS1115Config_A(LCMD,HCMD);          //配置通道
            
        delay_nms(5); // 延时一定时间,防止通道切换互相影响        
        value=ReadAD_A();
        return value;
    }
    
    u16 lvbo(u8 LCMD,u8 HCMD)        //求30个值的平均值
    {
        u8 k;
        u32 U=0, temp;   //u32 给够叠加空间 或者float、double亦可 
        for(k=0;k<30;k++)
        {
            U+=getad(LCMD,HCMD);    
        }
        temp=U;
            U=0;
        return ((float)temp/30);    //带上小数点
    }
    View Code

    ADS1115.h:

    #ifndef  __ADS115_H_
    #define  __ADS115_H_
    #include "sys.h"
     
    
    /***************************************************************************************
    *说明:当端输入时候正输入为输入信号,负输入为地但是输入信号不能为负电压(不能比地电位低)
    *       双端输入时候正输入为输入信号,负输入为负输入输入信号的差值可以为负电压
    ****************************************************************************************/
    #define     SDA_A1     PCout(11)=1   //SDA输出
    #define     SDA_A0     PCout(11)=0
    #define     SCL_A1        PCout(12)=1    //SCL
    #define     SCL_A0        PCout(12)=0
    #define     SDA_AI        PCin(11)   //SDA读入
    
    //#define     SDA_A21     PAout(10)=1   //SDA输出
    //#define     SDA_A20     PAout(10)=0
    //#define     SCL_A21       PAout(11)=1    //SCL
    //#define     SCL_A20       PAout(11)=0
    //#define     SDA_A2I       PAin(10)   //SDA读入
    
    //#define     SDA_A31     PBout(10)=1   //SDA输出
    //#define     SDA_A30     PBout(10)=0
    //#define     SCL_A31       PBout(11)=1    //SCL
    //#define     SCL_A30       PBout(11)=0
    //#define     SDA_A3I       PBin(10)   //SDA读入
    
    //#define     SDA_A41     PBout(12)=1   //SDA输出
    //#define     SDA_A40     PBout(12)=0
    //#define     SCL_A41       PBout(13)=1    //SCL
    //#define     SCL_A40       PBout(13)=0
    //#define     SDA_A4I       PBin(12)   //SDA读入
    
    //I2C地址以及读写设置
    #define  WR_REG 0x90       //写寄存器
    #define  RE_REG 0x91       //读寄存器
    
    /***********************************寄存器控制字**********************************************/
    #define  DATA_REG  0x00        //转换数据寄存器
    #define  CONF_REG  0x01     //控制字设置寄存器
    #define  LOTH_REG  0x02        //最低阀值寄存器
    #define  HITH_REG  0x03        //最高阀值寄存器
    
    #define  ch0  0xc0       //通道0
    #define  ch1  0xd0       //通道1
    #define  ch2  0xe0       //通道2
    #define  ch3  0xf0       //通道3
    
    /***********************控制字申明*************************************************************
    *|  OS | MUX2 | MUX1 | MUX0 | PGA2 | PGA1 | PGA0 | MODE  |------HCMD
    *|  DR2| DR1  | DR0  | COMP_MODE | COMP_POL | COMP_LAT |  COMP_QUE1 | COMP_QUE0 |-----LCMD
    ***********************************************************************************************/
    #define  HCMD1    0x64   //AIN0单端输入 +-4.096量程  连续模式  01000100b
    #define  LCMD1      0xf0     //860sps 窗口比较器模式 输出低有效  不锁存信号至读 每周期检测阀值 11110000b
    
    /************************函数申明****************************/
    static void ADS1115_delay(u16 D);
    void delay_nms(u16 ms);
    void delay_nus(u16 us);
    void ADS1115_Init(void);
    void I2CStart_A(void);
    void I2CStop_A(void);
    void I2CWriteByte_A(u8 DATA);
    u8 I2CReadByte_A(void);
    void ADS1115Config_A(u8 LCMD,u8 HCMD);
    void SetThresHold_A(u16 L_TH,u16 H_TH);        //高低阀门设置
    u16 ReadAD_A(void);
    u16 getad(u8 LCMD,u8 HCMD);
    u16 lvbo(u8 LCMD,u8 HCMD);
    
    
    
    
    
    #endif        
    View Code

    判断量程高低由数据手册寄存器决定。

     程序实现:

        if(result == 0x7fff || result == 0x8000)
                {
                    printf("已超量程!
    
    ");
                }
                else
                {
                    printf("读取正常!
    
    ");
                }    
    View Code

    实际电路接法:

  • 相关阅读:
    数据库的视图概念作用
    常见的反爬虫和应对方法
    referrer policy
    JSON
    异步消息处理机制
    Acitivity(活动)
    springboot @Autowired 空指针异常问题处理
    CentOS7 宝塔 ThinkPHP SQLServer 2000 安装FreeTDS
    PHP THINKPHP 函数 dump var_dump var_export
    ThinkPHP5 WHERE AND OR 实现多条件查询
  • 原文地址:https://www.cnblogs.com/zjx123/p/12875807.html
Copyright © 2011-2022 走看看