请教:
无论我怎样设置STM8L152的外设或其他单元,其最小电流总在140微安左右,与手册上标明的相去甚远,检查检查再检查,可能还是同一个思路,找不出产生问题的原因,哪位有空的话帮忙看一下,先行谢过.
硬件为最小系统,外部有一个电位器ADC.
/*****************************************************
@Fn: ConfigClock()
@Br: 配置处理器的时钟
@Pa: 无
@Rt: 无
@Sp: 无
*****************************************************/
void ConfigClock( void ){
CLK_CKDIVR = 0; /* 无分频 */
CLK_ICKCR = ( 1 << HSION ); /* 使能内部高速RC OSC */
while(( CLK_ICKCR & 0x02 ) == 0 ); /* ( 1 << HSIRDY ) */
CLK_ICKCR |= ( 1 << LSION );
while(( CLK_ICKCR & ( 1 << LSIRDY )) == 0 );
CLK_SWR = F_MASTER_LSI; /* 指定切换的LSI主时钟 */
CLK_SWCR |= ( 1 << SWEN ); /* 使能执行切换 */
while(( CLK_SCSR & F_MASTER_LSI ) == 0 );
CLK_CKDIVR = CLK_DIV_001; /* Internal Fcpu = 38KHz => 0.13mA */
CLK_ICKCR &= ~( 1 << HSION ); /* 关闭内部高速RC OSC */
CLK_SWCR &= ~( 1 << SWEN ); /* 关闭执行切换 */
CLK_PCKENR2 = ( 1 << ADC1_CLK_ENABLE )
+ ( 1 << TM1_CLK_ENABLE );
}
/************************************************************
@Fn: ConfigGPIO()
@Br: 配置GPIO
@Pa: 无
@Rt: 无
@Specification: 无
************************************************************/
void ConfigGPIO( void ){
PA_DDR = ( 1 << PA4 ); /* 输出 */
PA_CR1 = ( 1 << PA4); /* 推挽模式 */
PA_CR2 = 0x00; /* 速度2MHz */
PA_ODR = ( 1 << PA4 );
PB_DDR = 0;
PB_CR1 = 0xFF; /* 输入上拉 */
PB_CR2 = 0;
PB_ODR = 0xFF; /* 配置为高电平 */
PC_DDR = 0;
PC_CR1 = 0xFF;
PC_CR2 = 0;
PC_ODR = 0xFF;
PD_DDR = 0;
PD_CR1 = 0xFF;
PD_CR2 = 0;
PD_ODR = 0xFF;
}
/************************************************************
@Fn: ConfigTimer()
@Br: 配置定时器
@Pa: 无
@Rt: 无
@Specification: 无
************************************************************/
void ConfigTimer( void ){
TIM1_PSCRH = ( 1 << PSC10 );
TIM1_PSCRL = 0xFF;
/* Configure TIM1 prescaler = 512 */
/* Fck_cnt = Fck_psc / ( 2 ^[15:0] + 1 ) */
TIM1_PSCRH = 0;
TIM1_PSCRL = ( 1 << PSC01 ) + ( 1 << PSC00 );
/* Configure TIM1 prescaler = 4 */
/* Fck_cnt = Fck_psc / ( 2 ^[15:0] + 1 ) */
TIM1_ARRH = 0x94; /* TIM1的自动装载寄存器 */
TIM1_ARRL = 0x70;
TIM1_CNTRH = 0x94; /* TIM1的计数器 */
TIM1_CNTRL = 0x70;
/*
38,000
CNTR = ----------- * 4s = 0x9470 =>4s 产生一次中断
4
*/
TIM1_CR1 = ( 1 << ARPE ) + ( 1 << CEN ); /* 允许自动重装载,使能计数器 */
TIM1_IER = ( 1 << UIE ); /* 允许更新中断 */
}
/************************************************************
@Fn: ConfigADC()
@Br: 配置ADC
@Pa: 无
@Rt: 无
@Specification: 无
************************************************************/
void ConfigADC( void ){
ADC1_SR = 0;
ADC1_SQR1 = ( 1 << DMAOFF ); /* 禁止DMA传输,单转换模式 */
ADC1_SQR4 = ( 1 << CHSEL_S00 ); /* 使能ADC IN0通道 */
ADC1_CR3 = ADC_CH00; /* 第0通道 */
ADC1_CR2 = ( 1 << SMTP12 ) + ( 1 << SMTP11 ) + ( 1 << SMTP10 );
/* 时钟无分频,慢速模式的384个ADC时钟周期 */
ADC1_TRIGR1 &= ~( 1 << VREFINTON ); /* 关闭内部VREF参考源 */
ADC1_CR1 = ( 1 << EOCIE ) + ( 1 << CONT );
/* 中断使能,12位分辨率,连续模式 */
ADC1_CR1 |= ( 1 << ADON ); /* 打开ADC电源 */
/* 此处要延时,设置完成至少需要3uS时间等待参考源稳定 */
ADC1_CR1 |= ( 1 << START ); /* 软件启动转换 */
}
/************************************************************
@Fn: ConfigCPU()
@Br: 配置CPU及外围
@Pa: 无
@Rt: 无
@Specification: 无
************************************************************/
void ConfigCPU( void ){
_DI();
ConfigClock();
ConfigGPIO();
ConfigADC();
ConfigTimer();
_EI();
}
void main( void ){
uiTenor = 0;
ConfigCPU();
while( 1 )
{
if( uiTenor & T1_FLAG )
{
CLK_PCKENR2 |= ( 1 << ADC1_CLK_ENABLE );
ADC1_CR1 |= ( 1 << ADON );
ADC1_CR1 |= ( 1 << START ); /* 软件启动转换,由硬件自动清零 */
while(( uiTenor & ADC1_FLAG ) == 0 ); /* 至少3微秒时间延时确保精度 */
uiTenor &= ~ADC1_FLAG;
while(( uiTenor & ADC1_FLAG ) == 0 );
uiTenor &= ~ADC1_FLAG; /* 第一次结果不能使用 */
ADC1_CR1 &= ~( 1 << ADON );
uiTenor &= ~T1_FLAG;
}
if( uiTenor == 0 )
{
CLK_PCKENR2 &= ~( 1 << ADC1_CLK_ENABLE );
_WAIT_INTERR();
}
}
}
甚至把电位器拆除,电流还是这么大,电源是经过HT7133稳压后供给的.
电路图如下
-
-
未命名.GIF
(36.59 KB)
电流测量接线图
-
-
未命名.GIF
(5.16 KB)
看上去不对。12V的电源除了给MCU供电,还给其它芯片也供电。
12V电源通过1K电阻接到BATT接口,通过D801经HT7133稳压输出3.3V,没有其他芯片了。
12V电源通过1K电阻接到BATT接口,通过D801经HT7133稳压输出3.3V,没有其他芯片了。
即使把MCU拿掉,HT7133自身就有不少的静态电流,估计在100uA以上
没看程序,但思路应该如下, 供参考。
// 进入低功耗时的IO口初始化(注意,所有的端口都要初始化,别忘了)。没接外电路的设计为模拟输入。
// 口线外有上拉电路的,口置为输出模式并置1。
// 口线外有下拉电路的,口置为输出模式并置0。
// 注意唤醒源不要配置为不能唤醒的模式。
PWR_FastWakeUpCmd(DISABLE);
PWR_UltraLowPowerCmd(ENABLE);
// ;进入低功耗模式,等待MM叫醒。
IO口配置为原先配置;
外设配置为原先的配置;
没看程序,但思路应该如下, 供参考。
// 进入低功耗时的IO口初始化(注意,所有的端口都要初始化,别忘了)。没接外电路的设计为模拟输入。
// 口线外有上拉电路的,口置为输出模式并置1。
// 口线外有下拉电路的,口 ...
这些设置适用于STM32(32F、32L),但不适于STM8L。
为了简单起见,最好让STM8L进入HALT模式,此时电流最小。另外,最好什么外设也不打开(AD、定时器等等),delay延时一段时间后直接HALT
静默 所描述的部分方法,同样适用于STM8L处理器,具体可参考 STM8L15x microcontroller family.pdf
我认为,硬件是最小的系统,因此,还是软件没设置好。
我感觉自己走入了死胡同,钻了牛角尖,所以,还得要从软件上想办法才能实现 AN3147 文档上所描述的数据。
直接 _HALT()结果:
整板电流 = 14.5582uA
suzhwt, 可否试一下以下代码, 并告知整板电流。在你的板上应该在4uA左右。
GPIO_Init(GPIOA, GPIO_Pin_All, GPIO_Mode_In_FL_No_IT);
GPIO_Init(GPIOB, GPIO_Pin_All, GPIO_Mode_In_FL_No_IT);
GPIO_Init(GPIOC, GPIO_Pin_All, GPIO_Mode_In_FL_No_IT);
GPIO_Init(GPIOD, GPIO_Pin_All, GPIO_Mode_In_FL_No_IT);
GPIO_Init(GPIOE, GPIO_Pin_All, GPIO_Mode_In_FL_No_IT);
GPIO_Init(GPIOF, GPIO_Pin_All, GPIO_Mode_In_FL_No_IT);
PWR_FastWakeUpCmd(DISABLE);
PWR_UltraLowPowerCmd(ENABLE);
/* Enter Wait for interrupt mode*/
wfi(); // or halt();
如果要达到手册上给出的结果,正确的测量方法应该是只量进入MCU的电流,而不是测量整个系统的电流。手册上的数据肯定不包括系统中除MCU以外的电流。
16楼版主:你的意思我明白,外围部件的电流就是一个稳压器,并且现在已知该稳压器的电流是2.49uA。
15楼 静默 兄弟:
void main( void ){
PA_DDR = 0xFF;
PA_CR1 = 0x60;
PA_CR2 = 0x00;
PA_ODR = 0x10;
PB_DDR = 0;
PB_CR1 = 0xFF; /* 输入上拉 */
PB_CR2 = 0;
PB_ODR = 0xFF; /* 配置为高电平 */
PC_DDR = 0;
PC_CR1 = 0xFF;
PC_CR2 = 0;
PC_ODR = 0xFF;
PD_DDR = 0;
PD_CR1 = 0xFF;
PD_CR2 = 0;
PD_ODR = 0xFF;
PWR_CSR2 &= ~( 1 << FWU );
PWR_CSR2 |= ( 1 << ULP );
_HALT();
while( 1 );
}
整板电流是 4.6762uA.
4.6xx了,不错。
E口与F口都要配置,虽然手册上没有显示给出E口与F口,但实际核上有E口与F口存在,只不过没引出PIN来。
STM8L的HALT模式电流约0.4uA,芯片实测的值跟0.4uA很接近。
4.7-2.5=2.2uA,跟0.4uA的差距还不小,除非LZ的应用接受2uA的耗电。
否则还需要努力。正确的方式,还是应该测MCU本身的耗电