找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1923|回复: 6
收起左侧

初学者求修改单片机掉电模式过程中自动唤醒且可手动唤醒的程序

[复制链接]
ID:1136514 发表于 2024-11-29 17:08 | 显示全部楼层 |阅读模式
200黑币
硬件:
1、使用stc8g1k08a-8pin单片机
2、手动按键(sdkey)、设置按键(szkey)、3个指示灯,输出led灯。 51hei.png
程序需求:
1、按设置键设置led灯亮的时间,
(指示灯1亮表示3秒、
   指示灯2亮表示6秒、
   指示灯3亮表示9秒、
   指示灯3和1亮表示12秒
   指示灯3和2亮表示15秒
   指示灯3和2和1全亮表示18秒)
2、设置后按(sdkey)键可验证led运行时间、
3、led灭后10秒进入掉电模式,掉电模式24小时后,led自动按设置时长亮灯,10秒后再次进入掉电模式,如此循环。
4、在掉电模式(24小时)过程中,手动(sdkey 或szkey)可唤醒,唤醒后,led按照设置时长亮灯,并可进行第1步和第2步操作。
求修改:
#include <stc8g.h>
#include <intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
u8 ms;time1;time2;
u16 mode;
sbit led = P3^0;
sbit sdkey = P3^2;
sbit szkey = P5^4;
sbit led1 = P3^1;
sbit led2 = P5^5;
sbit led3 = P3^3;
/*************/
void delay(unsigned int y)
{
unsigned int x,z;
for (x=y;x>0;x--);
for (z=110;z>0;z--);
}
/****************/
void sz()
{
  switch(mode)
   {
    case(0):led1=0;led2=1;led3=1;break;
    case(1):led1=1;led2=0;led3=1;break;
    case(2):led1=1;led2=1;led3=0;break;
    case(3):led1=0;led2=1;led3=0;break;
    case(4):led1=1;led2=0;led3=0;break;
    case(5):led1=0;led2=0;led3=0;break;
   }
}
/****************/
void main()
{
  P1 = 0xff;
  P3 = 0xff;
  P5 = 0xff;
  P1M0 = 0x00;
  P1M1 = 0x00;
  P_SW1 = 0x00;
  P3M0 = 0x00;
  P3M1 = 0x00;
  P5M0 = 0x00;
  P5M1 = 0x00;
  WKTCL = 0xff; //设定掉电唤醒时钟约为1秒钟
  WKTCH = 0x87;
  TMOD = 0x01;
  TH0=(65536-50000)/256;
  TL0=(65536-50000)%256;
  EA=1;
  ET0=1;
  TR0=1;
  while(1)
    {
     ;
    }
}
/********************/
void server(void) interrupt 1
{
unsigned char i;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
ms++;
if(ms>=20)
   {
    ms = 0;
    time1++;
    if(time1==1)
      {
      led=0;//
      }
    if(time1==1+3+time2)
      {
      led=1;
      }
    if(time1==1+3+time2+10)
      { time1=0;
        led1=led2=led3=1;
        i=86400;
        while(i--)
          {
           PCON=0x02;
           _nop_();
           _nop_();
          }
       }
   }
/****************/
sz();
  if(szkey==0)
   {
    delay(10);
    if(szkey==0)
     {
      mode++;
      time1=1;
      if(mode==6)
       {
        mode=0;
       }
        while(!szkey);
     }
   }
/****************/
if (mode==0)
    {
    time2=0;
    }
if (mode==1)
    {
    time2=3;
    }
if (mode==2)
    {
    time2=6;
    }
if (mode==3)
    {
    time2=9;
    }
if (mode==4)
    {
    time2=12;
    }
if (mode==5)
    {
    time2=15;
    }

/******************/
if(sdkey==0)
        {
         delay(5);
         while(sdkey==0)
           {
            led = 0;
            time1 = 1;
           }
         }              
}
/******************/
                              

回复

使用道具 举报

ID:161164 发表于 2024-11-29 17:08 | 显示全部楼层
  1. #include <stc8g.h>
  2. #include <intrins.h>
  3. typedef unsigned char u8;
  4. typedef unsigned int u16;
  5. u8 ms,time1,time2;
  6. u16 Sec = 0;
  7. u8 hr = 0;
  8. u16 mode;
  9. sbit led = P3^0;
  10. sbit sdkey = P3^2;
  11. sbit szkey = P5^4;
  12. sbit led1 = P3^1;
  13. sbit led2 = P5^5;
  14. sbit led3 = P3^3;
  15. /*************/
  16. void delay(unsigned int y)
  17. {
  18.         unsigned int x,z;
  19.         for (x=y; x>0; x--);
  20.         for (z=110; z>0; z--);
  21. }
  22. /****************/
  23. void sz()
  24. {
  25.   switch(mode)
  26.    {
  27.     case(0):led1=0;led2=1;led3=1;time2=3;break;
  28.     case(1):led1=1;led2=0;led3=1;time2=6;break;
  29.     case(2):led1=1;led2=1;led3=0;time2=9;break;
  30.     case(3):led1=0;led2=1;led3=0;time2=12;break;
  31.     case(4):led1=1;led2=0;led3=0;time2=15;break;
  32.     case(5):led1=0;led2=0;led3=0;time2=18;break;
  33.    }
  34. }
  35. void led_On()
  36. {
  37.         led = 0;
  38.         ms = 0;
  39.         time1 = time2 + 10;       
  40.         EX0 = 0;
  41. }
  42. void INT0_ISR() interrupt 0
  43. {
  44.         led_On();
  45. }
  46. /****************/
  47. void main()
  48. {
  49.         P3 = 0xff;
  50.         P5 = 0xff;
  51.         P_SW1 = 0x00;
  52.         P3M0 = 0x00;
  53.         P3M1 = 0x00;
  54.         P5M0 = 0x00;
  55.         P5M1 = 0x00;
  56.         WKTCL = 0xff; //设定掉电唤醒时钟约为1秒钟
  57.         WKTCH = 0x87;
  58.         TMOD = 0x00;
  59.         TH0=(65536-50000)/256;
  60.         TL0=(65536-50000)%256;
  61.         EA=1;
  62.         ET0=1;
  63.         TR0=1;
  64.         IT0 = 1;
  65.         EX0 = 0;
  66.         time1 = 10;
  67.         while(1)
  68.         {
  69.                 if(szkey==0)
  70.                 {
  71.                         delay(10);
  72.                         if(szkey==0)
  73.                         {
  74.                                 sz();
  75.                                 mode++;
  76.                                 if(mode==6)
  77.                                 {
  78.                                         mode=0;
  79.                                 }
  80.                                 while(!szkey);
  81.                         }
  82.                 }
  83.                 /******************/
  84.                 if(sdkey==0)
  85.                 {
  86.                         delay(5);
  87.                         if(sdkey==0)
  88.                         {
  89.                                 led_On();
  90.                         }               
  91.                         while(sdkey==0);
  92.                 }
  93.                 if(time1==0xFF)
  94.                 {
  95.                         PCON=0x02;
  96.                         _nop_();
  97.                         _nop_();
  98.                         if(Sec++>=3600)
  99.                         {
  100.                                 Sec = 0;
  101.                                 if(hr++>=24)
  102.                                 {
  103.                                         hr = 0;
  104.                                         led_On();
  105.                                 }
  106.                         }
  107.                 }
  108.         }
  109. }
  110. /********************/
  111. void server(void) interrupt 1
  112. {
  113.         if(time1)
  114.         {
  115.                 ms++;
  116.                 if(ms>=20)
  117.                 {
  118.                         ms = 0;
  119.                         time1--;
  120.                         if(time1<10)led = 1;
  121.                         if(time1==0)
  122.                         {
  123.                                 time1=0xFF;
  124.                                 led1=led2=led3=1;
  125.                                 Sec = 0;
  126.                                 hr = 0;
  127.                                 IE0 = 0;
  128.                                 EX0 = 1;
  129.                         }
  130.                 }
  131.         }
  132. }
  133.         /******************/
复制代码
回复

使用道具 举报

ID:1133081 发表于 2024-11-30 08:16 | 显示全部楼层
楼主想实现的功能本身没有多少难度。需要使用内部掉电唤醒定时器,如果不是用电池供电没必要使用掉电模式,掉电唤醒定时器误差很大。另外还要使用EEPROM保存设置值。用一个按键接外部中断脚,睡眠状态短按外部中断唤醒,工作状态外部中断脚改为普通IO,长按2秒进入设置,3个指示灯闪烁,短按3个指示灯按2进制方式可显示7个设置状态,停按5~10秒自动退出设置状态并将设置值保存在EEPROM,如果断电下次重启不会改变运行方式。

评分

参与人数 1黑币 +30 收起 理由
admin + 30 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:1136514 发表于 2024-11-30 10:36 | 显示全部楼层
WL0123 发表于 2024-11-30 08:16
楼主想实现的功能本身没有多少难度。需要使用内部掉电唤醒定时器,如果不是用电池供电没必要使用掉电模式, ...

就是用电池供电使用的,目前就是,进入掉电循环后,不能手动唤醒,改手动唤醒后又不能自动进入掉电循环,所以求大佬给改一下程序,改为需要即可自动运行,又可手动唤醒的程序

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:1133081 发表于 2024-11-30 16:37 | 显示全部楼层
zhaojiechao 发表于 2024-11-30 10:36
就是用电池供电使用的,目前就是,进入掉电循环后,不能手动唤醒,改手动唤醒后又不能自动进入掉电循环, ...

手动唤醒和自动唤醒都不是问题,但24小时自动唤醒有点麻烦。因为睡眠后定时器也停止工作。掉电唤醒定时器的最长时间很有限。
回复

使用道具 举报

ID:624769 发表于 2024-11-30 17:51 | 显示全部楼层
zhaojiechao 发表于 2024-11-30 10:36
就是用电池供电使用的,目前就是,进入掉电循环后,不能手动唤醒,改手动唤醒后又不能自动进入掉电循环, ...

你是不是搞明白 中断唤醒 是什么意思?
除了定时唤醒之外,要唤醒单片机,都是通过 中断 来唤醒的。即,你要产生  中断。就要有中断产生。
假定,你是想通过sdkey 唤醒。
那么,EX0 = 1; 呢?
void EX0_INT()   interrupt 0  呢?  哪怕 空的你也要写一个啊。
回复

使用道具 举报

ID:1136514 发表于 2024-12-1 09:06 | 显示全部楼层
感谢各位大佬的支持,已解决。
回复

使用道具 举报

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

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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