IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32使用ADM1191实现多电源监控器 -> 正文阅读

[嵌入式]STM32使用ADM1191实现多电源监控器

STM32读取多个ADM1191电流电压,实现电源监控器
最近在通过STM32从多个ADM1191芯片中回读电压电流,踩坑不少,故做此简单记录。
一:芯片简介
1.主控芯片型号:STM32F405RGTX 高性能MCU,主频168MHZ,Cortex4-M4内核
2.ADM1191是一款集成电流检测放大器,可通过I2C接口传送的片内,12位模数转换器(ADC)提供数字电流和电压监控。内部电流检测放大器通过VCC引脚和感测引脚在电源路径中的感测电阻上的电压感测电压。
12位ADC可以测量检测电阻中看到的电流,以及VCC引脚上的电源电压。
行业标准I2C接口允许控制器从ADC读取电流和电压数据。测量可以由I2C命令或通过转换(CONV)引脚启动。 CONC引脚特别适用于同步多个ADM1191设备上的读取。或者,ADC可以连续运行,并且用户可以在需要时读取最新的转换数据。最多可以创建16个唯一的I2C地址,具体取决于A0引脚和A1引脚的方式连接。
器件I2C地址如下表:
在这里插入图片描述
二、电压电源回读
本实验用STM32与三个ADM1191采用I2C总线进行数据交换。
I2C协议常用信号这里不做记录。下面是读写ADM1191的读写控制时序:
在这里插入图片描述
发命令格式:
在这里插入图片描述
各位命令的含义:
在这里插入图片描述
这里是低七位,最高位控制其是发命令(MSB:0)还是向寄存器写入(MSB:1)
下面直接上程序:
1.采样控制引脚初始化:

void CONV_GPIO_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(CONV_GPIO_CLK,ENABLE);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_Pin =CONV_GPIO_PIN;
	GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_Init(CONV_GPIO_PORT,&GPIO_InitStructure);
	GPIO_ResetBits(CONV_GPIO_PORT,CONV_GPIO_PIN);	
}```c
void CONV_EN()
{
	GPIO_SetBits(CONV_GPIO_PORT,CONV_GPIO_PIN);
}
void CONV_DISABLE()
{
	GPIO_ResetBits(CONV_GPIO_PORT,CONV_GPIO_PIN);
}


2.过流过压引脚初始化:当发送过流过压现象是该引脚被置低

void ALERT_Pin_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(ALERT_ARM_GPIO_CLK|ALERT_OPTICAL_GPIO_CLK|ALERT_SAMPLE_GPIO_CLK,ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Pin =ALERT_ARM_GPIO_PIN |ALERT_OPTICAL_GPIO_PIN | ALERT_SAMPLE_GPIO_PIN;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}

3.配置ADM1191及回读电压电流:

/*设置ADM1191  ADC为连续转换*/
uint8_t adm1191_convert_con(uint8_t addr)
{
	i2c_Start();
	i2c_SendByte(addr|ADM1191_I2C_WR);
	if(i2c_WaitAck() != 0)
	{
		goto cmd_fail;
	}
	i2c_SendByte(0x05);
	if(i2c_WaitAck() != 0)
	{
		goto cmd_fail;
	}
	i2c_Stop();
	return 1;
	cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
	/* 发送I2C总线停止信号 */
	i2c_Stop();
	return 0;
}
/*设置ADM1191  ADC为单次转换*/
uint8_t adm1191_convert_once(uint8_t addr)
{
	i2c_Start();
	i2c_SendByte(addr|ADM1191_I2C_WR);
	if(i2c_WaitAck() != 0)
	{
		goto cmd_fail;
	}
	i2c_SendByte(0x05);
	if(i2c_WaitAck() != 0)
	{
		goto cmd_fail;
	}
	i2c_Stop();
	return 1;
	cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
	/* 发送I2C总线停止信号 */
	i2c_Stop();
	return 0;
}
/*从ADM1191读取电压电流*/
uint8_t adm1191_rd_VI(uint8_t *_pReadBuf,uint8_t addr)
{
	CONV_EN();
	delay_us(300);
	i2c_Start();
	i2c_SendByte(addr | ADM1191_I2C_RD);
	if (i2c_WaitAck() != 0)
	{
		goto cmd_fail;	/* EEPROM器件无应答 */
	}
	for(uint8_t i=0;i<3;i++)
	{		
			_pReadBuf[i] = i2c_ReadByte();
			if(i == 2)
			{
				i2c_NAck();
			}
			else
				i2c_Ack();	
	}
	i2c_Stop();
	CONV_DISABLE();
	return 1;
	
	cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
	/* 发送I2C总线停止信号 */
	i2c_Stop();
	return 0;
}

uint8_t Get_vi_from_1191(uint8_t addr,uint8_t *_pReadBuf,float *V,float * I)
{
	/*1.检查I2C设备*/
	int vcode,icode;
	uint8_t temp;
	if(Check_I2cdev_Ok(addr))
	{
		if(adm1191_convert_once(addr))
		{
			if(adm1191_rd_VI(_pReadBuf,addr))
			{
				temp=_pReadBuf[2];
				vcode=(_pReadBuf[0]<<4) | (_pReadBuf[2] >> 4);
				icode=(_pReadBuf[1]<<4)	|	(temp & 0x0F);
				*V=(26.52/4096)*vcode;
				*I=(105.84/4096)*icode/1000/0.01;
				return 1;
			}
			else
			{
				__485print_str("read VI failed\r\n");
				return 0;
			}	
		}
		else
		{
			__485print_str("config adm1191 failed\r\n");
			return 0;
		}
	}
	else
	{
		__485print_str("no find i2c device");
		return 0;
	}
}

使用定时器采样,2s采样一次,我使用的是基本定时器TIM6,定时器初始化过程略过,下面是定时器中断处理函数:

void TIM6_DAC_IRQHandler(void)
{
	if ( TIM_GetITStatus( BASIC_TIM, TIM_IT_Update) != RESET ) 
	{	
		/*监控arm电压电流*/
	if(Get_vi_from_1191(ADDRESS_ADM1191_ARM,V_ARM,&arm_v,&arm_i))
			{
					__485print_str("ARM供电电压 : ");	
					__485_print_float(arm_v);
					__485print_str("\r\n");
					__485print_str("ARM供电电流 : ");	
					__485_print_float(arm_i);
					__485print_str("\r\n");
			}
			else
			{
				__485print_str("get arm_v failed\r\n");
			}
			/*监控光源供电电压*/
if(Get_vi_from_1191(ADDRESS_ADM1191_OPTICAL,V_OPTICAL,&opt_v,&opt_i))
			{
				__485print_str("光源供电电压 : ");
				__485_print_float(opt_v);
				__485print_str("\r\n");
				__485print_str("光源供电电流 : ");
				__485_print_float(opt_i);
				__485print_str("\r\n");
			}
			else
			{
				__485print_str("get optical_v failed\r\n");
			}
			/*监控数采板供电电压*/
	if(Get_vi_from_1191(ADDRESS_ADM1191_SAMPLE,V_SAMPLE,&sam_v,&sam_i))
			{
					__485print_str("数采板供电电压 : ");
					__485_print_float(sam_v);
					__485print_str("\r\n");
					__485print_str("数采板供电电流 : ");
					__485_print_float(sam_i);
					__485print_str("\r\n");
			}
			else
			{
				__485print_str("get sample_v failed\r\n");
			}
		TIM_ClearITPendingBit(BASIC_TIM , TIM_IT_Update);  		 
	}		
}
主函数:
float arm_v,sam_v,opt_v;
/*用于存放转换后的真实电流值*/
float arm_i,sam_i,opt_i;

float temp4,temp5;
u16 temp4_adc,temp5_adc;
extern __IO uint16_t adc_value[2];
int main()
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组
	LED_GPIO_Config();	//初始化LED
	init_control_power_pin(); //上电使能引脚初始化
	CONV_GPIO_Config();	//ADM1191采样控制引脚初始化
	ALERT_Pin_Config();	//过流过压报警引脚初始化
	EXTI_Config();	//外部中断初始化
	TIMx_Configuration();	//电压电流采样定时器初始化
	delay_init(168);	//初始化延时
	_485_init(115200);	//485初始化
	while(1)
	{
			LED_TOGGLE;
			delay_ms(1000);
	}
}

三、烧写测试
测试结果
到此完结,第一次创作,不喜勿喷~~~~~~~~~~

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-07-09 17:37:02  更:2021-07-09 17:37:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 10:02:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计