打印
[STM8]

STM8L152K6T6功耗问题

[复制链接]
5904|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
suzhwt|  楼主 | 2010-10-13 14:29 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 suzhwt 于 2010-10-13 17:05 编辑

请教:
无论我怎样设置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();   
      }
    }
}
沙发
suzhwt|  楼主 | 2010-10-13 14:31 | 只看该作者
甚至把电位器拆除,电流还是这么大,电源是经过HT7133稳压后供给的.

使用特权

评论回复
板凳
香水城| | 2010-10-13 14:39 | 只看该作者
请贴出电路图,并说明你是如何测量电流的。

使用特权

评论回复
地板
suzhwt|  楼主 | 2010-10-13 14:49 | 只看该作者
电路图如下

未命名.GIF (36.59 KB )

未命名.GIF

使用特权

评论回复
5
suzhwt|  楼主 | 2010-10-13 14:55 | 只看该作者
电流测量接线图

未命名.GIF (5.16 KB )

未命名.GIF

使用特权

评论回复
6
IJK| | 2010-10-13 15:42 | 只看该作者
电流测量接线图
suzhwt 发表于 2010-10-13 14:55


看上去不对。12V的电源除了给MCU供电,还给其它芯片也供电。

使用特权

评论回复
7
suzhwt|  楼主 | 2010-10-13 15:46 | 只看该作者
12V电源通过1K电阻接到BATT接口,通过D801经HT7133稳压输出3.3V,没有其他芯片了。

使用特权

评论回复
8
IJK| | 2010-10-13 16:25 | 只看该作者
12V电源通过1K电阻接到BATT接口,通过D801经HT7133稳压输出3.3V,没有其他芯片了。
suzhwt 发表于 2010-10-13 15:46


即使把MCU拿掉,HT7133自身就有不少的静态电流,估计在100uA以上

使用特权

评论回复
9
suzhwt|  楼主 | 2010-10-13 16:53 | 只看该作者
HT7133的实测电流是2.49微安。

使用特权

评论回复
10
静默| | 2010-10-13 17:17 | 只看该作者
没看程序,但思路应该如下, 供参考。

// 进入低功耗时的IO口初始化(注意,所有的端口都要初始化,别忘了)。没接外电路的设计为模拟输入。
// 口线外有上拉电路的,口置为输出模式并置1。
// 口线外有下拉电路的,口置为输出模式并置0。
// 注意唤醒源不要配置为不能唤醒的模式。

PWR_FastWakeUpCmd(DISABLE);
PWR_UltraLowPowerCmd(ENABLE);

// ;进入低功耗模式,等待MM叫醒。

IO口配置为原先配置;
外设配置为原先的配置;

使用特权

评论回复
11
IJK| | 2010-10-13 17:30 | 只看该作者
没看程序,但思路应该如下, 供参考。

// 进入低功耗时的IO口初始化(注意,所有的端口都要初始化,别忘了)。没接外电路的设计为模拟输入。
// 口线外有上拉电路的,口置为输出模式并置1。
// 口线外有下拉电路的,口 ...
静默 发表于 2010-10-13 17:17


这些设置适用于STM32(32F、32L),但不适于STM8L。

使用特权

评论回复
12
IJK| | 2010-10-13 17:33 | 只看该作者
本帖最后由 IJK 于 2010-10-13 17:34 编辑

为了简单起见,最好让STM8L进入HALT模式,此时电流最小。另外,最好什么外设也不打开(AD、定时器等等),delay延时一段时间后直接HALT

使用特权

评论回复
13
suzhwt|  楼主 | 2010-10-13 17:35 | 只看该作者
本帖最后由 suzhwt 于 2010-10-14 09:03 编辑

静默 所描述的部分方法,同样适用于STM8L处理器,具体可参考 STM8L15x microcontroller family.pdf

我认为,硬件是最小的系统,因此,还是软件没设置好。
我感觉自己走入了死胡同,钻了牛角尖,所以,还得要从软件上想办法才能实现 AN3147 文档上所描述的数据。

使用特权

评论回复
14
suzhwt|  楼主 | 2010-10-13 17:46 | 只看该作者
直接 _HALT()结果:
整板电流 = 14.5582uA

使用特权

评论回复
15
静默| | 2010-10-13 20:58 | 只看该作者
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();

使用特权

评论回复
16
香水城| | 2010-10-14 05:09 | 只看该作者
如果要达到手册上给出的结果,正确的测量方法应该是只量进入MCU的电流,而不是测量整个系统的电流。手册上的数据肯定不包括系统中除MCU以外的电流。

使用特权

评论回复
17
bili| | 2010-10-14 08:50 | 只看该作者
摸大腿测体温能准?

使用特权

评论回复
18
suzhwt|  楼主 | 2010-10-14 08:55 | 只看该作者
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.

使用特权

评论回复
19
静默| | 2010-10-14 09:08 | 只看该作者
4.6xx了,不错。
E口与F口都要配置,虽然手册上没有显示给出E口与F口,但实际核上有E口与F口存在,只不过没引出PIN来。

使用特权

评论回复
20
IJK| | 2010-10-14 09:37 | 只看该作者
STM8L的HALT模式电流约0.4uA,芯片实测的值跟0.4uA很接近。
4.7-2.5=2.2uA,跟0.4uA的差距还不小,除非LZ的应用接受2uA的耗电。
否则还需要努力。正确的方式,还是应该测MCU本身的耗电

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

73

帖子

1

粉丝