第一次掉电P35可唤醒,第二次掉电P35不能唤醒 | 已解决
STC8H8K64U 开天斧实验板;定时10秒让单片机掉电(PCON|=0X02),设置P35,P36IO中断唤醒,,首次可以正常唤醒 ,一切正常,
第二轮定时10秒掉电后,P35按键不能唤醒(设置为下降沿或上升沿皆不能唤醒),这时按下P34按钮,可以唤醒.
我想让P35按钮每次都可以唤醒 ,请问是哪里设置错了呢?为什么,P34按键连续掉电后都可以唤醒,为什么?
代码如下:
#include "stc8h.h"
#include "stc32_stc8_usb.h"
#include "delay.h"
sbit LED=P1^0;//led指示灯
unsigned int tim0ms; // 定时器计时变量
unsigned char Tim0H, Tim0M, Tim0S; // 定时器计时变量
unsigned char SleepTime;
BOOL SleepFlag; // 超过多少时间以后单片机待机标志由按键来唤醒
void PortInt_Init(void); // IO中断初始化
void usb_uninit();//休眠时关闭USBCDC中断
void main()
{
unsigned int keyjishi;
keyjishi = 0;
tim0ms = 0;
Tim0S = 0;
Tim0M = 0;
SleepFlag = 0; // 待机标志
zhendong_flag = 0;
SleepTime = 1;//分钟
P_SW2 |= 0x80;
P0M1 = 0x00;
P0M0 = 0x00;
P1M1 = 0x00;
P1M0 = 0x00;
P2M1 = 0x00;
P2M0 = 0x00;
P3M1 = 0x00;
P3M0 = 0x00;
P4M1 = 0x00;
P4M0 = 0x00;
P5M1 = 0x00;
P5M0 = 0x00;
P6M1 = 0x00;
P6M0 = 0x00;
P7M1 = 0x00;
P7M0 = 0x00;
usb_init(); // USB CDC 接口配置
Timer0_Init(); // 开定时器
EA = 1;
while (1)
{
if (bUsbOutReady)
{
// USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
if (UsbOutBuffer == 'A') //'A'
{
printf("OK." ); // 接收串口信息 应答
}
else if ((UsbOutBuffer == 'I' || UsbOutBuffer == 'i') && (UsbOutBuffer == 'D' || UsbOutBuffer == 'd')) //"ID"
{
UsbInBuffer = CHIPID0;
UsbInBuffer = CHIPID1;
UsbInBuffer = CHIPID2;
UsbInBuffer = CHIPID3;
UsbInBuffer = CHIPID4;
UsbInBuffer = CHIPID5;
UsbInBuffer = CHIPID6;
USB_SendData(UsbInBuffer, 7); // 发送ID
}
usb_OUT_done();
}
if(SleepFlag)//掉电标志
{
SleepFlag = 0;
TR0 = 0;
usb_uninit() ; //休眠前关闭USBCDC中断
LED = 1;//关闭LED
PortInt_Init();//开按键中断
delayms(1);
PCON |= 0x02; // MCU进入掉电模式 由按键来唤醒
delayms(10);
//恢复P30P31数字输入
P3IE = 0xFF;
delayms(10);
tim0ms = 0;
Tim0S = 0;
Tim0M = 0;
usb_init(); // USB CDC 接口配置
TR0 = 1;
}
}
}
void TIM0interrupt() interrupt TMR0_VECTOR
{
tim0ms++;
if (tim0ms >= 1000) // 振动后PWM输出延时时间
{
tim0ms = 0;
zhendong_flag = 0;
LED = !LED;//DEBUG
Tim0S++;
if(Tim0S>10)
{
SleepFlag = 1;//掉电标志置位
}
if (Tim0S >= 60)
{
Tim0S = 0;
Tim0M++;
if (Tim0M >= SleepTime)
{
Tim0M = 0;
//SleepFlag = 1;
}
}
}
}
void Port3_Isr(void) interrupt 40
{
P3INTE = 0x00; // 禁止P3口中断
}
void PortInt_Init(void)
{
P3INTE = 0x60; // 使能P3口中断 P35 P36
P3IM0 = 0x60;// 设置P3口中断模式 (00:下降沿, 01:上升沿)P35 P36
P3IM1 = 0x00;// 设置P3口中断模式 (10:低电平, 11:高电平)
P3WKUE = 0x60; // 设置P3口中断唤醒省电模式 P35 P36
}
//休眠时需要关闭USB中断否则 不能进入
void usb_uninit()
{
USBCON &= 0x7F;
//USBCLK = 0x00; //不注释掉此处两行,唤醒后USBCDC重启失败,什么原因还不知道
//IRC48MCR = 0x00;
//P30 P31关闭数字输入
P3IE = 0xfc;
}
尊敬的用户:
您好,感谢您对STC8H8K64U芯片及开天斧实验板的关注与使用。针对您提出的问题,我们已认真分析并整理如下技术说明。
首先,根据您的描述,单片机在第一次掉电后可通过P35引脚中断唤醒,但在第二次掉电后无法唤醒,而P34可正常唤醒。此现象可能涉及以下几方面的原因:
1. 中断配置问题
在代码中,若您仅对P35进行了中断使能配置,但未确保其在每次掉电后仍处于正确的中断模式(如下降沿或上升沿),可能导致中断未能正确触发。建议检查PX1寄存器是否设置为允许P3口中断,并确认IP寄存器中对应优先级是否合理。
2. 电源管理状态异常
当单片机进入掉电模式时,部分外设可能会被关闭或进入低功耗状态,导致某些IO口无法维持中断信号的检测。特别是若P35在掉电前被拉高或拉低,可能在掉电后无法恢复至预期状态,从而影响中断触发。建议在进入掉电前,对P35进行适当的电平设置(如上拉或下拉)以确保其在唤醒时具备有效的中断条件。
3. 中断标志位未清除
若在掉电前存在未处理的中断标志位,可能导致系统在后续唤醒时无法正确识别新的中断请求。建议在每次唤醒后,及时清除相关中断标志位(如P3IF),以避免干扰。
4. 硬件连接或电平问题
P35引脚的外部电路可能存在接触不良、电容滤波不当或信号干扰等问题,导致在第二次掉电时无法稳定触发中断。建议检查P35的外部电路,确保其具备良好的信号完整性。
5. 唤醒源选择问题
STC8H系列单片机支持多种唤醒方式(如定时器、串口、I²C等)。若您在代码中同时启用了多个唤醒源,需确认P35作为唤醒源的优先级是否与其他唤醒源冲突。此外,确保在进入掉电模式前,已正确配置了唤醒源的选择寄存器(如PCON)。
6. 代码逻辑问题
您提供的代码片段中,未完整展示所有关键部分。例如,SleepFlag变量的更新逻辑、PortIntInit()函数的具体实现、以及掉电模式的进入和退出流程等。建议仔细检查这些部分,确保在掉电前后均能正确执行唤醒相关的初始化和配置。
综上所述,建议您从以下几个方面进行排查和优化:
确保P35引脚在掉电前后的电平状态符合中断触发条件;
检查中断使能、优先级及标志位的配置是否正确;
验证唤醒源选择是否合理,避免多源冲突;
完善代码逻辑,确保掉电前后各环节的连贯性与稳定性;
如有必要,可尝试使用示波器或逻辑分析仪观察P35引脚在掉电前后的电压变化,进一步定位问题所在。
如果您需要更详细的调试指导或代码示例,欢迎随时联系我们的技术支持团队,我们将竭诚为您服务。
祝您开发顺利!
国芯人工智能
2025年4月
[本文内容由国芯人工智能辅助生成,仅供参考] 在掉电语句下加入了清除P3 IO口中断标志位后,正常,正常了,感谢 国芯人工智能;
PCON |= 0x02; // MCU进入掉电模式 由按键来唤醒
delayms(10);
P3INTE = 0x00; // 禁止P3口中断
P3INTF =0X00;//软件清除标志位
页:
[1]