然后就是查看原理图,看下这个电流测量的具体过程
从跳线帽JP2入手,是一个很好的起始点。JP2决定了从哪路引入电流,左边VDD支路是直接引入的,没有接入任何器件;右侧IDD支路,有四个采样电阻,1Ω、24Ω、620Ω和10kΩ分别有三个MOS管控制开启或关断。控制三个MOS管的管脚SH0\SH1\SH2出自于MFX-V3。两个双运放芯片,共四个运放,三个作为电压跟随器,一个电压放大,最后传到MUC的ADC,采样电阻很明显可以确保最后的电压值不超量程。
看原理图时发现电流测量部分全部集中在一个独立的模块中:Title: IDD measurement / MFX (Multi Function eXpander)
虽然原理图上只写了MFX_V3,没写具体芯片,但是在STM32L496 Dis,可以看出是一颗STM32L152CCTB。对于MFX部分,在官网没有找到详细的介绍,只有部分文档里有介绍
明白其共有三个作用,触摸、电流测量、IO扩展。但遗憾的是其固件在网上也没有找到,倒是ST的英文社区很多人询问MFX的文档或者源码,几乎也都没有响应,只是让参考Demo接口直接调用。因此,如果覆盖擦除了MFX的固件,想恢复几乎就不可能了,估计也是为了以往万一,MFX的烧写口是引出来了的,但是没有焊接排针。
对于MFX的所有操作,被封装成了一个函数指针组成的结构体中
IDD_DrvTypeDef mfxstm32l152_idd_drv =
{
mfxstm32l152_Init,
mfxstm32l152_DeInit,
mfxstm32l152_ReadID,
mfxstm32l152_Reset,
mfxstm32l152_LowPower,
mfxstm32l152_WakeUp,
mfxstm32l152_IDD_Start,
mfxstm32l152_IDD_Config,
mfxstm32l152_IDD_GetValue,
mfxstm32l152_IDD_EnableIT,
mfxstm32l152_IDD_ClearIT,
mfxstm32l152_IDD_GetITStatus,
mfxstm32l152_IDD_DisableIT,
mfxstm32l152_Error_EnableIT,
mfxstm32l152_Error_ClearIT,
mfxstm32l152_Error_GetITStatus,
mfxstm32l152_Error_DisableIT,
mfxstm32l152_Error_ReadSrc,
mfxstm32l152_Error_ReadMsg
};
上一篇已经知道了怎么由GUI到具体的应用调用,所以可以忽略上层的调用过程,只看一下电流测量的过程。
总共七种测量模式,被封装成一个结构体数组:
Idd_AppliTypedef IddTest[IDD_TEST_NB]=
{
{Idd_RunEnter, Idd_RunRestore, "Run 24Mhz", IDD_RUN},
{Idd_SleepEnter, Idd_SleepRestore, "Sleep 24Mhz", IDD_SLEEP},
{Idd_LprEnter, Idd_LprRestore,"LP Run 2Mhz", IDD_LPR_2MHZ},
{Idd_LprSleepEnter, Idd_LprSleepRestore,"LP Sleep", IDD_LPR_SLEEP},
{Idd_StopEnter, Idd_StopRestore, "Stop2", IDD_STOP2},
{Idd_StandbyEnter, NULL,"Standby", IDD_STANDBY},
{Idd_ShutdownEnter, NULL,"Shutdown", IDD_SHUTDOWN},
}
每一种模式,其对于外设的设置就都不一样了,在其函数中体现,其中涉及时钟的总共有三个函数,分别对应不同模式下的时钟设置:
Idd_ExternalSupply_ClockDecrease,设置系统时钟从80Mhz变为24Mhz
SystemLowClock_Config,设置系统时钟2Mhz
在测量时,调用了SystemPeripheralClockDisable,关闭了外设时钟。
查看其中的某一个函数:
void mfxstm32l152_IDD_Start(uint16_t DeviceAddr)
{
uint8_t mode = 0;
mode = MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL);
mode |= MFXSTM32L152_IDD_CTRL_REQ;
MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL, mode);
}
uint8_t MFX_IO_Read(uint16_t Addr, uint8_t Reg)
{
return I2C2_ReadData(Addr, Reg, I2C_MEMADD_SIZE_8BIT);
}
static uint8_t I2C2_ReadData(uint16_t Addr, uint16_t Reg, uint16_t RegSize)
{
HAL_StatusTypeDef status = HAL_OK;
uint8_t value = 0x0;
__disable_irq();
status = HAL_I2C_Mem_Read(&I2c2Handle, Addr, Reg, RegSize, &value, 1, I2c2Timeout);
__enable_irq();
if (status != HAL_OK)
{
/* Re-Initiaize the BUS */
I2C2_Error();
HAL_Delay(200);
}
return value;
}
一些操作被底层抽象成了寄存器,最终调用的是HAL库的驱动函数HAL_I2C_Mem_Read,实现了像操作IIC器件一样去操作STM32L152的效果。这个过程中,可以熟悉MFX的操作流程。
最后的实际测试结果: