找回密码
 立即注册
查看: 1285|回复: 18

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

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:353
  • 最近打卡:2025-05-04 01:05:06
已绑定手机

130

主题

1522

回帖

1871

积分

金牌会员

积分
1871
发表于 2024-7-3 20:58:20 | 显示全部楼层 |阅读模式
手电的功能弄好了.

功耗太高,有2ma,估计放几天就没电了
设置了掉电模式 pcon = 0x02;
没有电流了.但是问题来了.
不会唤醒了
现在是按P32 开关和调光.
想用P32直接拿来唤醒.按下打开手电并退出掉电模式
关闭的时候 开启掉电模式
  1. #include <STC8G.H>
  2. #include "intrins.h"
  3.   
  4. #define MAIN_Fosc 11059200UL
  5. unsigned int pwm_levels[] = {5,15 ,80,255 };
  6. unsigned char PWM_SAVE;
  7. sbit KEY1 = P3^2;
  8. bit key_flag;
  9. unsigned char PWM_MODE;
  10. unsigned char time_out;
  11. void PWM_init(void)
  12. {
  13.     CCON = 0x00;
  14.     CMOD = 0x08;
  15.     CL = 0x00;
  16.     CH = 0x00;
  17.     CCAPM1 = 0x42;
  18.     PCA_PWM1 = 0x00;
  19.     CCAP1L = 0x00;                  
  20.     CCAP1H = 0x00;
  21.         CR=1;       
  22. }
  23. //void pwm_init(void);
  24. //void delayms(u16 ms);       
  25. //void pwm_init(void)
  26. //{
  27. //       
  28. //    CCON = 0x00;
  29. //    CMOD = 0x08;
  30. //    CL = 0x00;
  31. //    CH = 0x00;
  32. //    CCAPM1 = 0x42;
  33. //    PCA_PWM1 = 0x00;
  34. //    CCAP1L = ld;                  
  35. //    CCAP1H = ld;
  36. //        CR=1;       
  37. ////        while(1);
  38. //}
  39. void PWM_updata(unsigned int duty) {
  40.     if(duty > 0) {                              // 如果占空比大于0
  41.         CCAP1L = duty;                       // 更新CCR4计数值
  42.           CCAP1H = duty;  
  43.         CCAPM1 = 0x42;                         // 使能PWM输出
  44.         
  45.     } else {
  46.         CCAP1L = 0x00;                       
  47.           CCAP1H = 0x00;  
  48.         CCAPM1 = 0x00;                     
  49. //        P33 = 1; P34 = 1;                       // 将P3.3和P3.4设置为高电平
  50.     }
  51. }
  52. // 定时器0中断服务程序
  53. void Timer0_Isr(void) interrupt 1 {
  54.   
  55.         static unsigned char key_sta;               // 按键状态机变量
  56.     // 按键状态机
  57.     switch(key_sta) {
  58.         case 0:                                 // 状态0:等待按键
  59.             if (KEY1 == 0) key_sta++;            // 如果按键按下,进入状态1
  60.             break;
  61.         case 1:                                 // 状态1:确认按键
  62.             if (KEY1 == 0) key_sta++;            // 如果按键持续按下,进入状态2
  63.             else key_sta = 0;                   // 否则返回状态0
  64.             break;
  65.         case 2:                                 // 状态2:等待按键释放
  66.             if (KEY1 == 1) key_sta++;            // 如果按键释放,进入状态3
  67.             break;
  68.         case 3:                                 // 状态3:按键完成
  69.             key_flag = 1;                       // 设置按键标志位
  70.             key_sta = 0;                        // 重置状态机
  71.             break;
  72.         default:                                // 默认状态,重置状态机
  73.             key_sta = 0;
  74.             break;
  75.     }
  76.    
  77.     if (time_out < 30) time_out++;              // 如果未超时,增加超时计数器
  78. }
  79. void Timer0_Init(void) {
  80.     AUXR &= 0x7F;                               // 设置定时器时钟为12T模式
  81.     TMOD &= 0xF0;                               // 设置定时器模式
  82.     TL0 = 0x00;                                 // 设置定时初值低字节
  83.     TH0 = 0x4C;                                 // 设置定时初值高字节
  84.     TF0 = 0;                                    // 清除TF0标志
  85.     TR0 = 1;                                    // 开始定时器0计时
  86.     IE = 0x02;                                  // 开启定时器0中断
  87. }
  88.   
  89. void delayms(unsigned int ms)
  90. {
  91.         unsigned int i;
  92.         do{
  93.                 i = MAIN_Fosc /10000;
  94.                 while(--i);
  95.         }while(--ms);
  96. }
  97. void main()
  98. {
  99.    P_SW2=0x80;                                   // 初始化扩展寄存器
  100.     P0M0 = P0M1 = P1M0 = P1M1 = P2M0 = P2M1 = P3M0 = P3M1 = P4M0 = P4M1 = P5M0 = P5M1 = P6M0 = P6M1 = P7M0 = P7M1 = 0x00;
  101.                          
  102.         PWM_init();  
  103.         Timer0_Init();                              // 初始化定时器0
  104.         EA=1;
  105.        
  106.         PCON|=0x02;        _nop_();_nop_();_nop_();        //设置掉电模式
  107.        
  108. while(1)
  109. {            
  110.         if(key_flag) {                          // 如果有按键事件
  111.             key_flag = 0;                       // 清除按键标志位
  112.             if (time_out < 30) {                // 如果按键没有超时
  113.                 PWM_MODE++;                     // 增加PWM模式
  114.                 if(PWM_MODE > (sizeof(pwm_levels)/sizeof(pwm_levels[0]))) // 防止超出数组范围
  115.                     PWM_MODE = 1;               // 循环回第一个模式
  116.                
  117.                 PWM_updata(pwm_levels[PWM_MODE - 1]); // 更新PWM占空比
  118.                 time_out = 0;                   // 重置超时计数器
  119.             } else {                            // 如果按键超时
  120.                 if(PWM_MODE) {                  // 如果有输出状态
  121.                     PWM_SAVE = PWM_MODE;        // 保存当前PWM模式
  122.                     PWM_MODE = 0;               // 清空PWM模式
  123.                     PWM_updata(0);              // 关闭PWM输出
  124.                 } else {                        // 如果处于关闭状态
  125.                     if(PWM_SAVE == 0) PWM_SAVE = 1; // 首次按键启动最低亮度
  126.                     PWM_MODE = PWM_SAVE;        // 恢复之前的PWM模式
  127.                     time_out = 0;               // 重置超时计数器
  128.                    PWM_updata(pwm_levels[PWM_MODE - 1]);    // 更新PWM占空比(此处的PWM_MODE*20可能是错误的,应该使用pwm_levels数组)
  129.                 }
  130.             }
  131.         }
  132.     }
  133. }
  134.          
  135. //      if (KEY1 == 0) {
  136. //            delayms(10);
  137. //            if (KEY1 == 0) {
  138. //                      if (noShiftTime >= 3000 ) {
  139. //                    ld = 0; // 关闭LED  
  140. //                        }
  141. //                       
  142. //                gear = (gear + 1) % 5; // 切换档位,循环回到0  
  143. //                while (!KEY1); // 等待按钮释放  
  144. //                 noShiftTime = 0;        
  145. //            }  
  146. //        }  
  147. //       
  148. //                 // 检查是否长时间未换挡  
  149. //        if (noShiftTime >= 3000) { // 如果3秒(或3000毫秒)未换挡  
  150. //            gear = 0; // 可以选择将档位重置为0或其他默认档位  
  151. //            ld = 0; // 关闭LED  
  152. //            noShiftTime = 0; // 重置计时器  
  153. //        }  
  154. //          
  155. //          
  156. //         
  157. //        switch (gear) {  
  158. //            case 0:  
  159. //                        ld=0;
  160. //                break;  
  161. //            case 1:  
  162. //                ld=2;  
  163. //                break;  
  164. //            case 2:  
  165. //                ld=15;  
  166. //                break;  
  167. //            case 3:  
  168. //   
  169. //                ld=30;  
  170. //                break;  
  171. //                          case 4:  
  172. //   
  173. //                ld=255;  
  174. //                break;  
  175. //        }  
  176. //  delayms(10);
  177. //    }  
  178. //}
复制代码


回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:353
  • 最近打卡:2025-05-04 01:05:06
已绑定手机

130

主题

1522

回帖

1871

积分

金牌会员

积分
1871
发表于 2024-7-4 00:38:30 | 显示全部楼层
我的思路是这样的,
if (ld==0)        PCON|=0x02;
然后就是捕获一个 KEY1的上升或者下降沿,关闭掉电模式
这样就可以 按下KEY1打开led,3秒内再按就换挡, 3秒后按KEY1 就是关闭LED,这个时候 ld=0,又进入了掉电模式

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

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:353
  • 最近打卡:2025-05-04 01:05:06
已绑定手机

130

主题

1522

回帖

1871

积分

金牌会员

积分
1871
发表于 2024-7-4 00:41:14 | 显示全部楼层
这个程序没有ld
那就应该是 if (CCAP1L==0) PCON|=0x02;
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:324
  • 最近打卡:2025-05-04 09:44:01
已绑定手机

21

主题

487

回帖

1049

积分

金牌会员

积分
1049
发表于 2024-7-4 08:10:11 | 显示全部楼层
嗯,正好学习一下,单片机的很多功能还未用到过,但是以后肯定有用的到的时候
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-03-12 16:14:06

7

主题

59

回帖

984

积分

高级会员

积分
984
发表于 2024-7-4 09:25:27 | 显示全部楼层
打开P32的中断就行了,外部中断可以唤醒MCU
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:353
  • 最近打卡:2025-05-04 01:05:06
已绑定手机

130

主题

1522

回帖

1871

积分

金牌会员

积分
1871
发表于 2024-7-4 09:59:42 | 显示全部楼层
御坂美*** 发表于 2024-7-4 09:25
打开P32的中断就行了,外部中断可以唤醒MCU

现在多次按P32可以唤醒mcu,
但是后面不会配置重新打开mcu了
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-03-12 16:14:06

7

主题

59

回帖

984

积分

高级会员

积分
984
发表于 2024-7-4 10:10:50 | 显示全部楼层
vb2*** 发表于 2024-7-4 09:59
现在多次按P32可以唤醒mcu,
但是后面不会配置重新打开mcu了

啊这,是不会再次休眠还是?
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:353
  • 最近打卡:2025-05-04 01:05:06
已绑定手机

130

主题

1522

回帖

1871

积分

金牌会员

积分
1871
发表于 2024-7-4 10:25:46 | 显示全部楼层
wnag*** 发表于 2024-7-4 08:03
掉电模式要通过外部中断唤醒,你把P3^2脚的外部中断配置好就能退出掉电模式 ...

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

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:353
  • 最近打卡:2025-05-04 01:05:06
已绑定手机

130

主题

1522

回帖

1871

积分

金牌会员

积分
1871
发表于 2024-7-4 10:26:40 | 显示全部楼层
御坂美*** 发表于 2024-7-4 10:10
啊这,是不会再次休眠还是?

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

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-03-12 16:14:06

7

主题

59

回帖

984

积分

高级会员

积分
984
发表于 2024-7-4 11:43:25 | 显示全部楼层
vb2*** 发表于 2024-7-4 10:26
是的, 唤醒以后,就不会再次进入掉电模式了
需要重新上点才能进入.
可能是代码哪里没有处理好

我看你代码里面就进while之前睡了一次,while里面就没有判断再次进入睡眠的代码了
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-4 10:19 , Processed in 0.132291 second(s), 105 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表