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(\"\\r\\n temp = %d\ 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 CodeINA3221.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