SGM58031与单片机驱动实现

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    //增益修正,默认0x03FAextern 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;//默认0x8583hvalue_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;//默认0x8583hvalue_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.hqwc.cn/news/15648.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Element-UI 实现动态增加多个输入框并校验

文章目录 前言实现通过按钮动态增加表单并验证必填实现动态多个输入框为行内模式&#xff0c;其它为行外模式 前言 在做复杂的动态表单&#xff0c;实现业务动态变动&#xff0c;比如有一条需要动态添加的el-form-item中包含了多个输入框&#xff0c;并实现表单验证&#xff0…

CTFHub XSS DOM跳转 WriteUp

前文&#xff1a;DOM反射XSS 进入网站&#xff0c;直接查看源代码&#xff0c;下面是关键代码&#xff0c;这里有xss漏洞&#xff1a; <script>var target location.search.split("")if (target[0].slice(1) "jumpto") {location.href target[1…

vue项目中的vue.config.js配置文件中的proxy代理post一直在预检

记录一个比较有意思的bug,帮别人调试遇到的&#xff0c;一个哥们一直在群里问了好几次同一个问题了&#xff0c;他配置了代理&#xff0c;请求一直在发送&#xff0c;postman测试没问题&#xff0c;可以成功接收到&#xff0c;但是在项目前端请求&#xff0c;确实一点响应没有&…

Qt/C++原创项目作品精选(祖传原创/性能凶残)

00 前言说明 从事Qt开发十年有余&#xff0c;一开始是做C#.NET开发的&#xff0c;因为项目需要&#xff0c;转行做嵌入式linux开发&#xff0c;在嵌入式linux上做可视化界面开发一般首选Qt&#xff0c;当然现在可选的方案很多比如安卓&#xff0c;但是十多年前那时候板子性能低…

Nginx常用配置及和基本功能讲解

Nginx已经广泛应用于J-one和Jdos的环境部署上&#xff0c;本文对Nginx的常用的配置和基本功能进行讲解&#xff0c;适合Ngnix入门学习。 一、核心配置 找到Nginx安装目录下的conf目录下nginx.conf文件&#xff0c;Nginx的基本功能配置是由它提供的。 配置文件结构 Nginx的配…

linux中安装nginx

2.安装nginx 2.1 安装nginx前&#xff0c;需要安装的依赖&#xff08;可能是由于nginx版本旧原因&#xff0c;可能最新或较新版本不需安装这些依赖&#xff09; 如下四个依赖需要安装到linux中 2.1.1 安装 pcre 依赖 &#xff08;使用wget命令&#xff09; 步骤一&#xff1…

由中序及后序遍历序列构建二叉树的函数参数解析

【二叉树构建函数的参数确立示意图】 ile&#xff1a;中序遍历左端点位置&#xff0c;iri&#xff1a;中序遍历右端点位置 ple&#xff1a;后序遍历左端点位置&#xff0c;pri&#xff1a;后序遍历右端点位置 【函数代码】 int build(int ile,int iri,int ple,int pri){int ro…

MySql存储引擎介绍——InnoDB、MyISAM、Memory

文章目录 1.MySql体系结构2.存储引擎简介3.存储引擎的特点3.1 InnoDB存储引擎特点3.2 MyISAM存储引擎介绍3.3 Memory存储引擎介绍 4.三种存储引擎的特点5.存储引擎的选择6.小结 1.MySql体系结构 2.存储引擎简介 存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式…

基于springboot+mybatis-plus+mysql+vue音乐网站管理系统

基于springbootmybatis-plusmysqlvue音乐网站管理系统 一、系统介绍1、系统主要功能&#xff1a;2.涉及技术框架&#xff1a;3.项目说明&#xff1a; 二、功能展示三、其它系统四、获取源码 一、系统介绍 1、系统主要功能&#xff1a; 音乐播放 用户登录注册 用户信息编辑、头…

Failed to start connector [Connector[HTTP/1.1-8080]]

1、解决Web server failed to start. Port 8080 was already in use 2、SpringBoot启动报错:“Error starting ApplicationContext. To display the conditions report re-run your application with ‘debug’ enabled.” 3、Failed to start end point associated with Proto…

这所985太好考了,专硕06方向仅刷一人,其余过线全收!

一、学校及专业介绍 东北大学&#xff08;Northeastern University&#xff09;位于辽宁省沈阳市&#xff0c;是中华人民共和国教育部直属全国重点大学。它是国家“双一流”建设高校、国家“211工程”和“985工程”重点建设高校&#xff0c;全国首批博士、硕士学位授予单位。 …

RabbitMQ 常用 API

RabbitMQ 常用 API Connection 和 Channel 的创建、关闭 创建 Connection ConnectionFactory factory new ConnectionFactory(); // 方式1&#xff1a;通过设置参数创建 factory.setHost(IP_ADDRESS); factory.setPort(PORT); factory.setUsername("guest"); facto…