vb2002 发表于 2024-7-4 11:53:38

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

现在弄好了. 但是又有新问题了
不是手册上说的 掉电模式 0.4UA   而是 105UA
#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 INT0_Isr() interrupt 0
{
    P10 = !P10;                                 //测试端口
}


void main()
{
   P_SW2=0x80;                                 // 初始化扩展寄存器
   P3M0 = P3M1 =0x00;
                         
        PWM_init();

        Timer0_Init();                              // 初始化定时器0
        IT0=1;EX0=1;
        EA=1;
        _nop_();_nop_();_nop_();_nop_();
        PCON=0x02;_nop_();_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数组)
               
        PCON=0x02;_nop_();_nop_();_nop_();_nop_();

                  }
            }
      }
    }
}





       
//      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 12:19:53

御坂美琴我老婆 发表于 2024-7-4 11:43
我看你代码里面就进while之前睡了一次,while里面就没有判断再次进入睡眠的代码了 ...

这下完美了..哈哈哈哈哈哈哈哈

就是功耗有点点大,之前手册写的掉电模式0.4ua   ,但是我的是 110ua
不懂是哪里出状况了
#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 INT0_Isr() interrupt 0
{

}


void main()
{
   P_SW2=0x80;                                 // 初始化扩展寄存器
   P3M0 = P3M1 =0x00;
                         
        PWM_init();

        Timer0_Init();                              // 初始化定时器0
        IT0=1;EX0=1;
        EA=1;
        _nop_();_nop_();_nop_();_nop_();
        PCON=0x02;_nop_();_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(CCAP1H==0x00)
                              PCON=0x02;_nop_();_nop_();_nop_();_nop_();
            }
               
      }
       
    }
}


vb2002 发表于 2024-7-4 12:20:16

wnagming 发表于 2024-7-4 12:02
你看看你测得是单片机的功耗吗?没有测量外围器件的功耗?,单独测试单片机功耗 ...

掉电模式下,外围不是都关电了吗?

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

vb2002 发表于 2024-7-4 11:53
现在弄好了. 但是又有新问题了
不是手册上说的 掉电模式 0.4UA   而是 105UA
...

不需要的引脚关掉输入

御坂美琴我老婆 发表于 2024-7-4 12:28:51

vb2002 发表于 2024-7-4 12:19
这下完美了..哈哈哈哈哈哈哈哈

就是功耗有点点大,之前手册写的掉电模式0.4ua   ,但是我的是 110ua


不需要的引脚关掉,我看你这个就留P32,P31,P30应该就行
P0IE = 0x00;
P1IE = 0x00;
P2IE = 0x00;
P3IE = 0x06;
P4IE = 0x00;
P5IE = 0x00;
P6IE = 0x00;
P7IE = 0x00;
然后就是看你的标准双向口,有没有休眠之前写0的情况,因为弱上拉置零要消耗个十来uA,所以休眠之前就弄成开漏置零,起来再换成标准双向

御坂美琴我老婆 发表于 2024-7-4 12:29:49

vb2002 发表于 2024-7-4 12:19
这下完美了..哈哈哈哈哈哈哈哈

就是功耗有点点大,之前手册写的掉电模式0.4ua   ,但是我的是 110ua


写错了,应该是P3IE = 0x07;

vb2002 发表于 2024-7-4 12:36:03

御坂美琴我老婆 发表于 2024-7-4 12:29
写错了,应该是P3IE = 0x07;

我试试看,是不是IO口的问题
我用范例程序里面的掉电模式,确实是0.04ua
用我这个代码就不行了

vb2002 发表于 2024-7-4 12:50:56

御坂美琴我老婆 发表于 2024-7-4 12:29
写错了,应该是P3IE = 0x07;

现在掉电电流0.4ua了
因为之前io口没有配置p54,,
我的p54弄成复位按键了

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

vb2002 发表于 2024-7-4 12:50
现在掉电电流0.4ua了
因为之前io口没有配置p54,,
我的p54弄成复位按键了


OK,那没问题了{:4_164:}
页: 1 [2]
查看完整版本: 手电的待机功耗太高了.2ma .设置了掉电模式, 尴尬,不会唤醒