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

    INA3221使用方法和INA226基本上一致,多了选择多通道读取,根据数据手册制定不一样的初始化代码。

    INA3221不能够直接读分流电阻的电流,但可以通过算得两端电压算出电流。

    上代码:

    INA3221.c:

    #include "INA3221.h"
    
    static void delay_nns_3221(uint16_t D)  //30纳秒ns  根据手册要用到IIC的HS高速模式
    {
        while(--D);
    }
    
    void delay_nms_3221(uint16_t ms)  //毫秒
    {
        uint16_t i;
        uint32_t M = 0;//720W
        for(i = 0;i < ms; i++)
        for(M=12000;M > 0;M--);
    }
    
    void delay_nus_3221(uint16_t us)//微秒
    {
        uint16_t i;
        uint16_t M = 0;//720W
        for(i = 0;i < us; i++)
        for(M=72;M > 0;M--);
    }
    /****************IIC***************************/
    void INA3221_IIC_Init(void)
    {
        GPIO_InitTypeDef GPIO_Initure;
        __HAL_RCC_GPIOB_CLK_ENABLE();   //使能GPIOB时钟
        
         //PC11,12初始化设置
        GPIO_Initure.Pin=GPIO_PIN_6|GPIO_PIN_7;//PB6SCL PB7SDA
        GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;  //推挽输出
        GPIO_Initure.Pull=GPIO_PULLUP;          //上拉
        GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;     //高速
        HAL_GPIO_Init(GPIOB,&GPIO_Initure);
        
        IIC_SDA_H_3221;
        IIC_SCL_H_3221;  
            delay_nms_3221(5);
    }
        
    void INA3221_IIC_Start(void)
    {
        IIC_SDA_H_3221;            
        IIC_SCL_H_3221;
        delay_nns_3221(5);
         IIC_SDA_L_3221;//START:when CLK is high,DATA change form high to low 
        delay_nns_3221(5);
        IIC_SCL_L_3221;//钳住I2C总线,准备发送或接收数据 
        delay_nns_3221(5);
    }    
    
    void INA3221_IIC_Stop(void)
    {
        IIC_SDA_L_3221;//STOP:when CLK is high DATA change form low to high
         delay_nns_3221(5);
        IIC_SCL_H_3221; 
            delay_nns_3221(5);
        IIC_SDA_H_3221;//发送I2C总线结束信号
        delay_nns_3221(5);                                   
    }
    
    void INA3221_IIC_Ack(void)
    {
        IIC_SDA_L_3221;
        delay_nns_3221(5);
        IIC_SCL_H_3221;
        delay_nns_3221(5);
        IIC_SCL_L_3221;
            delay_nns_3221(5);
        IIC_SDA_H_3221;
    }
    
    void INA3221_IIC_NAck(void)
    {
        IIC_SDA_H_3221;
        delay_nns_3221(5);
        IIC_SCL_H_3221;
    delay_nns_3221(5);
        IIC_SCL_L_3221;
        delay_nns_3221(5);
        IIC_SDA_L_3221;
    }        
    
    uint8_t INA3221_IIC_Wait_Ack(void)
    {
        uint8_t ucErrTime=0;
        //SDA_IN();      //SDA设置为输入  
        IIC_SDA_H_3221;
        delay_nns_3221(5);       
        IIC_SCL_H_3221;
        delay_nns_3221(5);          
        
        while(READ_SDA_3221)
        {
            ucErrTime++;
            if(ucErrTime>250)
            {
                INA3221_IIC_Stop();
                return 1;
            }
        }
        IIC_SCL_L_3221;//时钟输出0        
        return 0;  
    }
    
    void INA3221_IIC_Send_Byte(uint8_t txd)
    {                              
       IIC_SCL_L_3221;//拉低时钟开始数据传输
       for(uint8_t i = 0;i < 8;i++)
        {              
            if(txd&0x80)
                        IIC_SDA_H_3221;
                    else
                        IIC_SDA_L_3221;                
            txd<<=1;       
                    
            IIC_SCL_H_3221;
            delay_nns_3221(5);
            IIC_SCL_L_3221;
            delay_nns_3221(5);
        }            
        //    IIC_SDA_H_3221;
        //    IIC_SCL_H_3221;            //当去掉wait_ack时的时候添加
        //    delay_nns_3221(5);
            //IIC_SCL_L_3221;
    } 
    
    uint8_t INA3221_IIC_Read_Byte(unsigned char ack)
    {
          uint8_t TData=0,i;
        for(i=0;i<8;i++)
        {
            IIC_SCL_H_3221;
            delay_nns_3221(5);
            TData=TData<<1;
            //if(GPIOB->IDR& GPIO_IDR_IDR7)        //判断SDA是否为高
                if(SDA_READ_3221)
            {
                TData|=0x01;
            }
            IIC_SCL_L_3221;
            delay_nns_3221(5);
        }
            if(!ack)
                INA3221_IIC_NAck();
            else
                INA3221_IIC_Ack();
    //    IIC_SCL_L_3221;
    //    delay_nns_3221(5);
    //    IIC_SDA_L_3221;
    //    delay_nns_3221(5);                //ACK
    //    IIC_SCL_H_3221;
    //    delay_nns_3221(5);
    //    IIC_SCL_L_3221;
    //    delay_nns_3221(5);
    //    IIC_SDA_H_3221;
        return TData;
    }
    
    /**********************IIC_END*************************/
    
    void INA3221_Init(void)
    {
        INA3221_IIC_Init();
        //HAL_Delay(10);
    
        INA3221_SendData(0x82 ,CFG_REG_3221,0x8000);//软件复位
        INA3221_SendData(0x84 ,CFG_REG_3221,0x8000);
        HAL_Delay(10);
        INA3221_SendData(0x82 ,CFG_REG_3221,0x7127);//7127
        INA3221_SendData(0x84 ,CFG_REG_3221,0x7127);
    //    HAL_Delay(2);
    //    INA3221_SendData(0x82, 0x01, 0x00);
    //    INA3221_SendData(0x82, 0x03, 0x00);
    //    INA3221_SendData(0x82, 0x05, 0x00);
    //    INA3221_SendData(0x84, 0x01, 0x00);
    //    INA3221_SendData(0x84, 0x03, 0x00);
    //    INA3221_SendData(0x84, 0x05, 0x00);
    //
        }
    
    void INA3221_SendData(uint8_t addr,uint8_t reg,uint16_t data)
    {
        uint8_t temp = 0;
        INA3221_IIC_Start();
        INA3221_IIC_Send_Byte(addr);
        INA3221_IIC_Wait_Ack();
     
        INA3221_IIC_Send_Byte(reg);
        INA3221_IIC_Wait_Ack();
        
        temp = (uint8_t)(data>>8);
        INA3221_IIC_Send_Byte(temp);
        INA3221_IIC_Wait_Ack();
     
        temp = (uint8_t)(data&0x00FF);
        INA3221_IIC_Send_Byte(temp);
        INA3221_IIC_Wait_Ack();
        
        INA3221_IIC_Stop();
    }
    
    void INA3221_SetRegPointer(uint8_t addr,uint8_t reg)
    {
        INA3221_IIC_Start();
     
        INA3221_IIC_Send_Byte(addr);
        INA3221_IIC_Wait_Ack();
     
        INA3221_IIC_Send_Byte(reg);
        INA3221_IIC_Wait_Ack();
     
        INA3221_IIC_Stop();
    }
    
    uint16_t INA3221_ReadData(uint8_t addr)
    {
        uint16_t temp=0;
        INA3221_IIC_Start();
     
        INA3221_IIC_Send_Byte(addr+1);
        INA3221_IIC_Wait_Ack();
        
        temp = INA3221_IIC_Read_Byte(1);
        temp<<=8;    
        temp |= INA3221_IIC_Read_Byte(0);
        
        INA3221_IIC_Stop();
        return temp;
    }
    
    uint16_t INA3221_GetVoltage(uint8_t addr,uint8_t channel)
    {
        uint32_t temp=0;
        switch(channel)
        {
            case 1:INA3221_SetRegPointer(addr,0x02);break;
            case 2:INA3221_SetRegPointer(addr,0x04);break;
            case 3:INA3221_SetRegPointer(addr,0x06);break;
            default:break;
        }
        temp = INA3221_ReadData(addr);//printf("
     temp = %d",temp);
        if(temp&0x8000)    temp = ~(temp - 1);    
        return (uint16_t)temp;
    //    return (u16)temp;    
    }
    
    //40uV/bit
    uint16_t INA3221_GetShuntVoltage(uint8_t addr,uint8_t channel)
    {
        uint32_t temp=0;
        switch(channel)
        {
            case 1:INA3221_SetRegPointer(addr,0x01);break;
            case 2:INA3221_SetRegPointer(addr,0x03);break;
            case 3:INA3221_SetRegPointer(addr,0x05);break;
            default:break;
        }
        temp = INA3221_ReadData(addr);
        if(temp&0x8000)    temp = ~(temp - 1);    
        return (uint16_t)temp;    
    }
    
    //1mA/bit
    //long INA226_GetShunt_Current(u8 addr)
    //{
    //    long temp=0;
    //    INA226_SetRegPointer(addr,CUR_REG);
    //    temp = INA226_ReadData(addr);
    //    if(temp&0x8000)
    //    {
    //        temp = ~(temp - 1);
    //        temp = (u16)temp - 2 * (u16)temp;
    //    }
    //    return temp;
    //}
    View Code

    INA3221.h:

    #ifndef __INA3221_H
    #define __INA3221_H
     #include "main.h"
    
    
    #define     CFG_REG_3221             0x00        //
    #define     SV_REG_3221             0x01        //分流电压, 此处分流电阻为 0.1欧
    #define     BV_REG_3221             0x02        //总线电压
    #define     PWR_REG_3221         0x03        //电源功率
    #define     CUR_REG_3221        0x04        //电流
    #define     CAL_REG_3221         0x05        //校准,设定满量程范围以及电流和功率测数的 
    //#define     ONFF_REG         0x06        //屏蔽 使能 警报配置和转换准备就绪
    //#define     AL_REG             0x07        //包含与所选警报功能相比较的限定值
    #define     INA3221_GET_ADDR 0XFF        //包含唯一的芯片标识号
    #define       INA3221_ADDR1    0x80
    
    
    //IO操作
    #define IIC_SCL_H_3221   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET) //SCL H
    #define IIC_SCL_L_3221   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET) //SCL H
    #define IIC_SDA_H_3221   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET) //SDA_H
    #define IIC_SDA_L_3221  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET) //SDA_L
    #define READ_SDA_3221     HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7)  //输入SDA
    #define SDA_READ_3221  GPIOB->IDR& GPIO_IDR_IDR7 
     
    
    static void delay_nns_3221(uint16_t D);
    void delay_nms_3221(uint16_t ms) ;
        void delay_nus_3221(uint16_t us);
            void INA3221_IIC_Init(void);
                void INA3221_IIC_Start(void);
        void INA3221_IIC_Stop(void);
    void INA3221_IIC_Ack(void);
    void INA3221_IIC_NAck(void);
    uint8_t INA3221_IIC_Wait_Ack(void);
    void INA3221_IIC_Send_Byte(uint8_t txd);
    uint8_t INA3221_IIC_Read_Byte(unsigned char ack);
    void INA3221_Init(void);
        void INA3221_SendData(uint8_t addr,uint8_t reg,uint16_t data);
            void INA3221_SetRegPointer(uint8_t addr,uint8_t reg);
                uint16_t INA3221_ReadData(uint8_t addr);
                uint16_t INA3221_GetVoltage(uint8_t addr,uint8_t channel);
                uint16_t INA3221_GetShuntVoltage(uint8_t addr,uint8_t channel);
                    
                
     #endif
    View Code

  • 相关阅读:
    软件测试的重要性
    软件测试二三事
    白盒测试总结
    黑盒测试总结
    闰年测试以及非法输入的处理方法
    软件测试(3)-基于等价类划分的一个小例子
    第二周课堂小结以及习题思考
    软件测试人员的自身修养
    软件测试的目的和方法
    第七周学习笔记之灰盒测试
  • 原文地址:https://www.cnblogs.com/zjx123/p/12875290.html
Copyright © 2011-2022 走看看