【MT32F006】MT32F006之max17048电量计(IIC通信)

发布于:2025-02-10 ⋅ 阅读:(44) ⋅ 点赞:(0)

本文最后修改时间:2025年01月09日

一、本节简介

本文介绍如何使用MT32F006通过IIC与电量计max17048通信。

二、实验平台

库版本:V1.0.0

编译软件:MDK5.37

硬件平台:MT32F006开发板(主芯片MT32F006)

仿真器:JLINK

三、版权声明

1)作者:甜甜的大香瓜

2)声明:喝水不忘挖井人,转载请注明出处。

3)纠错/业务合作:897503845@qq.com

4)香瓜嵌入式之STM8/STM32群:164311667

5)本文出处:原创连载资料《简单粗暴学MT32F006》

6)完整开源资料下载地址(电脑端打开):opengua.taobao.com

四、实验前提

1、在进行本文步骤前,请先阅读以下章节:

1)《简单粗暴学MT32F006》的第一章和第二章章节

暂无

2、在进行本文步骤前,请先实现以下章节:

1)《简单粗暴学MT32F006》的《MT32F006IIC》。

2)《简单粗暴学MT32F006》的《MT32F006之串口》。

五、基础知识

暂无

六、硬件原理

七、实验步骤

1、编写并添加驱动

1)编写驱动GUA_Max17048.c(存放在“……\Projects\MT006_StdPeriph_Templates\GUA”)

//**********************************************************************

//name:         GUA_Max17048.c

//introduce:    Max17048驱动

//author:       opengua     

//email:        897503845@qq.com  

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

#include "mt006.h"

#include "GUA_Max17048.h"

#include "GUA_IIC.h"

#include "GUA_UART.h"

#include "stdbool.h"

/*********************宏定义************************/

//MAX17048 registers

#define VCELL                         0x02U       // R/-: ADC measurement of VCELL, 78.125uV/cell

#define SOC                               0x04U       // R/-: Battery state of charge, 1%/256

#define MODE                              0x06U      // -/W: Current operating mode, enable sleep

#define VERSION                       0x08U           // R/-: Production version

#define HIBRT                         0x0AU       // R/W: Hibernation thresholds

#define CONFIG                        0x0CU           // R/W: Compensation, toggle sleep, alert masks, config

#define VALRT                         0x14U       // R/W: Voltage level to generate alert

#define CRATE                         0x16U       // R/-: Charge/discharge rate, 0.208%/hr

#define VRESET_ID                 0x18U          // R/W: VCELL for chip reset

#define STATUS                        0x1AU           // R/W: Over/undervoltage, SOC change/low, reset alerts

#define TABLE                         0x40U       // -/W: Configures battery parameters

#define CMD                               0xFEU       // R/W: POR command

//MAX17048 masks/constants

#define VERSION_MSK               0xFFF0U

#define PART_NUMBER               0x0010U

#define BAT_LOW_POS               0U

#define BAT_LOW_MSK               (0x001FU << BAT_LOW_POS)

#define BAT_LOW_MIN               1U

#define BAT_LOW_MAX               32U

#define ALRT_BIT_POS              5U

#define ALRT_BIT_MSK              (0x0001U << ALRT_BIT_POS)

#define ALSC_BIT_POS              6U

#define ALSC_BIT_MSK              (0x0001U << ALSC_BIT_POS)

#define VALRT_MAX_POS          0U

#define VALRT_MAX_MSK          (0x00FFU << VALRT_MAX_POS)

#define VALRT_MIN_POS          8U

#define VALRT_MIN_MSK          (0x00FFU << VALRT_MIN_POS)

#define VALRT_RESOLUTION       20U

#define VRESET_POS                9U

#define VRESET_MSK                (0x007FU << VRESET_POS)

#define VRESET_RESOLUTION 40U

#define ENVR_BIT_POS              14U

#define ENVR_BIT_MSK              (0x0001U << ENVR_BIT_POS)

#define ALRT_STATUS_POS        8U

#define ALRT_STATUS_MSK        (0x003FU << ALRT_STATUS_POS)

#define QUICK_START_BIT_POS 14U

#define QUICK_START_BIT_MSK (0x0001U << QUICK_START_BIT_POS)

//电池电量阈值设置宏

#define BAT_LOW_PERCENT        15U //可修改设置1%~32%

//VCELL的数值与mv转换

#define VCELL_TO_MV(vcell)     ((vcell * 5U) >> 6U)    //vcell*5/64=vcell*0.078125mV(寄存器里是每cell代表78.125uV)

//MAX17048是大端,所以需要小端转大端

#define SWAP16(x)                 ((uint16_t)(((x) << 8U) | ((x) >> 8U)))

/*********************变量************************/

uint16_t gnGUA_Max17048_Vcell = 0;        //电压

uint8_t gnGUA_Max17048_Soc = 0;               //电量

/*********************内部函数************************/

static inline bool GUA_Max17048_ReadReg(uint8_t reg, uint16_t* out);

static inline bool GUA_Max17048_WriteReg(uint8_t reg, uint16_t data);

static inline bool GUA_Max17048_ModifyReg(uint8_t reg, uint16_t data, uint16_t mask);

static bool GUA_Max17048_ReadVersion(void);

static bool GUA_Max17048_GetVcell(uint16_t* mv);

static bool GUA_Max17048_GetSoc(uint8_t* percent);

static bool GUA_Max17048_SetBatLowSoc(uint16_t percent);

static bool GUA_Max17048_SetUndervoltedVoltage(uint16_t mv);

static bool GUA_Max17048_SetOvervoltedVoltage(uint16_t mv);

static bool GUA_Max17048_SetResetVoltage(uint16_t mv);

static bool GUA_Max17048_SetSocChangeAlert(bool enable);

static bool GUA_Max17048_SetvVoltageResetAlert(bool enable);

static bool GUA_Max17048_ClearAlert(void);

static bool GUA_Max17048_GetAlerts(uint8_t* alerts);

static bool GUA_Max17048_QuickStartMode(void);

//**********************************************************************

//name:         GUA_Max17048_ReadReg

//introduce:    读取寄存器数据

//parameter:    reg:要读到的寄存器地址

//                         *out:数据要读到的接收缓冲区

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static inline bool GUA_Max17048_ReadReg(uint8_t reg, uint16_t* out)

{

    if(GUA_IIC_ReadBytes(reg, 2, (uint8_t*)out, GUA_MAX17048_ADDR) == false)  //读两个字节   

        return false;     

    *out = SWAP16(*out);                                                                                               //小端转大端

   

    return true;

}

//**********************************************************************

//name:         GUA_Max17048_WriteReg

//introduce:    写入寄存器数据

//parameter:    reg:要写到的寄存器地址

//                         data:要写入的数据

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static inline bool GUA_Max17048_WriteReg(uint8_t reg, uint16_t data)

{

    uint8_t Buffer[2];

   

    Buffer[0] = (uint8_t)(data&0X00FF);

    Buffer[1] = (uint8_t)(data>>8);

   

    return GUA_IIC_SendBytes(reg, 2, Buffer, GUA_MAX17048_ADDR);

}

//**********************************************************************

//name:         GUA_Max17048_ModifyReg

//introduce:    修改寄存器某一位的值

//parameter:    reg:要修改的寄存器地址

//                         data:最终修改的数据

//                         mask:寄存器中对应的位

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static inline bool GUA_Max17048_ModifyReg(uint8_t reg, uint16_t data, uint16_t mask)

{

    uint16_t tmp;

   

    //读出寄存器数据

    if(GUA_Max17048_ReadReg(reg, &tmp) == false)

    {

        return false;

    }

    //修改数据

    tmp = (tmp & ~mask) | (data & mask);

   

    //写入寄存器

    return GUA_Max17048_WriteReg(reg, tmp);

}

//**********************************************************************

//name:         GUA_Max17048_ReadVersion

//introduce:    读版本号,默认是0x001x

//parameter:    none

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static bool GUA_Max17048_ReadVersion(void)

{

    uint16_t data;

   

    //读寄存器

    if(GUA_Max17048_ReadReg(VERSION, &data)==false)

    {

        return false;

  }

   

    //打印(04是4个数字;x是十六进制显示)

    printf("VERSION = 0x%04x\r\n", data);

   

    //核对版本号是否满足0x001x,并返回GUA_TRUE和GUA_FALSE

    return ((data & VERSION_MSK) == PART_NUMBER);

}

//**********************************************************************

//name:         GUA_Max17048_GetVcell

//introduce:    获取ADC计算的电压Vcell

//parameter:    mv:读的电压(单位mv)

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static bool GUA_Max17048_GetVcell(uint16_t* mv)

{

    uint16_t data;

    //读出寄存器数据

    if(GUA_Max17048_ReadReg(VCELL, &data) == false)

    {

        return false;

    }

    //读出来的是vcell,要转换成电压值.vcell*5/64=vcell*0.078125mV(寄存器里是每cell代表78.125uV)

    *mv = (uint16_t)(VCELL_TO_MV(data));

    return true;

}

//**********************************************************************

//name:         GUA_Max17048_GetSoc

//introduce:    读电池电量

//parameter:    *percent:要读到的电量缓存区

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static bool GUA_Max17048_GetSoc(uint8_t* percent)

{

    uint16_t data;

   

    //读出寄存器数据

    if(GUA_Max17048_ReadReg(SOC, &data)  == false)

    {

        return false;

    }

    //每256为1%,所以除256换算成百分比

  *percent = (uint8_t)(data >> 8);

   

  return true;

}

//**********************************************************************

//name:         GUA_Max17048_SetBatLowSoc

//introduce:    设置电池低 SOC(State of Charge)阈值,config寄存器的ATHD位,将在ALRT引脚产生中断

//parameter:    *percent:要读到的电量缓存区

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static bool GUA_Max17048_SetBatLowSoc(uint16_t percent)

{

    //只能设置1%~32%

    if(percent < BAT_LOW_MIN || percent > BAT_LOW_MAX)

    {

        return false;

    }

   

    //寄存器中ATHD=32%-设定值

    uint16_t data = (uint16_t)((BAT_LOW_MAX - (percent % BAT_LOW_MAX)) & BAT_LOW_MSK);

    //修改config寄存器的ATHD位

    return GUA_Max17048_ModifyReg(CONFIG, data, BAT_LOW_MSK);

}

//**********************************************************************

//name:         GUA_Max17048_SetUndervoltedVoltage

//introduce:    设置电池欠压警报阈值

//parameter:    mv:设置的电压(单位mv)

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static bool GUA_Max17048_SetUndervoltedVoltage(uint16_t mv)

{

    //寄存器数值=实际mv/20mv

    uint16_t data = (uint16_t)(((mv / VALRT_RESOLUTION) << VALRT_MIN_POS) & VALRT_MIN_MSK);

    //修改VALRT的高8位

    return GUA_Max17048_ModifyReg(VALRT, data, VALRT_MIN_MSK);

}

//**********************************************************************

//name:         GUA_Max17048_SetOvervoltedVoltage

//introduce:    设置电池过压警报阈值

//parameter:    mv:设置的电压(单位mv)

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static bool GUA_Max17048_SetOvervoltedVoltage(uint16_t mv)

{

    //寄存器数值=实际mv/20mv  

    uint16_t data = (uint16_t)(((mv / VALRT_RESOLUTION) << VALRT_MAX_POS) & VALRT_MAX_MSK);

    //修改VALRT的低8位

    return GUA_Max17048_ModifyReg(VALRT, data, VALRT_MAX_MSK);

}

//**********************************************************************

//name:         GUA_Max17048_SetResetVoltage

//introduce:    设置电池复位阈值电压

//parameter:    mv:设置的电压(单位mv)

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static bool GUA_Max17048_SetResetVoltage(uint16_t mv)

{

    //寄存器数值=实际mv/40mv

    uint16_t data = (uint16_t)(((mv / VRESET_RESOLUTION) << VRESET_POS) & VRESET_MSK);

    //修改VRESET_ID的高7位  

    return GUA_Max17048_ModifyReg(VRESET_ID, data, VRESET_MSK);

}

//**********************************************************************

//name:         GUA_Max17048_SetSocChangeAlert

//introduce:    启用或禁用SOC改变警报(变动1%)

//parameter:    enable:1启动 0关闭

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static bool GUA_Max17048_SetSocChangeAlert(bool enable)

{

    //1启动 0关闭

    uint16_t data = (uint16_t)((enable << ALSC_BIT_POS) & ALSC_BIT_MSK);

    //修改config寄存器的ALSC位  

    return GUA_Max17048_ModifyReg(CONFIG, data, ALSC_BIT_MSK);

}

//**********************************************************************

//name:         GUA_Max17048_SetvVoltageResetAlert

//introduce:    启用或禁用电压复位警报,当写入1设置为开启后,电压复位时会通过ALRT引脚报警

//parameter:    enable:1启动 0关闭

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static bool GUA_Max17048_SetvVoltageResetAlert(bool enable)

{

    //1启动 0关闭

    uint16_t data = (uint16_t)((enable << ENVR_BIT_POS) & ENVR_BIT_MSK);

    //修改status寄存器的EnVr位  

    return GUA_Max17048_ModifyReg(STATUS, data, ENVR_BIT_MSK);

}

//**********************************************************************

//name:         GUA_Max17048_ClearAlert

//introduce:    清除当前警报配置和状态位。

//parameter:    *percent:要读到的电量缓存区

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static bool GUA_Max17048_ClearAlert(void)

{

    //清除警报状态位

    if(GUA_Max17048_ModifyReg(STATUS, 0, ALRT_STATUS_MSK) == false)

        return false;

    //清除警报配置

    if(GUA_Max17048_ModifyReg(CONFIG, 0, ALRT_BIT_MSK) == false)

        return false;

   

    return true;

}

//**********************************************************************

//name:         GUA_Max17048_GetAlerts

//introduce:    读取当前警报状态并且清除已触发的警报

//parameter:    *alerts:返回状态数据SC/HD/VR/VL/VH/RI

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static bool GUA_Max17048_GetAlerts(uint8_t* alerts)

{

    uint16_t data;

    //读警报状态位

    if(GUA_Max17048_ReadReg(STATUS, &data) == false)

        return false;

    //清除警报状态位

    if(GUA_Max17048_ClearAlert() == false)

        return false;

    //返回状态数据:SC/HD/VR/VL/VH/RI

    *alerts = (uint8_t)((data & ALRT_STATUS_MSK) >> ALRT_STATUS_POS);

    return true;

}

//**********************************************************************

//name:         GUA_Max17048_QuickStartMode

//introduce:    开启快速模式

//parameter:    none

//return:       false:0错误;true:1正常

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

static bool GUA_Max17048_QuickStartMode(void)

{

    //修MODE寄存器的Quick-Start位

    return GUA_Max17048_ModifyReg(MODE, 1, QUICK_START_BIT_MSK);

}

//**********************************************************************

//name:         GUA_Max17048_UpdataVcellSoc

//introduce:    获取电压和电量

//parameter:    none

//return:       none

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

void GUA_Max17048_UpdataVcellSoc(void)

{

    //获取电压

    GUA_Max17048_GetVcell(&gnGUA_Max17048_Vcell);

    //printf("max17048 - vcell = %d,read_Voltage_mv =%d \r\n",t_temp,max17048_ReadVoltage());

    //获取电量

    GUA_Max17048_GetSoc(&gnGUA_Max17048_Soc);

    //printf("max17048 SOC = %d%%\r\n",gnGUA_Max17048_Soc);

}

//**********************************************************************

//name:         GUA_Max17048_Init

//introduce:    初始化

//parameter:    none

//return:       none

//author:       opengua

//email:        897503845@qq.com

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

void GUA_Max17048_Init(void)

{

    //读版本号确认通信是否完好(或者读ID也可以)

    if(GUA_Max17048_ReadVersion() == true)

    {

        printf("OK: find max17048 IC\r\n");

    }

    else

    {

        printf("ERROR : cannot find  max17048 IC\r\n");

    }

    //开启快速模式

    GUA_Max17048_QuickStartMode();

   

    //获取电压和电量

    GUA_Max17048_UpdataVcellSoc();

}

2)编写驱动GUA_Max17048.h(存放在“……\Projects\MT006_StdPeriph_Templates\GUA”)

//**********************************************************************

//name:         GUA_Max17048.h

//introduce:    Max17048驱动的头文件

//author:       opengua     

//email:        897503845@qq.com  

//QQ group:     香瓜单片机之STM8/STM32(164311667)

//shop:         opengua.taobao.com

//changetime:   2024.12.11

//**********************************************************************

#ifndef _GUA_MAX17048_H_

#define _GUA_MAX17048_H_

/*********************头文件************************/

#include <stdint.h>

/*********************宏定义************************/

//默认设备地址是7位地址,左移1位为8位地址,最低位将用于读写标志

#define GUA_MAX17048_ADDR      (0x36<<1)

/*********************变量************************/

enum MAX_ALERT_TYPE{

    MAX_ALERT_RESET                   = 0x01U,

    MAX_ALERT_OVERVOLTED           = 0x02U,

    MAX_ALERT_UNDERVOLTED      = 0x04U,

    MAX_ALERT_VOLTAGE_RESET    = 0x80U,

    MAX_ALERT_SOC_LOW              = 0x10U,

    MAX_ALERT_SOC_CHANGE           = 0x20U,

};

extern uint16_t gnGUA_Max17048_Vcell;             //电压

extern uint8_t gnGUA_Max17048_Soc;                //电量

/*********************外部函数************************/

void GUA_Max17048_Init(void);

void GUA_Max17048_UpdataVcellSoc(void);

#endif

3)工程中添加驱动文件

4)在MDK设置中添加驱动源文件路径

2、添加库的驱动

1)添加库的驱动文件(为了方便一次性都添加进来,已有则不用添加)

2)添加库的驱动头文件(mt006_conf.h 中)(为了方便一次性都添加进来,已有则不用添加)

3、在应用层中调用

1)添加驱动头文件(main.c中)

#include "GUA_Max17048.h"

2)添加驱动初始化代码(main.c的main函数中)

    //max17048初始化 电量计

    GUA_Max17048_Init();

3)添加测试代码(main.c的main函数中)

                       //获取电压和电量

                       GUA_Max17048_UpdataVcellSoc();

八、注意事项

暂无

九、实验结果

暂无