vb2002 发表于 2024-7-3 20:58:20

手电的待机功耗太高了.2ma .设置了掉电模式, 尴尬,不会唤醒

手电的功能弄好了.

功耗太高,有2ma,估计放几天就没电了
设置了掉电模式 pcon = 0x02;
没有电流了.但是问题来了.
不会唤醒了
现在是按P32 开关和调光.
想用P32直接拿来唤醒.按下打开手电并退出掉电模式
关闭的时候 开启掉电模式
#include <STC8G.H>
#include "intrins.h"

#define MAIN_Fosc 11059200UL
unsigned int pwm_levels[] = {5,15 ,80,255 };

unsigned char PWM_SAVE;
sbit KEY1 = P3^2;
bit key_flag;
unsigned char PWM_MODE;
unsigned char time_out;

void PWM_init(void)
{
    CCON = 0x00;
    CMOD = 0x08;
    CL = 0x00;
    CH = 0x00;

    CCAPM1 = 0x42;
    PCA_PWM1 = 0x00;
    CCAP1L = 0x00;                  
    CCAP1H = 0x00;
        CR=1;       
}


//void pwm_init(void);
//void delayms(u16 ms);       

//void pwm_init(void)
//{
//       
//    CCON = 0x00;
//    CMOD = 0x08;
//    CL = 0x00;
//    CH = 0x00;

//    CCAPM1 = 0x42;
//    PCA_PWM1 = 0x00;
//    CCAP1L = ld;                  
//    CCAP1H = ld;

//        CR=1;       
////        while(1);
//}

void PWM_updata(unsigned int duty) {
    if(duty > 0) {                              // 如果占空比大于0
      CCAP1L = duty;                     // 更新CCR4计数值
          CCAP1H = duty;
      CCAPM1 = 0x42;                         // 使能PWM输出
      
    } else {
      CCAP1L = 0x00;                     
          CCAP1H = 0x00;
      CCAPM1 = 0x00;                     
//      P33 = 1; P34 = 1;                     // 将P3.3和P3.4设置为高电平
    }
}


// 定时器0中断服务程序
void Timer0_Isr(void) interrupt 1 {

        static unsigned char key_sta;               // 按键状态机变量

    // 按键状态机
    switch(key_sta) {
      case 0:                                 // 状态0:等待按键
            if (KEY1 == 0) key_sta++;            // 如果按键按下,进入状态1
            break;
      case 1:                                 // 状态1:确认按键
            if (KEY1 == 0) key_sta++;            // 如果按键持续按下,进入状态2
            else key_sta = 0;                   // 否则返回状态0
            break;
      case 2:                                 // 状态2:等待按键释放
            if (KEY1 == 1) key_sta++;            // 如果按键释放,进入状态3
            break;
      case 3:                                 // 状态3:按键完成
            key_flag = 1;                     // 设置按键标志位
            key_sta = 0;                        // 重置状态机
            break;
      default:                              // 默认状态,重置状态机
            key_sta = 0;
            break;
    }

   
    if (time_out < 30) time_out++;            // 如果未超时,增加超时计数器
}

void Timer0_Init(void) {
    AUXR &= 0x7F;                               // 设置定时器时钟为12T模式
    TMOD &= 0xF0;                               // 设置定时器模式
    TL0 = 0x00;                                 // 设置定时初值低字节
    TH0 = 0x4C;                                 // 设置定时初值高字节
    TF0 = 0;                                    // 清除TF0标志
    TR0 = 1;                                    // 开始定时器0计时
    IE = 0x02;                                  // 开启定时器0中断
}


void delayms(unsigned int ms)
{
        unsigned int i;
        do{
                i = MAIN_Fosc /10000;
                while(--i);
        }while(--ms);
}

void main()
{
   P_SW2=0x80;                                 // 初始化扩展寄存器
    P0M0 = P0M1 = P1M0 = P1M1 = P2M0 = P2M1 = P3M0 = P3M1 = P4M0 = P4M1 = P5M0 = P5M1 = P6M0 = P6M1 = P7M0 = P7M1 = 0x00;
                         
        PWM_init();
        Timer0_Init();                              // 初始化定时器0
        EA=1;
       
        PCON|=0x02;        _nop_();_nop_();_nop_();        //设置掉电模式

       
while(1)
{          
      if(key_flag) {                        // 如果有按键事件

            key_flag = 0;                     // 清除按键标志位

            if (time_out < 30) {                // 如果按键没有超时
                PWM_MODE++;                     // 增加PWM模式
                if(PWM_MODE > (sizeof(pwm_levels)/sizeof(pwm_levels))) // 防止超出数组范围
                  PWM_MODE = 1;               // 循环回第一个模式
               
                PWM_updata(pwm_levels); // 更新PWM占空比
                time_out = 0;                   // 重置超时计数器
            } else {                            // 如果按键超时
                if(PWM_MODE) {                  // 如果有输出状态
                  PWM_SAVE = PWM_MODE;      // 保存当前PWM模式
                  PWM_MODE = 0;               // 清空PWM模式
                  PWM_updata(0);            // 关闭PWM输出
                } else {                        // 如果处于关闭状态
                  if(PWM_SAVE == 0) PWM_SAVE = 1; // 首次按键启动最低亮度
                  PWM_MODE = PWM_SAVE;      // 恢复之前的PWM模式
                  time_out = 0;               // 重置超时计数器
                   PWM_updata(pwm_levels);    // 更新PWM占空比(此处的PWM_MODE*20可能是错误的,应该使用pwm_levels数组)
                }
            }
      }
    }
}


       
//      if (KEY1 == 0) {
//            delayms(10);
//            if (KEY1 == 0) {
//                      if (noShiftTime >= 3000 ) {
//                  ld = 0; // 关闭LED
//                        }
//                       
//                gear = (gear + 1) % 5; // 切换档位,循环回到0
//                while (!KEY1); // 等待按钮释放
//               noShiftTime = 0;        
//            }
//      }
//       
//                 // 检查是否长时间未换挡
//      if (noShiftTime >= 3000) { // 如果3秒(或3000毫秒)未换挡
//            gear = 0; // 可以选择将档位重置为0或其他默认档位
//            ld = 0; // 关闭LED
//            noShiftTime = 0; // 重置计时器
//      }
//          
//          
//         
//      switch (gear) {
//            case 0:

//                        ld=0;
//                break;
//            case 1:

//                ld=2;
//                break;
//            case 2:

//                ld=15;
//                break;
//            case 3:
//   
//                ld=30;
//                break;
//                        case 4:
//   
//                ld=255;
//                break;
//      }
//delayms(10);
//    }
//}








vb2002 发表于 2024-7-4 00:38:30

我的思路是这样的,
if (ld==0)        PCON|=0x02;
然后就是捕获一个 KEY1的上升或者下降沿,关闭掉电模式
这样就可以 按下KEY1打开led,3秒内再按就换挡, 3秒后按KEY1 就是关闭LED,这个时候 ld=0,又进入了掉电模式

思路这样没问题了. 但是代码不会植入,尝试了蛮多方法,弄不来

vb2002 发表于 2024-7-4 00:41:14

这个程序没有ld
那就应该是 if (CCAP1L==0) PCON|=0x02;

llyymm 发表于 2024-7-4 08:10:11

嗯,正好学习一下,单片机的很多功能还未用到过,但是以后肯定有用的到的时候

御坂美琴我老婆 发表于 2024-7-4 09:25:27

打开P32的中断就行了,外部中断可以唤醒MCU

vb2002 发表于 2024-7-4 09:59:42

御坂美琴我老婆 发表于 2024-7-4 09:25
打开P32的中断就行了,外部中断可以唤醒MCU

现在多次按P32可以唤醒mcu,
但是后面不会配置重新打开mcu了{:4_266:}

御坂美琴我老婆 发表于 2024-7-4 10:10:50

vb2002 发表于 2024-7-4 09:59
现在多次按P32可以唤醒mcu,
但是后面不会配置重新打开mcu了

啊这,是不会再次休眠还是?{:4_184:}

vb2002 发表于 2024-7-4 10:25:46

wnagming 发表于 2024-7-4 08:03
掉电模式要通过外部中断唤醒,你把P3^2脚的外部中断配置好就能退出掉电模式 ...

现在重新上点直接进入掉电模式
然后按键后可以唤醒mcu.
接下来不懂怎么处理,再次进入掉电模式了

vb2002 发表于 2024-7-4 10:26:40

御坂美琴我老婆 发表于 2024-7-4 10:10
啊这,是不会再次休眠还是?

是的, 唤醒以后,就不会再次进入掉电模式了
需要重新上点才能进入.
可能是代码哪里没有处理好

御坂美琴我老婆 发表于 2024-7-4 11:43:25

vb2002 发表于 2024-7-4 10:26
是的, 唤醒以后,就不会再次进入掉电模式了
需要重新上点才能进入.
可能是代码哪里没有处理好


我看你代码里面就进while之前睡了一次,while里面就没有判断再次进入睡眠的代码了
页: [1] 2
查看完整版本: 手电的待机功耗太高了.2ma .设置了掉电模式, 尴尬,不会唤醒