1. 程式人生 > >基於STM32F429的ADS1115驅動程式

基於STM32F429的ADS1115驅動程式

1.ADS1115中文資料:https://wenku.baidu.com/view/8bab101feef9aef8941ea76e58fafab069dc44e7.html?rec_flag=default&sxts=1557987780920

2.IIC協議程式

IIC協議是大多數感測的通訊協議,每個嵌入式工程師都要有自己的IIC底層協議

IIC可細分為7個函式

1.開始

2.讀取

3.傳送

4.結束

5.主機檢測從機應答

6. 主機應答

7. 主機不應答

/*******************************************************************************
* 
* 
*                          Protocol  Part
* 
* 
****************************************************************************** */



/*******************************************************************************
* Function Name  : vIIC_Start_Signal
* Description    : Master Send Start Signal
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void vIIC_Start_Signal(IIC_HandleTypedef * hIICx)
{
    
    IIC_SDA_1                    (hIICx);                        //拉高資料線    
    IIC_SCL_1                    (hIICx);                        //拉高時鐘線
    vIIC_Delay_2us        (            );                        //延時
    IIC_SDA_0                    (hIICx);                        //拉低資料線
    vIIC_Delay_2us        (            );                        //延時
    IIC_SCL_0                    (hIICx);                        //拉低時鐘線
    vIIC_Delay_2us        (            );                        //延時
}



/*******************************************************************************
* Function Name  : vIIC_SendByte
* Description    : Master Send a Byte to Slave
* Input          : Will Send Date
* Output         : None
* Return         : None
****************************************************************************** */
void vIIC_SendByte(IIC_HandleTypedef * hIICx,uint8_t uSendByte)
{    
    
        uint8_t i;
    
    for (i=0; i<8; i++)         
    {
                 if(uSendByte & 0X80)
                    IIC_SDA_1                (hIICx);
              else
                    IIC_SDA_0                (hIICx);
                uSendByte <<= 1;    
        vIIC_Delay_1us        (            );                             
        IIC_SCL_1                    (hIICx);              
        vIIC_Delay_2us        (            );                 
        IIC_SCL_0                    (hIICx);              
        vIIC_Delay_1us        (            );
                
    }
        
}



/*******************************************************************************
* Function Name  : uIIC_RecvByte
* Description    : Master Reserive a Byte From Slave
* Input          : None
* Output         : None
* Return         : Date From Slave 
****************************************************************************** */
uint8_t uIIC_RecvByte(IIC_HandleTypedef * hIICx)
{
    uint8_t i,uReceiveByte = 0;
    
    IIC_GPIO_MODE_Ipt (hIICx);
    IIC_SDA_1                    (hIICx);
    for(i=0;i<8;i++)
    {
        uReceiveByte <<= 1;
        
        vIIC_Delay_1us    (            );                
        IIC_SCL_1                (hIICx);        
        vIIC_Delay_1us    (            );        
        
        if(IIC_SDA_R        (hIICx))
        {
            uReceiveByte |=0x01;
        }
        
        vIIC_Delay_1us    (            );    
        IIC_SCL_0                (hIICx);
        vIIC_Delay_1us    (         );         
    }
    IIC_GPIO_MODE_Opt (hIICx);
    
    return uReceiveByte;
    
}



/*******************************************************************************
* Function Name  : vIIC_Ack
* Description    : Master Send Acknowledge Single
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void vIIC_Ack(IIC_HandleTypedef * hIICx)
{

    IIC_SDA_0                    (hIICx);                            //拉低資料位
    vIIC_Delay_1us        (            );                            //延時    
    IIC_SCL_1                    (hIICx);                            //拉高時鐘位
    vIIC_Delay_2us        (     );                            //延時
    IIC_SCL_0                    (hIICx);                            //拉低時鐘位
    vIIC_Delay_1us        (            );                            //延時
    
}



/*******************************************************************************
* Function Name  : vProto_IIC_NAck
* Description    : 
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void vIIC_NAck(IIC_HandleTypedef * hIICx)
{    
    
    IIC_SDA_1         (hIICx);                      //SDA拉高 不應答對方
    vIIC_Delay_1us        (            );
    IIC_SCL_1         (hIICx);
    vIIC_Delay_2us        (            );
    IIC_SCL_0         (hIICx);
    vIIC_Delay_1us        (            );
    
}



/*******************************************************************************
* Function Name  : bIIC_ReadACK
* Description    : Master Reserive Slave Acknowledge Single
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
bool bIIC_ReadACK(IIC_HandleTypedef * hIICx) //返回為:=1有ACK,=0無ACK
{                
    IIC_GPIO_MODE_Ipt (hIICx);
    IIC_SDA_1                    (hIICx);                            //拉高資料線
    vIIC_Delay_1us        (            );                            //延時
    IIC_SCL_1                    (hIICx);                    //拉高時鐘線
    vIIC_Delay_2us        (            );                            //延時
    
    if(IIC_SDA_R(hIICx))
    {
        vIIC_Delay_1us(            );
        IIC_SCL_0            (hIICx);
        vIIC_Delay_1us(            );
        IIC_GPIO_MODE_Opt(hIICx);
        return FALSE; // 沒有應答
    }
    else
    {
        vIIC_Delay_1us(            );
        IIC_SCL_0            (hIICx); 
        vIIC_Delay_1us(            );
        IIC_GPIO_MODE_Opt(hIICx);
        return TRUE;
    }    
            
}


/*******************************************************************************
* Function Name  : vIIC_Stop_Signal
* Description    : Master Send Stop Signal
* Input          : None
* Output         : None
* Return         : None
****************************************************************************** */
void vIIC_Stop_Signal(IIC_HandleTypedef * hIICx)
{

    IIC_SDA_0                                (hIICx);                //拉低資料線
    vIIC_Delay_2us                    (            );                //延時
    IIC_SCL_1                                (hIICx);                //拉高時鐘線
    vIIC_Delay_2us                    (            );                //延時
    IIC_SDA_1                                (hIICx);                //拉高資料線
  vIIC_Delay_2us                    (            );                //延時
    
}

3.暫存器操作

ADS1115的ADDR引腳接地,則暫存器地址為0x90

 

ADS1115的操作只有3步

1.向配置暫存器0x01寫入配置,先寫高8位,再寫低8位

void uSen_ADS1115_Confight(IIC_HandleTypedef * iicHandle)
{
    vIIC_Start_Signal(iicHandle);                                 //1.  IIC_Start                 ;  起始訊號                          
  vIIC_SendByte(iicHandle, Slave_Address);                            //2.  IIC_Send Device Address(W);  傳送裝置地址  0x90
                                                                                     
  bIIC_ReadACK(iicHandle);
    
  vIIC_SendByte(iicHandle, 0x01);                              //傳送暫存器地址  0x01
  bIIC_ReadACK(iicHandle);                                        
  vIIC_SendByte(iicHandle, 0xc0);                                     //具體如何配置看手冊
  bIIC_ReadACK(iicHandle);                                 
    vIIC_SendByte(iicHandle, 0x83);                       
  bIIC_ReadACK(iicHandle);    
  vIIC_Stop_Signal(iicHandle);                                
  
}

 

2. 寫入指標暫存器0x00,準備讀取電壓

void uSen_ADS1115_PointRegister(IIC_HandleTypedef * iicHandle, uint8_t Register_Address)
{
    vIIC_Start_Signal(iicHandle);                                 //1.  IIC_Start                 ;  起始訊號                          
  vIIC_SendByte(iicHandle, Slave_Address);                        //2.  IIC_Send Device Address(W);  傳送裝置地址  0x90
                                                                                         
     vIIC_Ack(iicHandle);    
    
    
  vIIC_SendByte(iicHandle, 0x00);                                //4.  IIC_Send Register Address ; 傳送要操作的暫存器地址
  vIIC_NAck(iicHandle);                                      
                          
  vIIC_Stop_Signal(iicHandle);                                   //9.  IIC_Stop                  ; 結束訊號
}

 

3.讀取電壓資料

float uSen_ADS1115_Read_Date(IIC_HandleTypedef * iicHandle)      
{
    uint8_t uRev_Register_Data_H = 0x00,uRev_Register_Data_L = 0x00;
  float  uRev_Register_Data = 0x00;
    
   
  vIIC_Start_Signal(iicHandle);                                      //1.  IIC_Start                 ;  起始訊號
  vIIC_SendByte(iicHandle,0x91);                                     //7.  I2C_Send Device Address(R); 傳送裝置地址+1 準備讀取
  vIIC_Ack(iicHandle);                                               //8.  I2C_Ack                   ; 等待應答
  uRev_Register_Data_H = uIIC_RecvByte(iicHandle);                   //9.  I2C_ReadByte              ; 讀取高位資料
  vIIC_Ack(iicHandle);                                                        
  uRev_Register_Data_L = uIIC_RecvByte(iicHandle);                   //9.  I2C_ReadByte              ; 讀取低位資料
  vIIC_NAck(iicHandle);                                                       
  
   //資料處理 
    vIIC_Stop_Signal(iicHandle);                                            
  uRev_Register_Data=uRev_Register_Data_H*256+uRev_Register_Data_L; //合取為16位資料
    
    if(uRev_Register_Data>=0x8000)  
     uRev_Register_Data=((float)(0xffff-uRev_Register_Data)/32767.0)*4.096;
  else
     uRev_Register_Data=((float)uRev_Register_Data/32768.0)*4.096;
; return uRev_Register_Data; }

 4. 資料處理

(16位資料/2的15次方)*量程

即(uRev_Register_Data/32768)*4.096

注意有電壓有正負

5.量程範圍

VCC+/-量程

比如 3.3v+/-4.096<