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\r\n",t1);//打印
            
                if(result == 0x7fff || result == 0x8000)
            {
                printf("已超量程!\r\n\r\n");
            }
            else
            {
                printf("讀取正常!\r\n\r\n");
            }    
        }
        
        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\r\n",t1); //打印
            
                if(result == 0x7fff || result == 0x8000) //超過最大值或者低於最小值
            {
                printf("已超量程!\r\n\r\n");
            }
            else
            {
                printf("讀取正常!\r\n\r\n");
            }    
        }    
        
        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\r\n",t1);//打印
            if(result == 0x7fff || result == 0x8000)
            {
                printf("已超量程!\r\n\r\n");
            }
            else
            {
                printf("讀取正常!\r\n\r\n");
            }
        }
        
        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("已超量程!\r\n\r\n");
            }
            else
            {
                printf("讀取正常!\r\n\r\n");
            }    
View Code

實際電路接法:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM