SGM58031与单片机驱动实现

news2024/11/16 1:28:06

SGM58031与单片机驱动实现


文章目录

  • SGM58031与单片机驱动实现
  • CUBEIDE设置
  • I2C通讯封装
  • SGM58031通讯实现


CUBEIDE设置

在这里插入图片描述
使用硬件I2C与sgm芯片通讯,上面即配置硬件I2C,其他参数默认即可。

I2C通讯封装

封装实现

/**
  * @brief  Manages error callback by re-initializing I2C.
  * @param  Addr: I2C Address
  * @retval None
  */
static void I2Cx_Error(uint8_t Addr)
{
	/* 恢复I2C寄存器为默认值 */
	HAL_I2C_DeInit(&hi2c1);
	/* 重新初始化I2C外设 */
	MX_I2C1_Init();
}
/**
  * @brief  写寄存器,这是提供给上层的接口
    * @param  slave_addr: 从机地址
    * @param     reg_addr:寄存器地址
    * @param len:写入的长度
    *    @param data_ptr:指向要写入的数据
  * @retval 正常为0,不正常为非0
  *   HAL_OK       = 0x00U,
	  HAL_ERROR    = 0x01U,
	  HAL_BUSY     = 0x02U,
	  HAL_TIMEOUT  = 0x03U
  */
int smg58031_i2c_writeregister(uint8_t slave_addr,
                                        uint8_t reg_addr,
                                        uint8_t len,
                                        uint8_t *data_ptr)
{
    HAL_StatusTypeDef status = HAL_OK;
    status = HAL_I2C_Mem_Write(&hi2c1, slave_addr, reg_addr, I2C_MEMADD_SIZE_8BIT,data_ptr, len,I2Cx_FLAG_TIMEOUT);
    /* 检查通讯状态 */
    if(status != HAL_OK)
    {
        /* 总线出错处理 */
        I2Cx_Error(slave_addr);
    }
    while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
    {

    }
    /* 检查SENSOR是否就绪进行下一次读写操作 */
    while (HAL_I2C_IsDeviceReady(&hi2c1, slave_addr, I2Cx_FLAG_TIMEOUT, I2Cx_FLAG_TIMEOUT) == HAL_TIMEOUT);
    /* 等待传输结束 */
    while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
    {

    }
    return status;
}

/**
  * @brief  读寄存器,这是提供给上层的接口
    * @param  slave_addr: 从机地址
    * @param     reg_addr:寄存器地址
    * @param len:要读取的长度
    *    @param data_ptr:指向要存储数据的指针
  * @retval 正常为0,不正常为非0
  */
int smg58031_i2c_readregister(uint8_t slave_addr,
                                        uint8_t reg_addr,
                                        uint8_t len,
                                        uint8_t *data_ptr)
{
    HAL_StatusTypeDef status = HAL_OK;
    status =HAL_I2C_Mem_Read(&hi2c1,slave_addr,reg_addr,I2C_MEMADD_SIZE_8BIT,data_ptr,len,I2Cx_FLAG_TIMEOUT);
    /* 检查通讯状态 */
    if(status != HAL_OK)
    {
        /* 总线出错处理 */
        I2Cx_Error(slave_addr);
    }
    while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
    {

    }
    /* 检查SENSOR是否就绪进行下一次读写操作 */
    while (HAL_I2C_IsDeviceReady(&hi2c1, slave_addr, I2Cx_FLAG_TIMEOUT, I2Cx_FLAG_TIMEOUT) == HAL_TIMEOUT);
    /* 等待传输结束 */
    while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY)
    {

    }
    return status;
}

对应头文件


#define I2Cx_FLAG_TIMEOUT             ((uint32_t) 1000) //0x1100
#define I2Cx_LONG_TIMEOUT             ((uint32_t) (300 * I2Cx_FLAG_TIMEOUT)) //was300
/**
  * @brief  读寄存器,这是提供给上层的接口
    * @param  slave_addr: 从机地址
    * @param     reg_addr:寄存器地址
    * @param len:要读取的长度
    *    @param data_ptr:指向要存储数据的指针
  * @retval 正常为0,不正常为非0
  */
int smg58031_i2c_readregister(uint8_t slave_addr,
                                        uint8_t reg_addr,
                                        uint8_t len,
                                        uint8_t *data_ptr);
/**
  * @brief  写寄存器,这是提供给上层的接口
    * @param  slave_addr: 从机地址
    * @param     reg_addr:寄存器地址
    * @param len:写入的长度
    *    @param data_ptr:指向要写入的数据
  * @retval 正常为0,不正常为非0
  */
int smg58031_i2c_writeregister(uint8_t slave_addr,
                                        uint8_t reg_addr,
                                        uint8_t len,
                                        uint8_t *data_ptr);

这段代码是一个用于操作 I2C 总线的函数库。下面是对代码的详细分析:

I2Cx_Error 函数:

该函数用于处理 I2C 错误回调,通过重新初始化 I2C 外设来恢复错误。
首先,使用 HAL_I2C_DeInit 函数将 I2C1 外设的寄存器恢复为默认值。
然后,调用 MX_I2C1_Init 函数重新初始化 I2C1 外设。
smg58031_i2c_writeregister 函数:

这个函数用于向从机设备写入寄存器数据。
函数参数包括从机地址 slave_addr,寄存器地址 reg_addr,要写入的数据长度 len,以及指向要写入数据的指针 data_ptr。
首先,定义一个 HAL_StatusTypeDef 类型的变量 status 并初始化为 HAL_OK。
然后,调用 HAL_I2C_Mem_Write 函数向从机设备写入数据。
接下来,检查通信状态,如果状态不是 HAL_OK,则调用 I2Cx_Error 函数处理总线错误。
然后,使用 HAL_I2C_GetState 函数等待 I2C 状态变为 HAL_I2C_STATE_READY,表示传输完成。
继续使用 HAL_I2C_IsDeviceReady 函数等待从机设备准备就绪。
最后,再次使用 HAL_I2C_GetState 函数等待 I2C 状态变为 HAL_I2C_STATE_READY,确保传输结束。
最后,函数返回 status。
smg58031_i2c_readregister 函数:

这个函数用于从从机设备读取寄存器数据。
函数参数与 smg58031_i2c_writeregister 函数类似。
首先,定义一个 HAL_StatusTypeDef 类型的变量 status 并初始化为 HAL_OK。
然后,调用 HAL_I2C_Mem_Read 函数从从机设备读取数据。
接下来,检查通信状态,如果状态不是 HAL_OK,则调用 I2Cx_Error 函数处理总线错误。
然后,使用 HAL_I2C_GetState 函数等待 I2C 状态变为 HAL_I2C_STATE_READY,表示传输完成。
继续使用 HAL_I2C_IsDeviceReady 函数等待从机设备准备就绪。
最后,再次使用 HAL_I2C_GetState 函数等待 I2C 状态变为 HAL_I2C_STATE_READY,确保传输结束。
最后,函数返回 status。
总体而言,这段代码是一个简单的 I2C 总线操作函数库,提供了向从机设备写入寄存器数据和从从机设备读取寄存器数据的功能。在传输数据之前和之后,对通信状态进行了检查,并在出现错误时重新初始化 I2C 外设。

SGM58031通讯实现

头文件

#define I2C_ADC_ADDR 				0x90		//adc模块的写地址
//#define I2C_ADC_ADDR				0x91		//adc模块的读地址


//输入电压 = AINP-AINN    默认AINP=AIN0 AINN=AIN1
//输出数据速率  = 100HZ,即10ms更新一次数据
/* SGM58031内部寄存器地址 */
#define Conversion_Register      0x00    //AD值转换寄存器,16bit数据,默认值0x0000,只读
#define Config_Register          0x01    //配置寄存器,默认0x8583,可读可写
#define Lo_Thresh_Register       0x02    //比较器阈值下限,默认0x8000
#define Hi_Thresh_Register       0x03    //比较器阈值上限,默认0x7FFF
#define Config1_Register         0x04    //扩展配置寄存器,默认0x0000
#define ChipID_Register          0x05    //芯片ID,默认0x0080
#define GN_Trim1_Register        0x06    //增益修正,默认0x03FA

extern uint8_t control_flag ;
void set_adc_control(void);


extern uint16_t smg58031_Data_index;//用于保存当前写入数据的索引	0~100	存ADC采采样值用

int read_adc_value(void);

通讯实现

uint8_t control_flag = 0;

void set_adc_control(void){
	int i = 1;
	uint8_t value_Config[2] = {0};
	uint8_t read_value_Config[2] = {0};
	uint8_t value_Config1[1] = {0};
	uint8_t chip_id[2] = {0};
	uint8_t id;
	/* Config_Register 0x01
	 * bit[15]					工作状态/单次激发转换开始对于写入状态:
									0=无效果
									1=开始单次转换(处于单次激发模式时)
									对于读取状态:
									0=芯片正在进行转换
									1=芯片没有进行转换
									此位报告芯片的状态。
									只有当芯片处于断电状态时,才能写入此位。
	 * bit[14:12] = 100			AIN p = AIN0 和 AIN n =GND
	 * bit[11:9] = 010		 	fs = +-2.048V
	 * bit[8] = 0				连续转换模式
	 * bit[7:5] = 110		 	ADC输出数据速率 960HZ (DR_SEL = 1)或 800HZ(DR_SEL = 0)
	 *
	 * bit[4:0]=00011
	 * bit[4]					0=具有滞后的传统比较器(默认)
								1=窗口比较器
	 * bit[3]					比较器极性
									0=有效低(默认)
									1=有效高
									此位设置ALERT/RDY引脚的有效极性
	 * bit[2]					锁存比较器
									0=非锁存比较器(默认)
									1=锁存比较器
									该位设置ALERT/RDY引脚在其输出设置后是否锁存,或者当ADC转换结果在上限和下限阈值限制内时是否复位。
	 * bit[1:0]					比较器队列和禁用功能
									00=一次转换后断言
									01=两次转换后断定
									10=四次转换后确信
									11=禁用比较器(默认)
									这些位可以禁用比较器。
									在alert/RDY引脚上输出警报之前,这些位可以将连续ADC转换所需的时间设置为超过阈值。
	 */
	uint16_t value_Config_Register = 0x44c3;//默认0x8583h
	value_Config[0] = value_Config_Register >> 8;
	value_Config[1] = value_Config_Register;

	/* Config1_Register	0x04
	 * bit[6]		0=DR[2:0]=000~111转换率为6.25Hz、12.5Hz、25Hz、50Hz、100Hz、200Hz、400Hz和800Hz(默认)
	 * 				1=DR[2:0]=000~111转换速率为7.5Hz、15Hz、30Hz、60Hz、120Hz、240Hz、480Hz和960Hz
	 */
	uint16_t value_Config1_Register = 0x0040;//默认0x8583h
	value_Config1[1] = value_Config1_Register;

	while(i){
		i = 0;
		i += smg58031_i2c_writeregister(I2C_ADC_ADDR, Config_Register, 2, value_Config);
			HAL_Delay(20);

		i += smg58031_i2c_writeregister(I2C_ADC_ADDR, Config1_Register, 2, value_Config1);
	
		HAL_Delay(20);
		i += smg58031_i2c_readregister(I2C_ADC_ADDR, ChipID_Register, 2, chip_id);
		HAL_Delay(20);
		id = (chip_id[0] << 3) | (chip_id[1] >> 5);
		
//		if(id == 0x90)
		i += smg58031_i2c_readregister(I2C_ADC_ADDR,Config_Register,2,read_value_Config);


	}
	control_flag = 1;
}



float voltage;

int read_adc_value(void){
	int i = 0;
	int data;
	uint16_t tmpHL;
	uint8_t buf[2];
	if(control_flag == 1){
		i = smg58031_i2c_readregister(I2C_ADC_ADDR,Conversion_Register,2,buf);
		if(i != 0){
		
			return -1;
		}
		tmpHL= (buf[0] << 8) | buf[1];
//		tmpHL= (buf[1] << 8) | buf[0];
		voltage = (float) (tmpHL * (2.048 / 32768));
	
		return 0;
	}
	return -1;
}

这段代码涉及到对 ADC(模数转换器)芯片的控制和读取功能。下面是对代码的详细分析:

set_adc_control 函数:

这个函数用于设置 ADC 控制寄存器的值。
首先,定义了一些变量,包括 value_Config、read_value_Config、value_Config1、chip_id 和 id。
然后,根据注释中的说明,给这些变量赋予相应的数值。
在一个循环中,通过调用 smg58031_i2c_writeregister 函数将 value_Config 和 value_Config1 的值写入对应的寄存器。
紧接着,通过调用 smg58031_i2c_readregister 函数读取 chip_id 的值,并将其转换为 id。
最后,打印相关信息,将 control_flag 置为 1,表示设置控制成功。
read_adc_value 函数:

这个函数用于读取 ADC 转换寄存器的值并进行一些处理。
首先,定义一些变量,包括 data、tmpHL 和 buf。
在 control_flag 为 1 的条件下,通过调用 smg58031_i2c_readregister 函数读取转换寄存器的值,并将结果存储在 buf 中。
接下来,将 buf 中的两个字节按位拼接成一个 16 位的值 tmpHL。
根据公式将 tmpHL 转换为电压值 voltage。
将电压值转换为整型 data,并打印相关信息。
更新 smg58031_Data 数组中的值,并将其打印到串口。
更新 smg58031_Data_index 的值,循环覆盖保存的值。
最后,根据操作的结果返回相应的值。
这段代码主要实现了对 ADC 芯片的控制和读取功能。在 set_adc_control 函数中,通过写入寄存器的方式设置了 ADC 的配置参数。在 read_adc_value 函数中,通过读取寄存器的方式获取了 ADC 的转换结果,并将结果转换为电压值,并保存到数组中。

如果文章对您该有所帮助,点赞支持,感谢!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/735040.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JVM调优】JVM调优工具之Arthas

Arthas的作用 Arthas是一款线上监控诊断产品&#xff0c;通过全局视角实时查看应用 load、内存、gc、线程的状态信息&#xff0c;并能在不修改应用代码的情况下&#xff0c;对业务问题进行诊断&#xff0c;包括查看方法调用的出入参、异常&#xff0c;监测方法执行耗时&#x…

【Elasticsearch】索引库操作

目录 2.索引库操作 2.1.mapping映射属性 2.2.索引库的CRUD 2.2.1.创建索引库和映射 基本语法&#xff1a; 示例&#xff1a; 2.2.2.查询索引库 2.2.3.修改索引库 2.2.4.删除索引库 2.2.5.总结 2.索引库操作 索引库就类似数据库表&#xff0c;mapping映射就类似表的…

[神经网络]Anchor_Free网络(YoloX,CenterNet)

Anchor_Free网络不同于传统的目标检测网络需要先生成很多先验框再从中筛选回归生成预测框。其可以直接从目标的中心点向周围发散一个预测框。这样做有两个好处&#xff1a;①省略了生成大量先验框的过程&#xff0c;可以一定程度增加预测速度&#xff1b;②预测框没有预设长宽比…

魅族新专利:弹开机构及折叠终端,提高便捷性、降低使用难度

珠海市魅族科技有限公司透露新专利&#xff1a;弹开机构及折叠终端&#xff0c;提高展开便捷性、降低使用难度&#xff01; 该专利介绍了一种用于电子设备的弹开机构和折叠终端。该弹开机构由磁吸组和弹开模组组成。磁吸组包括第一磁吸件和第二磁吸件&#xff0c;其中第一磁吸件…

SpringBoot 如何使用 TestRestTemplate 进行 RESTful API 集成测试

SpringBoot 如何使用 TestRestTemplate 进行 RESTful API 集成测试 在使用 SpringBoot 开发 RESTful API 的过程中&#xff0c;我们需要进行集成测试&#xff0c;以确保 API 的正确性和可用性。而 TestRestTemplate 是 Spring Framework 提供的一个工具类&#xff0c;可以用来…

Flink实时任务性能调优

前言 通常我们在开发完Flink任务提交运行后&#xff0c;需要对任务的参数进行一些调整&#xff0c;通常需要调整的情况是任务消费速度跟不上数据写入速度&#xff0c;从而导致实时任务出现反压、内存GC频繁&#xff08;FullGC&#xff09;频繁、内存溢出导致TaskManager被Kill…

【笔记】数字电路基础1 - 门电路

目录 数字电路基础与门电路数电基础基本门电路复合门电路TTL 门电路CMOS 门电路 数字电路基础与门电路 数电基础 数字电路中常将 0 &#xff5e; 1V 范围的电压称为低电平&#xff0c;用“0”表示&#xff1b;而将 3 &#xff5e; 5V 范围的电压称为高电平&#xff0c;用“1”…

【InnoDB 存储引擎】InnoDB 存储引擎的行格式,有 Compact、Redundant、Dynamic 等行格式还有它们配套实验(理论篇)

文章目录 1 InnoDB 行记录格式&#xff08;理论&#xff09;1.1 Redundant 行记录格式1.2 Compact 行记录格式&#xff08;重点&#xff09;1.3 行溢出数据1.4 Compressed 和 Dynamic 行记录格式1.5 CHAR 的行结构存储 2 参考资料 1 InnoDB 行记录格式&#xff08;理论&#xf…

什么是数据一致性

什么是数据一致性 数据一致性这个单词在平常开发中&#xff0c;或者各种文章中都能经常看见&#xff0c;我们常常听见什么东西数据不一致了&#xff0c;造成了一定的损失&#xff0c;赶快修复一下。但是很多同学对一致性具体代表什么意思&#xff0c;他有什么作用依然不是很了解…

车载软件架构 —— 闲聊几句AUTOSAR OS(八)

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他人的角度来反对自己。人生在世,最怕的就是把别人的眼光当成自己生活的唯一标…

Overleaf 集成git出现authentification failed 的解决方法

Overleaf 集成git遇到的问题和解决办法 需求背景&#xff1a;使用git 将overleaf 项目克隆到本地硬盘上工作&#xff0c;像写代码一样管理论文版本。 问题描述&#xff1a;直接使用overleaf提供的git clone xxxx 会出现authentication failed for xxxxx (见下图&#xff09; …

C++中的继承/虚继承原理

C中的继承 文章目录 C中的继承1.继承的概念和定义1.1 继承定义1.12 继承关系和访问限定符2.基类和派生类对象的复制转换3.继承中的作用域4.派生类的默认成员函数继承与友元 6.**继承与静态成员****复杂的菱形继承及菱形虚拟继承**7.虚继承解决数据冗余和二义性的原理 1.继承的概…

git 技术点整理

1.git安装 1.1官网下载 Git 安装详情见https://www.cnblogs.com/liuwenwu9527/p/11688323.html 1.2配置 2.git基本概念 2.1本地 工作区(Working Directory)&#xff1a;就是你在电脑里能看到的目录。说人话就是idea直接能看到的这部分纯代码区域。&#xff08;不含 .git…

基于51单片机的太阳追光系统设计

本实例是基于51单片机的太阳追光系统&#xff0c;主要硬件由51单片机最小系统&#xff0c;四路光敏感应电路&#xff0c;ADC0832转换电路、LED指示灯电路、X轴与Y轴步进电机构成。 设计功能 1.四路光敏感应电路&#xff1a;四路光敏电阻分别感应上、下、左、右四个方向的光强…

两组表单看懂MySQL的多表查询

第一组表单信息 1、查询每个部门的所属员工 mysql> SELECT name,GROUP_CONCAT(ename) persons-> FROM dept3 d-> LEFT JOIN emp3 e-> ON d.deptno e.dept_id-> GROUP BY d.deptno-> UNION -> SELECT name,GROUP_CONCAT(ename) persons-> FROM dept3 …

代码随想录算法训练营第六十天| 84.柱状图中最大的矩形

柱状图中最大的矩形 题目链接&#xff1a; 力扣 假设以柱子1&#xff08;指值为1的柱子&#xff09;为基准&#xff0c;柱子1的左侧没有比柱子1矮的元素&#xff0c;所以柱子1可以无限像左边扩展&#xff0c;柱子1的右侧也没有比柱子1矮的元素&#xff0c;所以柱子1可以无限向…

用OpenCV进行图像分割--进阶篇

1. 引言 大家好&#xff0c;我的图像处理爱好者们&#xff01; 在上一篇幅中&#xff0c;我们简单介绍了图像分割领域中的基础知识&#xff0c;包含基于固定阈值的分割和基于OSTU的分割算法。这一次&#xff0c;我们将通过介绍基于色度的分割来进一步巩固大家的基础知识。 闲…

如何提升问卷数据的有效性?

问卷调查法是收集数据的宝贵工具&#xff0c;可以为商业、社会科学和医疗保健等众多领域的决策过程提供真实可靠的数据信息。然而&#xff0c;问卷数据的准确性和可靠性是影响最终结论的关键因素&#xff0c;而他们取决于问卷设计和数据收集过程的质量。在本文中&#xff0c;我…

Coggle 30 Days of ML(23年7月)任务三:使用TFIDF提取文本特征

Coggle 30 Days of ML&#xff08;23年7月&#xff09;任务三&#xff1a;使用TFIDF提取文本特征 任务三&#xff1a;使用TFIDF提取文本特征 说明&#xff1a;在这个任务中&#xff0c;需要使用Sklearn库中的TFIDF技术来提取文本特征&#xff0c;将文本转化为可供机器学习算法…