打印
[STM8]

stm8l在Active_Halt(低功耗)模式下,怎么让RTC和LCD正常工作?

[复制链接]
13069|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
香主,请问如何让stm8l在Active_Halt的模式下,让RTC和LCD正常工作,LCD不需要刷屏,只要显示日期即可,我现在RTC已经可以实现在Active_Halt正常工作,但是一旦进入halt模式下,LCD就不亮了。。
      我想问:1、Active_Halt模式下,是只要使能LCD,并配置好LCD,再进入Halt模式就可以使LCD正常工作了吗?
                  2、如果正常工作,那功耗是多少?
下面是我的程序:
void main()
{
  GPIO_Init( BUTTON_GPIO_PORT, USER_GPIO_PIN, GPIO_Mode_In_FL_IT);//用户按键初始化:
  EXTI->CR2 = 0x80; //使能PC1口上升沿来唤醒        
  enableInterrupts();

  rtc_init();//使能RTC
  Calendar_Init();//日期初始化

  HSE_TO_LSE();//切换时钟,HSE-->LSE
  u8 temp;

  while (1)
  {
    switch (state_machine)
    {
        case 0://想在halt模式下显示“20140214”
           LCD_GLASS_Init();
           u16  table[]={'2','0','1','4','0','2','1','4'};
           LCD_GLASS_DisplayStrDeci(table);
           Halt_Init();//初始化HALT模式  
           //delay_ms(1);
           //rim();//失能中断
           //while((GPIOE->IDR & USER_GPIO_PIN) != 0x0);
           halt();//进入HALT模式
        break;
        case 1://按下PE7键,进入正常状态,显示当前时间   
          {
             u8 count=0;
             LCD_GLASS_Init();
             while (1)
                {
                  RTC_GetTime(RTC_Format_BIN, &RTC_TimeStr);
                  temp=RTC_TimeStr.RTC_Seconds;
                  while(temp==RTC_TimeStr.RTC_Seconds)//查询等待1s
                    {
                      RTC_GetTime(RTC_Format_BIN, &RTC_TimeStr);
                    }
                  Time_Show();
                  count++;
                  if(count==6)
                    {
                      state_machine=0;
                      break;
                    }
                 }
             LCD_GLASS_Clear();
           }            
          break;
    }   
  }

沙发
嵌入式云终端| | 2014-2-18 08:50 | 只看该作者
这样的问题要自己看编程手册哦,大家应用的不是很多,

使用特权

评论回复
板凳
samniuniu|  楼主 | 2014-2-19 16:43 | 只看该作者
       首先,我要感谢liuguobing网友,看了他的一篇帖子,我对低功耗了解了更多,这里给出原帖的精华部分,供大家参考:
//****************************************************************************************//
停机状态(无唤醒)
        1. PCB仅焊接MCU,电源3.3V,复位电容(10nF)和一个退偶电容(0.1uF), 程序中将所有GPIO确定输出低电平,主函数中直接halt(),电流约 1.730uA
        2. 在1的基础上,增加一条语句,PWR_UltraLowPowerCmd(ENABLE),或者 PWR->CSR2 = 0x2,再执行halt,电流下降至最低,0.400uA,达到官方指标
        3. 在实际产品上的测试(电路上增加了LCD,LSE晶振等),GPIO确定电平,超低功耗开启,停机状态 halt(),电流约 0.38uA
        4. 在3的基础上,开启RTC日历,电流约 1.3uA
        5. 初始化并开启LCD(未显示),最低电流约 2.25uA (LCD显示参数: 死区时间 7, 持续周期 0, HD=0,LCD外部电源)
        6. LCD正常工作,电流约 5.95uA (LCD显示参数: 死去时间 3, 持续周期 5, HD=0,LCD外部电源),显示效果均衡,LCD电流与LCD玻璃相关
        7. 在6的基础上,HD=1 电流约 18uA

低功耗运行状态        1. 将主时钟切换为 LSI,所有GPIO确定电平,开超低功耗,关RTC、LCD、LSE等,主函数执行 while(1), 电流约 95uA
        2. 在1的基础上,关电压调节器(默认开启),电流约 3.75uA;  达到标称电流值。
        3. 在2的基础上,将主时钟切换为 LSE,电流约为 4.32uA
        4. 在3的基础上,开启RTC,电流约为 4.59uA
        5. 在4的基础上,开启LCD(不显示),电流约为 8.8uA,LCD显示,电流约为 9.25uA

正常工作状态
        1. PCB仅焊接MCU,电源3.3V,复位电容(10nF)和一个退偶电容(0.1uF),程序中将所有GPIO确定输出低电平
        2. 在1的基础上,主函数直接执行 while(1),功耗在 930~950uA 波动 (默认2MHz)
        3. 在2的基础上,while(1) 中加入5个 nop(),功耗降低 200uA(即在730~750uA波动)
        4. 在3的基础上,将时钟配置位16MHz,功耗约为 3.7mA
        5. 在4的基础上,在while(1)中加入 wfi()/wfe(),功耗约为 720uA
        6. 在5的基础上,将时钟配置位1MHz,功耗约为 325uA

说明: 对于 stm8l 这类低功耗芯片,多数时候应该工作在停止或者等待状态,全速运行功耗意义不大,以下两个实际工作模拟
        1. 在一般定时显示程序中(主函数中延时500ms刷新显示),16MHz时钟,延时函数使用wfe功耗约1mA, 使用while(flag)功耗约4.5mA
        2. 在实际低功耗项目中,RTC和LCD一直工作,CPU脉冲工作,RTC约500ms唤醒一次,刷新显示,其电池寿命主要取决于LCD显示效果,正常一般可做到6uA,显示均衡
        3. 以上测试所用的LCD均为4*34段,如果更小的LCD,可能功耗更小
//******************************************************************************************//
https://bbs.21ic.com/forum.php?mod=viewthread&tid=670756原文链接

其次,我的那个问题也解决了,现在RTC和LCD都能正常工作了,解决方法如下:
软件上:1、使能RTC,日期初始化,这边RTC选择的时钟是LSE
              2、切换时钟(HSI-->LSE)切换时钟程序:
//====================================================================//
// 实现功能:时钟切换:HSE-->LSE
// 参    数:无
// 返 回 值:无
//====================================================================//
void HSE_TO_LSE(void)
{
  CLK_LSEConfig(CLK_LSE_ON);                    //目标CLK 先开启
  while (((CLK->ECKCR)& 0x08)!=0x08);           //等待目标CLK稳定,f=32768Hz
  CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);         //设定目标 CLK的分频参数
  CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_LSE); //设定此CLK 为切换目标CLK
  CLK_SYSCLKSourceSwitchCmd(ENABLE);            //开始CLK 切换
  CLK->SWCR |=0X01;                             //使能切换中断
  while (((CLK->SWCR)& 0x01)==0x01);            //等待切换后的CLK稳定
  CLK->SWCR &=0X00;
  CLK_HSICmd(DISABLE);                          //关闭原先的 CLK source
}
              3、LCD初始化,输入想要的数据,比如(20140214)
              4、HALT模式设置,设置如下
void Halt_Init(void)//设置低功耗
{
  CLK_HaltConfig(CLK_Halt_FastWakeup,ENABLE);//快速唤醒
  PWR->CSR2 |= 0x06;//ULP=1,FWU=1 //与上句一样
  GPIO_LowPower_Config();//配置GPIO口,这边把不需要的IO口都设置为低电平推挽输出,以降低功耗
}
                 5、halt();//进入低功耗模式
硬件上:
                 1、stm8l152的芯片引脚中的VLCD引脚最好接高电平并且再接一个电容后接地,如图

其中电容为4.7UF。(我之前一直没有接VCC,所以电平一直是低电平,虽然有信号,但是都不能点亮LCD)
                 2、选择好点的32768HZ的晶振,我后来选择的是MC306型号的晶振,之前选的晶振都无**常起振。

总结,得益于各位网友的帖子和评论,我现在做出的功耗为5.2uA。
我以上所说的可能有误或不全,希望大家补充~





使用特权

评论回复
地板
samniuniu|  楼主 | 2014-2-19 16:44 | 只看该作者
嵌入式云终端 发表于 2014-2-18 08:50
这样的问题要自己看编程手册哦,大家应用的不是很多,

嗯嗯,确实要多看看手册,后来问题解决了,我把方法写在了下面,你可以看下,希望继续补充~

使用特权

评论回复
5
嵌入式云终端| | 2014-2-19 18:43 | 只看该作者
学会自己解决问题,很有成就感的,多看看编程手册就好

使用特权

评论回复
6
FAQ| | 2014-2-19 19:16 | 只看该作者
samniuniu 发表于 2014-2-19 16:43
首先,我要感谢liuguobing网友,看了他的一篇帖子,我对低功耗了解了更多,这里给出原帖的精华部分 ...

总结,得益于各位网友的帖子和评论,我现在做出的功耗为5.2uA。

你这个5.2uA的时候LCD可以正常显示吧

使用特权

评论回复
7
samniuniu|  楼主 | 2014-2-19 20:14 | 只看该作者
FAQ 发表于 2014-2-19 19:16
总结,得益于各位网友的帖子和评论,我现在做出的功耗为5.2uA。

你这个5.2uA的时候LCD可以正常显示吧 ...

对的~

使用特权

评论回复
8
samniuniu|  楼主 | 2014-2-19 20:16 | 只看该作者
嵌入式云终端 发表于 2014-2-19 18:43
学会自己解决问题,很有成就感的,多看看编程手册就好

嗯嗯,是的呢~也谢谢你哦~

使用特权

评论回复
9
FAQ| | 2014-2-20 16:53 | 只看该作者
samniuniu 发表于 2014-2-19 20:16
嗯嗯,是的呢~也谢谢你哦~

我现在在做计数器,屏幕有5位数字,做低功耗的时候觉得很矛盾,就是让这5位数字同时显示的时候遇到问题,难道用像数码管动态扫描那样,那样的话单片机就得不停的扫,不能做低功耗了。显示一位数字低功耗我会做,多位呢。谢谢。

使用特权

评论回复
10
FAQ| | 2014-2-20 18:27 | 只看该作者
LCD不刷屏怎么能同时显示那么多位时间呢。

使用特权

评论回复
11
FAQ| | 2014-2-20 20:35 | 只看该作者
samniuniu 发表于 2014-2-19 20:14
对的~

多位数字不断改变显示,你的电流做到多少?

使用特权

评论回复
12
samniuniu|  楼主 | 2014-2-20 21:45 | 只看该作者
FAQ 发表于 2014-2-20 20:35
多位数字不断改变显示,你的电流做到多少?

我觉得可以这样做,在显示秒位的时候,进入正常模式,刷新一次,也就是说1s刷新一次,然后再进入低功耗模式,如果要刷新的话,CPU肯定是要工作的

使用特权

评论回复
13
samniuniu|  楼主 | 2014-2-20 21:47 | 只看该作者
FAQ 发表于 2014-2-20 20:35
多位数字不断改变显示,你的电流做到多少?

多位数字同时改变,我觉得不是在低功耗模式下做的,如果LCD显示的数字变化的话,CPU一定会运行

使用特权

评论回复
14
FAQ| | 2014-2-20 21:56 | 只看该作者
samniuniu 发表于 2014-2-20 21:47
多位数字同时改变,我觉得不是在低功耗模式下做的,如果LCD显示的数字变化的话,CPU一定会运行 ...

恩,我对这个屏幕的驱动原理还是清楚的,之前我都是用普通的单片机模拟出来的,翻转驱动波形。当时不需要做低功耗,直接像数码管动态扫描那样动态扫描的,当然我是翻转扫描的,不然屏幕会烧掉的。

当时做的只要求显示1到3三个数字,所以我把整个屏幕取模,每次显示都要刷新整个屏幕的。

但是这次的由于显示的数字组合太多了,比如要是5位数据的话那就是0到99999就有100000个屏幕模了,比如显示数字1,我要整个屏幕刷一次,显示11又要整个屏幕刷一次,这样的话就太麻烦了,我想应该是是用数码管那种扫描方法的吧。


但是这种动态扫描CPU肯定会工作,电流就很大了

使用特权

评论回复
15
FAQ| | 2014-2-20 22:02 | 只看该作者
samniuniu 发表于 2014-2-20 21:47
多位数字同时改变,我觉得不是在低功耗模式下做的,如果LCD显示的数字变化的话,CPU一定会运行 ...

你有没有想过这样的一种情况,比如钟表  显示格式为   12:34:56     让你做这个屏幕显示效果你会怎么做。


如果让我做,我会分步显示

具体实现是,比如我从右边往左,先让整个屏幕显示一个6,然后下一屏换成5,接着刷冒号,当然整个屏幕刷下来这个周期不超过50Hz,不然屏幕会闪。

不知道你是怎么做的。

使用特权

评论回复
16
samniuniu|  楼主 | 2014-2-20 22:48 | 只看该作者
FAQ 发表于 2014-2-20 22:02
你有没有想过这样的一种情况,比如钟表  显示格式为   12:34:56     让你做这个屏幕显示效果你会怎么做。 ...

我觉的可以按一下方法做:
比如改变一秒钟,那么就是从12:34:56到12:34:57
方法是:
...//之前的初始化程序,省略
Time_Show();//要显示的时间放在一个table中,待会给出Tim_Show();的函数
Halt_Init();//初始化halt模式
halt();//进入halt
...//这段程序等待wakeup,1s钟一次wakeup,此时CPU唤醒,进入中断
//***中断程序****//
RTC_GetTime(RTC_Format_BIN, &RTC_TimeStr);//得到现在的时间
Time_Show();//刷新一次,全部都刷一次
然后再进入halt模式

以下是Time_Show函数
void Time_Show(void)
{
  u16 table[4];
  table[0]=RTC_TimeStr.RTC_Hours/10+0x30;
  table[1]=RTC_TimeStr.RTC_Hours%10+0x30;
  table[1]|=DOUBLE_DOT;
  table[2]=RTC_TimeStr.RTC_Minutes/10+0x30;
  table[3]=RTC_TimeStr.RTC_Minutes%10+0x30;
  table[3]|=DOUBLE_DOT;
//  table[4]=RTC_TimeStr.RTC_Seconds/10+0x30;
//  table[5]=RTC_TimeStr.RTC_Seconds%10+0x30;
  LCD_GLASS_DisplayStrDeci(table);
}

不知道我的方法对不对。。。。请指正


使用特权

评论回复
17
axushilong| | 2014-8-20 15:53 | 只看该作者
请教stm8l 低功耗运行模式,我的代码如下:
void main(void)
{
        AllGpioRPPLowOut();        //配置IO为推免输出低电平
        HSItoLSI();
        PWR->CSR2 = 0x2;
        LCD_GLASS_Init();
//        CLK->REGCSR = 0x02;        // Swith off the Regulator
//        while(((CLK->REGCSR)&0x01)==0x01);
        while(1) LCD_GLASS_ScrollSentence("      ** STM8L-DISCOVERY **",1,SCROLL_SPEED);
}
上面代码电流为100uA,LCD屏能正常显示;
如果去掉注释,也就是说关闭电压调节器,电流为10uA左右,可是此时LCD屏不显示,请问这是怎么回事?怎么解决啊?
为什么一关闭电压调节器就不显示了?
上面两个函数LCD_GLASS_Init和LCD_GLASS_ScrollSentence
都是stm8L-discover评估板程序的函数,没做改动。

使用特权

评论回复
18
genggegengge| | 2015-10-21 10:40 | 只看该作者
网友在啊,我在做STM8L低功耗的实验,一直没搞明白低功耗该怎样做,想向你请教,谢谢,我的QQ1845395137

使用特权

评论回复
19
温庆瑞| | 2016-10-18 09:14 | 只看该作者
你进入 Halt(); 前别用 LCD_GLASS_Clear();函数清LCD就行,他会一直显示。 当你RTC下一次唤醒后清一次LCD再显示就OK。

使用特权

评论回复
20
gyh974| | 2017-9-10 10:29 | 只看该作者

使用特权

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

本版积分规则

4

主题

26

帖子

3

粉丝