找回密码
 立即注册
查看: 43|回复: 4

求助大佬,51单片机STC8G1K08的掉电模式和唤醒问题

[复制链接]
  • 打卡等级:偶尔看看II
  • 打卡总天数:20
  • 最近打卡:2025-10-11 08:44:12
已绑定手机

22

主题

28

回帖

190

积分

注册会员

积分
190
发表于 5 天前 | 显示全部楼层 |阅读模式
您好,我的单片机是STC8G1K08的51单片机。
我想要实现的功能是单片机接收到8字节数据后,先存储起来,在掉电模式来临后,低功耗状态下数据保持一段时间,然后经过INT2外部中断唤醒后,通过串口输出这8字节数据。

目前在未加掉电模式的情况下,单片机可以实现正确的接收数据和发送数据,但是一加上掉电模式和唤醒就不能实现功能了。

目前是这样的,我在注释了外部中断INT2唤醒的代码后,单片机可以正常的接收到数据并通过串口再将数据发送,如下图所示:

并且可以通过串口接收到正确的8字节数据,如下图:



但是如果加上了我自己写的掉电模式和唤醒配置后,如下图:

单片机能够被唤醒,但串口处一直发送如下图所示的语句:

应该是卡在了如下图所示的地方:


请您帮帮我,我不知道是我哪里配置错了,官方的外部中断可以正常唤醒运行。
并且在不加外部中断唤醒情况下,代码是可以实现正确接收和正确发送的,但是只要一加了掉电模式和唤醒,就不能实现了。

结尾附上了我写的代码,请大佬帮帮我,万分感谢!!! 10.10哑铃板代码.zip (460.58 KB, 下载次数: 2)

回复

使用道具 举报 送花

3

主题

1880

回帖

608

积分

等待验证会员

积分
608
发表于 5 天前 | 显示全部楼层
您好,关于您在使用 STC8G1K08 51 单片机时遇到的 掉电模式(Power Down Mode)与外部中断唤醒后串口通信异常 的问题,我将从硬件机制、低功耗配置、中断唤醒流程、串口恢复机制等方面进行专业分析,并给出优化建议。

一、问题简述

您希望实现如下功能:
单片机接收 8 字节数据 → 存储在 RAM 中;
进入掉电模式,保持 RAM 数据;
通过 INT2 外部中断唤醒;
唤醒后通过串口输出之前存储的 8 字节数据。

当前现象:
不加掉电模式时功能正常;
加入掉电与唤醒后,串口持续输出乱码,疑似程序卡死或串口未正确恢复。

二、STC8G1K08 掉电模式与唤醒机制分析

1. 掉电模式特性

STC8 系列单片机支持多种低功耗模式,其中 掉电模式(Power Down) 是最低功耗的一种,其特点如下:
CPU 停止运行;
所有时钟源关闭;
只有部分 I/O 可用于唤醒;
RAM 数据可保持(需使能掉电模式下的 RAM 保持功能);
支持唤醒源:外部中断、定时器、看门狗、ADC、SPI、UART 等。

2. 掉电进入方式

进入掉电模式一般通过设置 PCON 寄存器:
  1. c
  2. PCON |= 0x02;   // 设置掉电模式
复制代码

进入掉电后,MCU 会等待中断唤醒。

3. 唤醒后的状态恢复

唤醒后,系统会从复位地址重新开始执行代码,即掉电唤醒后程序会从 main 函数重新运行。因此,若未做特殊处理,之前接收的数据将丢失。
注意:掉电唤醒后不是从中断返回继续执行,而是从头运行程序!

三、问题定位分析

从您提供的信息来看,问题可能出在以下几点:

1. 掉电唤醒后程序流程异常

由于掉电唤醒后程序会从 main 重新运行,若您未做特殊处理(如标志位保存在 RAM 或 EEPROM 中),则无法知道之前是否已经接收到数据。

2. 串口初始化未正确恢复

唤醒后若未重新初始化串口(如波特率、寄存器设置),可能导致串口输出异常,出现乱码。

3. 外部中断唤醒配置不当

INT2 中断唤醒配置是否正确?例如:
是否设置了正确的边沿触发方式(上升沿 / 下降沿);
是否开启了全局中断(EA);
是否开启了中断使能(EX2);
是否清除了中断标志(IE2);
是否编写了中断服务函数(ISR)。

4. RAM 数据保持配置未开启

STC8G1K08 在掉电模式下,默认 RAM 数据会丢失。必须通过设置寄存器来启用 RAM 数据保持功能。

查看是否设置了以下寄存器:
  1. c
  2. P5M1 = 0x00; P5M0 = 0x00;  // 设置 P5 为高阻态,防止漏电
  3. WKTCL = 0x00;              // 看门狗定时器清零
  4. WDTCONTR = 0x3C;          // 启用看门狗并设置唤醒源
复制代码

此外,还应检查是否启用了 RAM 保持功能(具体寄存器请参考数据手册)。

四、解决方案建议

1. 使用 RAM 保持功能并设置唤醒标志

在进入掉电前,将接收到的数据存储在 RAM 中,并设置一个标志位(如 uint8t datareceived = 1;),同时确保掉电唤醒后 RAM 数据未丢失。

掉电唤醒后,检查该标志位是否为 1,若为 1 则跳过数据接收流程,直接发送数据。

示例代码结构如下:
  1. c
  2. uint8t data[8];
  3. uint8t datareceived = 0;
  4. void main(void) {
  5.     // 初始化外设
  6.     UARTInit();
  7.    
  8.     if (datareceived == 0x55) {
  9.         // 已接收到数据,直接发送
  10.         UARTSend(data, 8);
  11.     } else {
  12.         // 正常接收数据
  13.         UARTReceive(data, 8);
  14.         datareceived = 0x55;
  15.     }
  16.     // 进入掉电模式
  17.     EnterPowerDown();
  18. }
复制代码

2. 正确配置外部中断唤醒

确保 INT2 中断配置如下:
  1. c
  2. IT2 = 1;     // 设置为下降沿触发
  3. EX2 = 1;     // 使能 INT2 中断
  4. EA = 1;      // 使能全局中断
复制代码

中断服务函数应为空或仅用于唤醒:
  1. c
  2. void INT2ISR(void) interrupt 10 {
  3.     EX2 = 0;  // 可选:关闭中断防止重复唤醒
  4. }
复制代码

3. 掉电前后正确初始化串口

唤醒后务必重新初始化串口,包括:
设置串口模式(如 8N1);
设置波特率;
清除缓冲区;
重新使能串口中断(若使用中断发送)。

示例初始化函数:
  1. c
  2. void UARTInit(void) {
  3.     SCON = 0x50;       // 8位数据,1位停止位,无校验
  4.     TMOD |= 0x20;      // 定时器1模式2
  5.     TH1 = 0xFD;        // 波特率9600
  6.     TL1 = 0xFD;
  7.     TR1 = 1;           // 启动定时器1
  8.     ES = 1;            // 使能串口中断
  9. }
复制代码

4. 确保 RAM 数据保持有效

查阅 STC8G1K08 数据手册,找到 RAM 保持相关寄存器配置,确保掉电后 RAM 数据不丢失。

五、其他建议

1. 使用 EEPROM 保存数据(可选)

如果 RAM 保持不可靠,可以将数据写入 EEPROM,掉电唤醒后再读出发送。

2. 添加看门狗防死锁

掉电唤醒过程中,若程序卡死,建议启用看门狗防止系统死锁。

3. 使用调试工具排查问题

建议使用调试器(如 Keil uVision + STC-ISP)单步调试唤醒流程,观察寄存器状态和程序流程。

六、总结

| 问题点 | 分析 | 建议 |
|--------|------|------|
| 掉电唤醒后程序重启 | 掉电唤醒后程序从 main 重新运行 | 使用 RAM 标志位区分流程 |
| 串口乱码 | 唤醒后未正确初始化 | 唤醒后重新初始化串口 |
| 数据丢失 | RAM 未保持 | 启用 RAM 保持功能或使用 EEPROM |
| 中断唤醒失败 | 中断配置错误 | 检查 INT2 触发方式、中断使能、ISR 函数 |

如果您能提供完整的代码片段和电路图,我可以进一步帮助您定位问题。同时建议您参考 STC8G1K08 技术手册 和 STC 官方应用笔记,以确保配置准确。

如需进一步协助,欢迎继续提问。

祝您项目顺利!

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:516
  • 最近打卡:2025-10-16 00:05:49
已绑定手机

154

主题

1889

回帖

2621

积分

金牌会员

积分
2621
发表于 5 天前 | 显示全部楼层
为啥你不用LVD或者是比较器 来进入掉电模式,
我看你的代码是用的主循环里面轮询来检测的,
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:328
  • 最近打卡:2025-10-15 08:50:20
已绑定手机

85

主题

3256

回帖

7196

积分

荣誉版主

无情的代码机器

积分
7196
发表于 5 天前 | 显示全部楼层

简单试了下掉电唤醒后串口发送没问题,是不是接错外部中断pin脚了?WakeUpSource == 3过滤条件去掉能唤醒吗?或者试下我修改这个纯串口验证逻辑
截图202510110933258074.jpg

20250107小板P3.2-test.zip (441.63 KB, 下载次数: 0)
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:200
  • 最近打卡:2025-10-15 13:18:53

77

主题

6775

回帖

1万

积分

超级版主

积分
14384
发表于 5 天前 | 显示全部楼层
唤醒需要一点时间,如果串口波特率不大于2400,则唤醒后可以马上正确接收数据。如果波特率大于2400,则唤醒后需要延时至少10个波特时间,串口再发送数据。
另外,外中断唤醒一定要有对应的外中断处理函数。
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-10-16 07:46 , Processed in 0.126632 second(s), 70 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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