芯片:STC8H1K08(24 MHz),下载工具:STC-ISP
c
/******************************************************************************
* STC8H 低功耗深度睡眠 Demo ------ 完整可编译源码
* Keil5 工程创建步骤:
* 1. Device 选择 STC8H1K08
* 2. 选项卡 Target 设置 24 MHz,Memory Model Small
* 3. 选项卡 Output 勾选 Create HEX
* 4. STC-ISP 选择"IRC 频率 24 MHz"下载
******************************************************************************/
#include "stc8h.h"
#include "intrins.h"
#define MAIN_Fosc 24000000L /* 主频 24 MHz */
#define TIMER0_RELOAD (65536UL - (MAIN_Fosc / 1000)) /* 1 ms */
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
/* ---------- 全局变量 ---------- */
u8 sleep_mode = 0; /* 1=正在睡眠 */
u8 wakeup_indicator_flag = 0; /* 中断里置位,主循环里点灯 */
u32 sleep_time_counter = 0; /* 统计进入睡眠次数 */
/* ---------- 唤醒源位定义 ---------- */
#define WAKEUP_EXT_INT0 0x01
#define WAKEUP_EXT_INT1 0x02
#define WAKEUP_RTC 0x04
/* ---------- 函数声明 ---------- */
void System_Init(void);
void GPIO_Init(void);
void GPIO_DeepSleep_Config(void);
void Timer0_Init(void);
void External_Int_Init(void);
void Enter_DeepSleep_Mode(void);
void LED_Running_Light(void);
void LED_Wakeup_Indicator(void);
void Deep_Power_Optimize(void);
void Wakeup_Source_Config(u8 sources);
void delay_ms(u8 ms);
/* ========================== main ========================== */
void main(void)
{
System_Init(); /* 时钟/复位标志 */
GPIO_Init(); /* 推挽输出,LED 灭 */
Timer0_Init(); /* 1 ms 时基 */
External_Int_Init(); /* 外部中断,先关闭 */
EA = 1; /* 开总中断 */
LED_Wakeup_Indicator(); /* 上电指示 */
while (1)
{
if (!sleep_mode) /* 正常模式 */
{
if (wakeup_indicator_flag)
{
LED_Wakeup_Indicator();
wakeup_indicator_flag = 0;
}
LED_Running_Light(); /* 流水灯 */
Deep_Power_Optimize(); /* 关外设 */
Enter_DeepSleep_Mode(); /* 进去睡 */
}
else
{
_nop_(); /* 睡眠中,实际不会跑到这里 */
}
}
}
/* ---------------- 系统初始化 ---------------- */
void System_Init(void)
{
P_SW2 |= 0x80; /* 允许访问扩展寄存器 */
RSTFLAG = 0x00; /* 清复位标志 */
}
/* ---------------- GPIO 初始化(推挽输出高) ---------------- */
void GPIO_Init(void)
{
P0M1 = 0x00; P0M0 = 0xFF; P0 = 0xFF;
P1M1 = 0x00; P1M0 = 0xFF; P1 = 0xFF;
P2M1 = 0x00; P2M0 = 0xFF; P2 = 0xFF; /* LED */
P3M1 = 0x00; P3M0 = 0xFF; P3 = 0xFF;
P4M1 = 0x00; P4M0 = 0xFF; P4 = 0xFF;
P5M1 = 0x00; P5M0 = 0xFF; P5 = 0xFF;
P6M1 = 0x00; P6M0 = 0xFF; P6 = 0xFF;
P7M1 = 0x00; P7M0 = 0xFF; P7 = 0xFF;
}
/* ---------------- 睡眠前 GPIO 高阻 ---------------- */
void GPIO_DeepSleep_Config(void)
{
P0M1 = 0xFF; P0M0 = 0x00; P0 = 0xFF;
P1M1 = 0xFF; P1M0 = 0x00; P1 = 0xFF;
P2M1 = 0x00; P2M0 = 0xFF; P2 = 0xFF; /* LED 保持高,灭 */
P3M1 = 0x0C; P3M0 = 0x00; P3 = 0xFF; /* P3.2/3.3 高阻输入 */
P4M1 = 0xFF; P4M0 = 0x00; P4 = 0xFF;
P5M1 = 0xFF; P5M0 = 0x00; P5 = 0xFF;
P6M1 = 0xFF; P6M0 = 0x00; P6 = 0xFF;
P7M1 = 0xFF; P7M0 = 0x00; P7 = 0xFF;
}
/* ---------------- 定时器 0 初始化(1 ms) ---------------- */
void Timer0_Init(void)
{
TMOD &= 0xF0; /* 16 位自动重装 */
AUXR |= 0x80; /* 1T 模式 */
TH0 = (u8)(TIMER0_RELOAD >> 8);
TL0 = (u8)TIMER0_RELOAD;
ET0 = 1;
TR0 = 1;
}
/* ---------------- 外部中断初始化 ---------------- */
void External_Int_Init(void)
{
IT0 = 1; /* 下降沿 */
IT1 = 1;
EX0 = 0; /* 先关闭 */
EX1 = 0;
IE0 = 0; IE1 = 0;
}
/* ---------------- 唤醒源配置 ---------------- */
void Wakeup_Source_Config(u8 sources)
{
EX0 = (sources & WAKEUP_EXT_INT0) ? 1 : 0;
EX1 = (sources & WAKEUP_EXT_INT1) ? 1 : 0;
IE0 = 0; IE1 = 0;
}
/* ---------------- 流水灯 ---------------- */
void LED_Running_Light(void)
{
u8 i;
for (i = 0; i < 8; i++)
{
P2 = ~(1 << i);
delay_ms(100);
}
P2 = 0xFF;
}
/* ---------------- 唤醒指示(闪 3 次) ---------------- */
void LED_Wakeup_Indicator(void)
{
u8 i;
for (i = 0; i < 3; i++)
{
P2 = 0x00; delay_ms(50);
P2 = 0xFF; delay_ms(50);
}
}
/* ---------------- 深度功耗优化 ---------------- */
void Deep_Power_Optimize(void)
{
/* 关外设 */
ADC_CONTR = 0x00;
SCON = 0x00;
TR0 = TR1 = 0;
WDT_CONTR = 0x00;
/* GPIO 高阻 */
GPIO_DeepSleep_Config();
/* 只开 INT0/1 唤醒 */
Wakeup_Source_Config(WAKEUP_EXT_INT0 | WAKEUP_EXT_INT1);
}
/* ---------------- 进入掉电模式 ---------------- */
void Enter_DeepSleep_Mode(void)
{
delay_ms(10); /* 稳定 */
sleep_time_counter++;
sleep_mode = 1; /* 标记睡眠 */
EA = 0; /* 关中断 */
_nop_(); _nop_();
PCON |= 0x02; /* 置位 PD */
_nop_(); _nop_(); _nop_(); /* 固定 >3 个空操作 */
/* 唤醒后从这里继续执行 */
EA = 1; /* 重新开中断 */
sleep_mode = 0; /* 清标记 */
/* 重建现场 */
System_Init();
GPIO_Init();
Timer0_Init();
wakeup_indicator_flag = 1; /* 主循环里闪灯 */
}
/* ---------------- 毫秒延时 ---------------- */
void delay_ms(u8 ms)
{
u16 i;
do {
i = MAIN_Fosc / 13000;
while (--i);
} while (--ms);
}
/* ========================== 中断服务 ========================== */
/* INT0 唤醒 */
void INT0_ISR(void) interrupt 0
{
IE0 = 0;
wakeup_indicator_flag = 1;
}
/* INT1 唤醒 */
void INT1_ISR(void) interrupt 2
{
IE1 = 0;
wakeup_indicator_flag = 1;
}
/* Timer0 中断(调试用,睡眠前已关闭) */
void Timer0_ISR(void) interrupt 1
{
/* 用户可扩展软件定时器 */
}
把上面代码直接复制到 Keil → 编译 → 下载,即可看到:
- 上电 LED 闪 3 次;
- 正常模式跑流水灯;
- 1 轮后自动进入睡眠,电流小于1mA;
- 按 KEY1/KEY2 唤醒,LED 再闪 3 次,继续跑流水灯。


祝调试愉快,低功耗一路长虹!